Facebook的GBDT+LR模型python代码实现
承接上篇講解,本文代碼,講解看上篇
- 目標:GBDT+LR模型
- 步驟:GBDT+OneHot+LR
- 測試數據:iris
- 代碼:
- 結果比較:與直接GBDT模型的比較
目標:GBDT+LR模型
實現GBDT+LR模型代碼,并比較和各種RF/XGBoost + LR模型的效果(下篇),發現GBDT+LR真心好用啊。
繼續修復bug:GBDT和LR模型需要分開用不同的數據訓練,當數據量多的時候,就能體現出差別,分開訓練時防止過擬合,能提升模型的泛化性能。
步驟:GBDT+OneHot+LR
構造GBDT+LR步驟
訓練階段:
1、 獲取特性數據,拆分成3組,一組測試數據,一組GBDT訓練數據,一組LR訓練數據
2、訓練GBDT分類器
3、遍歷GBDT樹的葉子節點,拼接成一個長長的一維向量
4、 訓練OneHot編碼器
5、 訓練LR模型
預測階段:
1、把帶預測的特征輸入到GBDT
2、獲得葉子節點,拼接成一個常常的一維向量
3、獲得OneHot向量
4、LR預測結果
這里發現了上篇文章的一個錯誤:
就是GBDT樹的葉子節點,輸出的不是0/1的預測值,也不是0/1的概率,而是一些實數值,值還比較大,因此,葉子節點的值,拼接出來的向量,是個長長的非稀疏矩陣。
結果表明,GBDT+LR效果好過單純的GBDT。
GBDT模型不能太深,太深效果反而不好,可能跟GBDT容易過擬合有關系。
測試數據:iris
數據采用sklearn里面自帶的iris花分類數據。為了模擬CTR的二分類效果,做了一下特殊處理:
1、 iris花是個3分類的數據,因此把分類為2的數據,統一歸為0,這樣就模擬了0/1的二分類
2、分類數據比0/1=2:1
提醒:貌似GBDT模型不能太深,太深效果反而不好,可能跟GBDT容易過擬合有關系。
代碼:
from sklearn.datasets import load_iris import numpy as np import pandas as pd from sklearn.ensemble import GradientBoostingClassifiernp.random.seed(10)# 加載測試數據 iris_data,iris_target = load_iris(return_X_y=True,as_frame=True) iris_data.columns =['SepalLengthCm','SepalWidthCm','PetalLengthCm','PetalWidthCm'] print(iris_data.head(5)) print(iris_data.columns) print(iris_target) iris_target = pd.DataFrame(iris_target,dtype='float32') #替換類型 print(iris_target.dtypes) iris_target[iris_target['target']==2]=0 #把類別為2的歸為0,這樣模擬CTR的0/1標記。iris=iris_data.merge(iris_target,left_index=True,right_index=True) #拼接成一個大的Dataframe,便于拆分測試數據 print(iris.head(5)) from sklearn.model_selection import train_test_split# 拆分測試數據和驗證數據 iris_train ,iris_test = train_test_split(iris,test_size=0.8,random_state=203) print(iris_train.head(5))#拆分特征和標簽為測試集和訓練集 Y_train = np.array(iris_train['target']) X_train = iris_train.drop(columns=['target'])#訓練集進一步拆分為GBDT訓練集和LR訓練集,兩者分開,能防止過擬合,提升模型的泛化性能。 X_train_GBDT ,X_train_LR,Y_train_GBDT,Y_train_LR = train_test_split(X_train,Y_train,test_size=0.5,random_state=203)print(X_train_GBDT.head(5))Y_test = np.array(iris_test['target']) X_test = iris_test.drop(columns=['target']) print(X_test.head(5))#訓練GBDT模型 from sklearn.ensemble import GradientBoostingClassifier GBDT = GradientBoostingClassifier(n_estimators=5) GBDT.fit(X_train_GBDT,Y_train_GBDT)#GBDT直接預測 GBDTPredict= GBDT.predict(X_test)#獲取GBDT葉子節點的輸出,展開成1維 GBDTy=GBDT.apply(X_train_GBDT)[:,:,0]#訓練OneHot編碼 from sklearn.preprocessing import OneHotEncoder OneHot = OneHotEncoder() OneHoty=OneHot.fit_transform(GBDTy)# 導入線性模型LR from sklearn.linear_model import LinearRegressionOneHot.transform(GBDT.apply(X_train_LR)[:,:,0]) LR = LinearRegression() LR.fit(OneHot.transform(GBDT.apply(X_train_LR)[:,:,0]),Y_train_LR)#test GBDT輸出預測的概率值 GBDT.predict_proba(X_test)[:,1]# 把測試數據輸入到訓練好的GBDT模型,然后得到葉子節點的值 GBDTtesty=GBDT.apply(X_test)[:,:,0] print(GBDTtesty) # 得到OneHot編碼 OneHotTesty = OneHot.transform(GBDTtesty) #LR模型預測 LRy= LR.predict(OneHotTesty) print(LRy)#導入評估模塊,使用AUC 評估模型 from sklearn.metrics import roc_curve,roc_auc_score # 測試GBDT+LR的預測效果 pr,fr,_=roc_curve(Y_test,LRy) print(Y_test) print('roc_auc_score of GDBT+LR is ',roc_auc_score(Y_test,LRy))from matplotlib import pyplot pyplot.plot(pr,fr) pyplot.xlabel("pr") pyplot.ylabel('fr') pyplot.show()# 測試GBDT預測的概率值和真值的差距 print('roc_auc_score of GDBT predict_proba is ',roc_auc_score(Y_test,GBDT.predict_proba(X_test)[:,1])) # 測試GBDT預測值和真值的差距 print('roc_auc_score of GDBT predict is ',roc_auc_score(Y_test,GBDT.predict(X_test)))結果比較:與直接GBDT模型的比較
roc_auc_score of GDBT+LR is 0.8348255634455078直接用GBDT預測的結果:
roc_auc_score of GDBT predict_proba is 0.8260265514047544 roc_auc_score of GDBT predict is 0.8260265514047544可以看到,GBDT+LR模型的效果,好于GBDT。
總結
以上是生活随笔為你收集整理的Facebook的GBDT+LR模型python代码实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 推荐系统XDeepFM模型--DeepF
- 下一篇: XGBoost对比RandomFores