文章目錄
-
-
- 一、GBDT模型介紹
-
- 1.該案例GBDT結構
- 2.GBDT常用參數
- 二、分類器性能名額—AUC
- 三、GBDT在流失預警模型中的應用
-
- 1.調參過程
- 2.變量重要性
-
- 金融評分卡項目—2.銀行客戶流失預警模型介紹(單因子與多因子分析)
- 金融評分卡項目—3.流失預警模型中的資料預處理與特征衍生
- 金融評分卡項目—5.神經網絡模型在銀行業客戶流失預警模型中的應用—MLP
一、GBDT模型介紹
梯度提升樹是一個內建模型,可用于分類、回歸與排序。GBDT的核心在于累加所有樹的結果作為最終結果,GBDT可用于分類,并不代表是累加所有分類樹的結果。GBDT中的樹都是回歸樹(利用平方誤差最小化準則,進行特征選擇,生成二叉樹),不是分類樹,這點對了解GBDT相當重要
梯度提升樹,當損失函數是平方損失時,下一棵樹拟合的是上一棵樹的殘內插補點(實際值減預測值)。當損失函數是非平方損失時,拟合的是損失函數的負梯度值。
舉個簡單例子:
A的真實年齡是18歲,但第一棵樹的預測年齡是12歲,差了6歲,即殘差為6歲。那麼在第二棵樹裡我們把A的年齡設為6歲去學習,如果第二棵樹真的能把A分到6歲的葉子節點,那累加兩棵樹的結論就是A的真實年齡;如果第二棵樹的結論是5歲,則A仍然存在1歲的殘差,第三棵樹裡A的年齡就變成1歲,繼續學。
當損失函數是平方差損失時,用殘差作為全局最優的絕對方向,并不需要Gradient求解。但是損失函數多種多樣,當損失函數是非平方損失時,機器學習界的大牛Freidman提出了梯度提升算法:利用最速下降的近似方法,即利用損失函數的負梯度在目前模型的值,作為回歸問題中提升樹算法的殘差的近似值,拟合一個回歸樹。

特點:
- 基于簡單回歸決策樹的組合模型
決策樹的優點:
解釋性強
允許變量互動作用
對離群值、缺失值、共線性不敏感
決策樹的缺點:
準确度不夠高
易過拟合
運算量大
- 沿着梯度下降的方向進行提升
- 隻接受數值型連續變量—需要做特征轉化(将類别型變量轉換成離散型變量)
優點:
- 準确度高
- 不易過拟合
1.該案例GBDT結構
2.GBDT常用參數
更多參數解析詳見sklearn官網
GBDT架構常用參數
n_estimators:分類樹的個數,K
learning_rate:即每個弱學習器的權重縮減系數 v v v,也稱為步長。較小的 v v v意味着需要更多的弱學習器的疊代次數。
參數n_estimators和learning_rate要一起調參。可以從一個小一點的 v v v開始調參,預設為1,這兩個參數關系相反,一個大了,另一個就小了
Subsample:(不放回)抽樣率,推薦[0.5,0.8]之間,預設是1.0,即不使用子采樣
init:即初始化的時候的弱學習器,一般用在對資料有先驗知識,或者之前做過一些拟合的時候
loss:GBDT算法中的損失函數
max_features : {‘auto’, ‘sqrt’, ‘log2’}, int or float, default=None
尋找最佳分割時需要考慮的特性數量:
If int, then consider max_features features at each split.
If float, then max_features is a fraction and int(max_features * n_features) features are considered at each split.
If ‘auto’, then max_features=sqrt(n_features).
If ‘sqrt’, then max_features=sqrt(n_features).
If ‘log2’, then max_features=log2(n_features).
If None, then max_features=n_features.
弱分類樹的參數:
max_features:劃分時考慮的最大特征數
max_depth:決策樹的最大深度
min_samples_split:内部節點再劃分時所需的最小樣本數。預設是2。如果樣本量不大,就不需要管這個值。如果樣本量數量級非常大,則推薦增大這個值
min_samples_leaf:葉子節點最少樣本數
min_weight_fraction_leaf:葉子節點最小的樣本權重。預設是0,就是不考慮權重問題。一般來說,如果我們有較多樣本有缺失值,或者分類樹樣本的分布類别偏差很大,就會引入樣本權重,這個時候就要注意這個值。
max_leaf_nodes:最大葉子節點數,通過限制最大葉子節點數,可以防止過拟合
min_impurity_split : 節點劃分最小不純度
二、分類器性能名額—AUC
如果想弄懂AUC和ROC曲線,一定要徹底了解混淆矩陣的概念!!!
混淆矩陣中有Postitive(陽性)、Negative(陰性)、False(僞)、True(真)的概念
- 預測類别為0的為Negative(陰性),預測類别為1的為Postitive(陽性)
- 預測錯誤的為False(僞)、預測正确為True(真)
對上述概念進行組合,就有了混淆矩陣!
ROC計算過程參見該部落格
三、GBDT在流失預警模型中的應用
1.調參過程
導入子產品、加載資料集、切分資料集
# 導入子產品
import pandas as pd
import numpy as np
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.model_selection import train_test_split, KFold, GridSearchCV
from sklearn import ensemble, metrics
# 讀取預處理後的資料集
modelData = pd.read_csv('data/modelData.csv', header=0)
allFeatures = list(modelData.columns)
# 移除CUST_ID與CHURN_CUST_IND列
allFeatures.remove('CUST_ID')
allFeatures.remove('CHURN_CUST_IND')
# 切割資料集
x_train, x_test, y_train, y_test = train_test_split(modelData[allFeatures], modelData['CHURN_CUST_IND'], test_size=0.3,
shuffle=True)
print(y_train.value_counts())
print(y_test.value_counts())
預設設定的GBDT
# 1.使用預設模型參數
gbdt_0 = GradientBoostingClassifier(random_state=10)
gbdt_0.fit(x_train, y_train)
y_pred = gbdt_0.predict(x_test)
# predict_proba生成一個n行k列的數組,其中n為樣本資料量,k為标簽個數,
# 每一行為某個樣本屬于某個标簽的機率,每行機率和為1
y_pred_prob = gbdt_0.predict_proba(x_test)[:, 1]
# %g 浮點數字(根據值的大小采用%e或%f)
print('Accuracy : %.4g' % metrics.accuracy_score(y_test, y_pred))
print('AUC(Testing) : %f' % metrics.roc_auc_score(y_test, y_pred_prob))
# 訓練集上的accuracy、auc
y_pred_1 = gbdt_0.predict(x_train)
y_pred_prob_1 = gbdt_0.predict_proba(x_train)[:, 1]
print('Accuracy : %.4g' % metrics.accuracy_score(y_train, y_pred_1))
print('AUC(Training) : %f' % metrics.roc_auc_score(y_train, y_pred_prob_1))
調參第一步:
首先從learning rate(步長)和n_estimators(疊代次數)入手。一般是選擇一個較小的步長來網格搜尋最好的疊代次數。這裡,我們不妨将learning rate設定為0.1,疊代次數的所搜次數為20~80,确定下n_estimators(疊代次數)。
# 2.設定一個較小的learning_rate,網格搜尋n_estimators
params_test = {'n_estimators': np.arange(20, 81, 10)}
gbdt_1 = GradientBoostingClassifier(learning_rate=0.1, min_samples_split=300, min_samples_leaf=20,
max_depth=8, max_features='sqrt', subsample=0.8, random_state=10)
gs = GridSearchCV(estimator=gbdt_1, param_grid=params_test, scoring='roc_auc', cv=5)
gs.fit(x_train, y_train)
print('模型最佳參數為', gs.best_params_)
print('模型最好的評分為', gs.best_score_)
模型最佳參數為 {'n_estimators': 80}
模型最好的評分為 0.9999988452344752
調參第二步:
在學習率與疊代次數确定的情況下,我們開始對決策樹進行調參。首先,對決策樹最大深度max_depth和内部節點再劃分所需最小樣本數min_samples_split進行網格搜尋,搜尋範圍分别是3~13和100 ~800。由于内部節點再劃分所需最小樣本數min_samples_split還與決策樹的其他參數存在關聯,我們就先确定下決策樹最大深度max_depth
# 3.對max_depth與min_samples_split進行網格搜尋
params_test = {'max_depth': np.arange(3, 14, 1), 'min_samples_split': np.arange(100, 801, 100)}
gbdt_2 = GradientBoostingClassifier(learning_rate=0.1, n_estimators=80, min_samples_leaf=20,
max_features='sqrt', subsample=0.8, random_state=10)
gs = GridSearchCV(estimator=gbdt_2, param_grid=params_test, scoring='roc_auc', cv=5)
gs.fit(x_train, y_train)
print('模型最佳參數為', gs.best_params_)
print('模型最好的評分為', gs.best_score_)
調參第三步:
将内部節點再劃分所需最小樣本數min_samples_split和葉子節點最少樣本數min_samples_leaf一起調參。調參範圍分别是400-1000以及60-100。
# 4.内部節點再劃分所需最小樣本數min_samples_split和葉子節點最少樣本數min_samples_leaf一起調參
params_test = {'min_samples_leaf': np.arange(20, 101, 10), 'min_samples_split': np.arange(400, 1001, 100)}
gbdt_3 = GradientBoostingClassifier(learning_rate=0.1, n_estimators=80, max_depth=9,
max_features='sqrt', subsample=0.8, random_state=10)
gs = GridSearchCV(estimator=gbdt_3, param_grid=params_test, scoring='roc_auc', cv=5)
gs.fit(x_train, y_train)
print('模型最佳參數為', gs.best_params_)
print('模型最好的評分為', gs.best_score_)
最終版本
gbdt_4 = GradientBoostingClassifier(learning_rate=0.1, n_estimators=80, max_depth=9, min_samples_leaf=70,
min_samples_split=500, max_features='sqrt', subsample=0.8, random_state=10)
gbdt_4.fit(x_train, y_train)
y_pred_4 = gbdt_4.predict(x_test)
y_pred_prob_4 = gbdt_4.predict_proba(x_test)[:, 1]
print('Accuracy : %.4g' % metrics.accuracy_score(y_test, y_pred_4))
print('AUC(Testing) : %f' % metrics.roc_auc_score(y_test, y_pred_prob_4))
# 訓練集上的accuracy、auc
y_pred_1 = gbdt_4.predict(x_train)
y_pred_prob_1 = gbdt_4.predict_proba(x_train)[:, 1]
print('Accuracy : %.4g' % metrics.accuracy_score(y_train, y_pred_1))
print('AUC(Training) : %f' % metrics.roc_auc_score(y_train, y_pred_prob_1))
發現效果竟然還不如預設效果,主要原因是這裡我們隻使用了0.8的子采樣,20%的資料沒有參與拟合。
調參第四步:
我們對最大特征數max_features進行網格搜尋
# 對max_features進行網格搜尋
param_test4 = {'max_features': range(5, 31, 2)}
gbdt_4 = GradientBoostingClassifier(learning_rate=0.1, n_estimators=80, max_depth=9, min_samples_leaf=70,
min_samples_split=500, subsample=0.8, random_state=10)
gs = GridSearchCV(estimator=gbdt_4, param_grid=param_test4, scoring='roc_auc', cv=5)
gs.fit(x_train, y_train)
print('模型最佳參數為', gs.best_params_)
print('模型最好的評分為', gs.best_score_)
凋參第五步:
# 對subsample進行網格搜尋
param_test5 = {'subsample':[0.6,0.7,0.75,0.8,0.85,0.9]}
gbdt_5 = GradientBoostingClassifier(learning_rate=0.1, n_estimators=80, max_depth=9, min_samples_leaf=70,
min_samples_split=500, max_features=28, random_state=10)
gs = GridSearchCV(estimator=gbdt_5, param_grid=param_test5, scoring='roc_auc', cv=5)
gs.fit(x_train, y_train)
print('模型最佳參數為', gs.best_params_)
print('模型最好的評分為', gs.best_score_)
現在我們已經基本上得到我們所有的調參結果,這時,我們可以減半步長,最大疊代次數加倍來增加我們模型的泛化能力。
2.變量重要性
和随機森林一樣,GBDT也可以給出特征的重要性。
clf = GradientBoostingClassifier(learning_rate=0.05, n_estimators=70,max_depth=9, min_samples_leaf =70,
min_samples_split =1000, max_features=28, random_state=10,subsample=0.8)
clf.fit(X_train, y_train)
importances = clf.feature_importances_
# 按重要性降序對要素進行排序。 預設情況下,argsort傳回升序
features_sorted = np.argsort(-importances)
import_feautres = [allFeatures[i] for i in features_sorted]
如果對您有幫助,麻煩點贊關注,這真的對我很重要!!!如果需要互關,請評論留言!