日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

GBDT和LR结合使用分析

發(fā)布時間:2024/1/17 编程问答 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 GBDT和LR结合使用分析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?文章來源:https://www.deeplearn.me/1797.html

?

GBDT+LR 的特征組合方案是工業(yè)界經(jīng)常使用的組合,尤其是計(jì)算廣告 CTR 中應(yīng)用比較廣泛,方案的提出者是 Facebook 2014 的一篇論文。

相關(guān)的開發(fā)工具包,sklearn 和 xgboost(ps:xgboost 是一個大殺器,并且支持 hadoop 分布式,你可以部署實(shí)現(xiàn)分布式操作,博主部署過,布置過程較為負(fù)責(zé),尤其是環(huán)境變量的各種設(shè)置)


特征決定模型性能上界,例如深度學(xué)習(xí)方法也是將數(shù)據(jù)如何更好的表達(dá)為特征。如果能夠?qū)?shù)據(jù)表達(dá)成為線性可分的數(shù)據(jù),那么使用簡單的線性模型就可以取得很好的效果。GBDT 構(gòu)建新的特征也是使特征更好地表達(dá)數(shù)據(jù)。

主要參考 Facebook[1],原文提升效果:

在預(yù)測 Facebook 廣告點(diǎn)擊中,使用一種將決策樹與邏輯回歸結(jié)合在一起的模型,其優(yōu)于其他方法,超過 3%。

主要思想:GBDT 每棵樹的路徑直接作為 LR 輸入特征使用。

用已有特征訓(xùn)練 GBDT 模型,然后利用 GBDT 模型學(xué)習(xí)到的樹來構(gòu)造新特征,最后把這些新特征加入原有特征一起訓(xùn)練模型。構(gòu)造的新特征向量是取值 0/1 的,向量的每個元素對應(yīng)于 GBDT 模型中樹的葉子結(jié)點(diǎn)。當(dāng)一個樣本點(diǎn)通過某棵樹最終落在這棵樹的一個葉子結(jié)點(diǎn)上,那么在新特征向量中這個葉子結(jié)點(diǎn)對應(yīng)的元素值為 1,而這棵樹的其他葉子結(jié)點(diǎn)對應(yīng)的元素值為 0。新特征向量的長度等于 GBDT 模型里所有樹包含的葉子結(jié)點(diǎn)數(shù)之和。

上圖為混合模型結(jié)構(gòu)。輸入特征通過增強(qiáng)的決策樹進(jìn)行轉(zhuǎn)換。 每個單獨(dú)樹的輸出被視為稀疏線性分類器的分類輸入特征。 增強(qiáng)的決策樹被證明是非常強(qiáng)大的特征轉(zhuǎn)換。

例子 1:上圖有兩棵樹,左樹有三個葉子節(jié)點(diǎn),右樹有兩個葉子節(jié)點(diǎn),最終的特征即為五維的向量。對于輸入 x,假設(shè)他落在左樹第一個節(jié)點(diǎn),編碼[1,0,0],落在右樹第二個節(jié)點(diǎn)則編碼[0,1],所以整體的編碼為[1,0,0,0,1],這類編碼作為特征,輸入到線性分類模型(LR or FM)中進(jìn)行分類。

需要注意的是在 sklearn 或者 xgboost 輸出的結(jié)果都是葉子節(jié)點(diǎn)的 index,所以需要自己動手去做 onehot 編碼,然后交給 lr 訓(xùn)練,onehot 你可以在 sklearn 的預(yù)處理包中調(diào)用即可

論文中 GBDT 的參數(shù),樹的數(shù)量最多 500 顆(500 以上就沒有提升了),每棵樹的節(jié)點(diǎn)不多于 12。

下面給出二者相結(jié)合的代碼演示

?

  • # -*- coding: utf-8 -*-
  • # @Time : 2018/2/27 上午 10:39
  • # @Author : Tomcj
  • # @File : gbdt_lr.py
  • # @Software: PyCharm
  • import xgboost as xgb
  • from sklearn.datasets import load_svmlight_file
  • from sklearn.model_selection import train_test_split
  • from sklearn.linear_model import LogisticRegression
  • from sklearn.metrics import roc_curve, auc, roc_auc_score
  • from sklearn.externals import joblib
  • from sklearn.preprocessing import OneHotEncoder
  • import numpy as np
  • from scipy.sparse import hstack
  • ?
  • ?
  • ?
  • def xgb_feature_encode(libsvmFileNameInitial):
  • ?
  • # load 樣本數(shù)據(jù)
  • X_all, y_all = load_svmlight_file(libsvmFileNameInitial)
  • ?
  • # 訓(xùn)練/測試數(shù)據(jù)分割
  • X_train, X_test, y_train, y_test = train_test_split(X_all, y_all, test_size = 0.3, random_state = 42)
  • ?
  • # 定義模型
  • xgboost = xgb.XGBClassifier(nthread=4, learning_rate=0.08,
  • n_estimators=50, max_depth=5, gamma=0, subsample=0.9, colsample_bytree=0.5)
  • # 訓(xùn)練學(xué)習(xí)
  • xgboost.fit(X_train, y_train)
  • ?
  • ?
  • # 預(yù)測及 AUC 評測
  • y_pred_test = xgboost.predict_proba(X_test)[:, 1]
  • xgb_test_auc = roc_auc_score(y_test, y_pred_test)
  • print('xgboost test auc: %.5f' % xgb_test_auc)
  • ?
  • # xgboost 編碼原有特征
  • X_train_leaves = xgboost.apply(X_train)
  • X_test_leaves = xgboost.apply(X_test)
  • # 訓(xùn)練樣本個數(shù)
  • train_rows = X_train_leaves.shape[0]
  • # 合并編碼后的訓(xùn)練數(shù)據(jù)和測試數(shù)據(jù)
  • X_leaves = np.concatenate((X_train_leaves, X_test_leaves), axis=0)
  • X_leaves = X_leaves.astype(np.int32)
  • ?
  • (rows, cols) = X_leaves.shape
  • ?
  • # 記錄每棵樹的編碼區(qū)間
  • cum_count = np.zeros((1, cols), dtype=np.int32)
  • ?
  • for j in range(cols):
  • if j == 0:
  • cum_count[0][j] = len(np.unique(X_leaves[:, j]))
  • else:
  • cum_count[0][j] = len(np.unique(X_leaves[:, j])) + cum_count[0][j-1]
  • ?
  • print('Transform features genenrated by xgboost...')
  • # 對所有特征進(jìn)行 ont-hot 編碼,注釋部分是直接使用 onehot 函數(shù),結(jié)果輸出保證是 libsvm 格式也可以使用
  • #sklearn 中的 dump_svmlight_file 操作,這個文件代碼是參考別人的代碼,這些點(diǎn)都是可以優(yōu)化的。
  • ?
  • # onehot=OneHotEncoder()
  • # onehot.fit(X_leaves)
  • # x_leaves_encode=onehot.transform(X_leaves)
  • for j in range(cols):
  • keyMapDict = {}
  • if j == 0:
  • initial_index = 1
  • else:
  • initial_index = cum_count[0][j-1]+1
  • for i in range(rows):
  • if X_leaves[i, j] not in keyMapDict:
  • keyMapDict[X_leaves[i, j]] = initial_index
  • X_leaves[i, j] = initial_index
  • initial_index = initial_index + 1
  • else:
  • X_leaves[i, j] = keyMapDict[X_leaves[i, j]]
  • ?
  • # 基于編碼后的特征,將特征處理為 libsvm 格式且寫入文件
  • print('Write xgboost learned features to file ...')
  • xgbFeatureLibsvm = open('xgb_feature_libsvm', 'w')
  • for i in range(rows):
  • if i < train_rows:
  • xgbFeatureLibsvm.write(str(y_train[i]))
  • else:
  • xgbFeatureLibsvm.write(str(y_test[i-train_rows]))
  • for j in range(cols):
  • xgbFeatureLibsvm.write(' '+str(X_leaves[i, j])+':1.0')
  • xgbFeatureLibsvm.write('\n')
  • xgbFeatureLibsvm.close()
  • ?
  • ?
  • def xgboost_lr_train(xgbfeaturefile, origin_libsvm_file):
  • ?
  • # load xgboost 特征編碼后的樣本數(shù)據(jù)
  • X_xg_all, y_xg_all = load_svmlight_file(xgbfeaturefile)
  • X_train, X_test, y_train, y_test = train_test_split(X_xg_all, y_xg_all, test_size = 0.3, random_state = 42)
  • ?
  • # load 原始樣本數(shù)據(jù)
  • X_all, y_all = load_svmlight_file(origin_libsvm_file)
  • X_train_origin, X_test_origin, y_train_origin, y_test_origin = train_test_split(X_all, y_all, test_size = 0.3, random_state = 42)
  • ?
  • ?
  • # lr 對原始特征樣本模型訓(xùn)練
  • lr = LogisticRegression(n_jobs=-1, C=0.1, penalty='l1')
  • lr.fit(X_train_origin, y_train_origin)
  • joblib.dump(lr, 'lr_orgin.m')
  • # 預(yù)測及 AUC 評測
  • y_pred_test = lr.predict_proba(X_test_origin)[:, 1]
  • lr_test_auc = roc_auc_score(y_test_origin, y_pred_test)
  • print('基于原有特征的 LR AUC: %.5f' % lr_test_auc)
  • ?
  • # lr 對 load xgboost 特征編碼后的樣本模型訓(xùn)練
  • lr = LogisticRegression(n_jobs=-1, C=0.1, penalty='l1')
  • lr.fit(X_train, y_train)
  • joblib.dump(lr, 'lr_xgb.m')
  • # 預(yù)測及 AUC 評測
  • y_pred_test = lr.predict_proba(X_test)[:, 1]
  • lr_test_auc = roc_auc_score(y_test, y_pred_test)
  • print('基于 Xgboost 特征編碼后的 LR AUC: %.5f' % lr_test_auc)
  • ?
  • # 基于原始特征組合 xgboost 編碼后的特征
  • X_train_ext = hstack([X_train_origin, X_train])
  • del(X_train)
  • del(X_train_origin)
  • X_test_ext = hstack([X_test_origin, X_test])
  • del(X_test)
  • del(X_test_origin)
  • ?
  • # lr 對組合后的新特征的樣本進(jìn)行模型訓(xùn)練
  • lr = LogisticRegression(n_jobs=-1, C=0.1, penalty='l1')
  • lr.fit(X_train_ext, y_train)
  • joblib.dump(lr, 'lr_ext.m')
  • # 預(yù)測及 AUC 評測
  • y_pred_test = lr.predict_proba(X_test_ext)[:, 1]
  • lr_test_auc = roc_auc_score(y_test, y_pred_test)
  • print('基于組合特征的 LR AUC: %.5f' % lr_test_auc)
  • ?
  • if __name__ == '__main__':
  • xgb_feature_encode("/Users/leiyang/xgboost/demo/data/agaricus.txt.train")
  • xgboost_lr_train("xgb_feature_libsvm","/Users/leiyang/xgboost/demo/data/agaricus.txt.train")
  • ?
  • 下面給出一個 ipynb 文件,也是從官方的文件改過來的,主要是對 GBDT 輸出到 lr 部分?jǐn)?shù)據(jù)觀察

    ?

    view rawgbdt_lr.ipynb?hosted with ? by?GitHub

    總結(jié)

    以上是生活随笔為你收集整理的GBDT和LR结合使用分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。