python调参工作都是干啥的_Python中Gradient Boosting Machine(GBM)调参方法详解
1.前言
如果一直以來(lái)你只把GBM當(dāng)作黑匣子,只知調(diào)用卻不明就里,是時(shí)候來(lái)打開這個(gè)黑匣子一探究竟了!
這篇文章是受Owen Zhang (DataRobot的首席產(chǎn)品官,在Kaggle比賽中位列第三)在NYC Data Science Academy里提到的方法啟發(fā)而成。他當(dāng)時(shí)的演講大約有2小時(shí),我在這里取其精華,總結(jié)一下主要內(nèi)容。
不像bagging算法只能改善模型高方差(high variance)情況,Boosting算法對(duì)同時(shí)控制偏差(bias)和方差都有非常好的效果,而且更加高效。如果你需要同時(shí)處理模型中的方差和偏差,認(rèn)真理解這篇文章一定會(huì)對(duì)你大有幫助,因?yàn)槲也粌H會(huì)用Python闡明GBM算法,更重要的是會(huì)介紹如何對(duì)GBM調(diào)參,而恰當(dāng)?shù)膮?shù)往往能令結(jié)果大不相同。
特別鳴謝:?非常感謝Sudalai Rajkumar對(duì)我的大力幫助,他在AV Rank中位列第二。如果沒(méi)有他的指導(dǎo)就不會(huì)有這篇文章了。
2.目錄
Boosing是怎么工作的?
理解GBM模型中的參數(shù)
學(xué)會(huì)調(diào)參(附詳例)
3.Boosting是如何工作的?
Boosting可以將一系列弱學(xué)習(xí)因子(weak learners)相結(jié)合來(lái)提升總體模型的預(yù)測(cè)準(zhǔn)確度。在任意時(shí)間t,根據(jù)t-1時(shí)刻得到的結(jié)果我們給當(dāng)前結(jié)果賦予一個(gè)權(quán)重。之前正確預(yù)測(cè)的結(jié)果獲得較小權(quán)重,錯(cuò)誤分類的結(jié)果得到較大權(quán)重。回歸問(wèn)題的處理方法也是相似的。
讓我們用圖像幫助理解:
圖一: 第一個(gè)弱學(xué)習(xí)因子的預(yù)測(cè)結(jié)果(從左至右)
一開始所有的點(diǎn)具有相同的權(quán)重(以點(diǎn)的尺寸表示)。
分類線正確地分類了兩個(gè)正極和五個(gè)負(fù)極的點(diǎn)。
圖二: 第二個(gè)弱學(xué)習(xí)因子的預(yù)測(cè)結(jié)果
在圖一中被正確預(yù)測(cè)的點(diǎn)有較小的權(quán)重(尺寸較小),而被預(yù)測(cè)錯(cuò)誤的點(diǎn)則有較大的權(quán)重。
這時(shí)候模型就會(huì)更加注重具有大權(quán)重的點(diǎn)的預(yù)測(cè)結(jié)果,即上一輪分類錯(cuò)誤的點(diǎn),現(xiàn)在這些點(diǎn)被正確歸類了,但其他點(diǎn)中的一些點(diǎn)卻歸類錯(cuò)誤。
對(duì)圖3的輸出結(jié)果的理解也是類似的。這個(gè)算法一直如此持續(xù)進(jìn)行直到所有的學(xué)習(xí)模型根據(jù)它們的預(yù)測(cè)結(jié)果都被賦予了一個(gè)權(quán)重,這樣我們就得到了一個(gè)總體上更為準(zhǔn)確的預(yù)測(cè)模型。
現(xiàn)在你是否對(duì)Boosting更感興趣了?不妨看看下面這些文章(主要討論GBM):
4.GBM參數(shù)
總的來(lái)說(shuō)GBM的參數(shù)可以被歸為三類:
樹參數(shù):調(diào)節(jié)模型中每個(gè)決定樹的性質(zhì)
Boosting參數(shù):調(diào)節(jié)模型中boosting的操作
其他模型參數(shù):調(diào)節(jié)模型總體的各項(xiàng)運(yùn)作
從樹參數(shù)開始,首先一個(gè)決定樹的大致結(jié)構(gòu)是這樣的:
現(xiàn)在我們看一看定義一個(gè)決定樹所需要的參數(shù)。注意我在這里用的都是python里scikit-learn里面的術(shù)語(yǔ),和其他軟件比如R里用到的可能不同,但原理都是相同的。
min_ samples_split
定義了樹中一個(gè)節(jié)點(diǎn)所需要用來(lái)分裂的最少樣本數(shù)。
可以避免過(guò)度擬合(over-fitting)。如果用于分類的樣本數(shù)太小,模型可能只適用于用來(lái)訓(xùn)練的樣本的分類,而用較多的樣本數(shù)則可以避免這個(gè)問(wèn)題。
但是如果設(shè)定的值過(guò)大,就可能出現(xiàn)欠擬合現(xiàn)象(under-fitting)。因此我們可以用CV值(離散系數(shù))考量調(diào)節(jié)效果。
min_ samples_leaf
定義了樹中終點(diǎn)節(jié)點(diǎn)所需要的最少的樣本數(shù)。
同樣,它也可以用來(lái)防止過(guò)度擬合。
在不均等分類問(wèn)題中(imbalanced class problems),一般這個(gè)參數(shù)需要被設(shè)定為較小的值,因?yàn)榇蟛糠稚贁?shù)類別(minority class)含有的樣本都比較小。
min_ weight_ fraction_leaf
和上面min_ samples_ leaf很像,不同的是這里需要的是一個(gè)比例而不是絕對(duì)數(shù)值:終點(diǎn)節(jié)點(diǎn)所需的樣本數(shù)占總樣本數(shù)的比值。
#2和#3只需要定義一個(gè)就行了
max_ depth
定義了樹的最大深度。
它也可以控制過(guò)度擬合,因?yàn)榉诸悩湓缴罹驮娇赡苓^(guò)度擬合。
當(dāng)然也應(yīng)該用CV值檢驗(yàn)。
max_ leaf_ nodes
定義了決定樹里最多能有多少個(gè)終點(diǎn)節(jié)點(diǎn)。
這個(gè)屬性有可能在上面max_ depth里就被定義了。比如深度為n的二叉樹就有最多2^n個(gè)終點(diǎn)節(jié)點(diǎn)。
如果我們定義了max_ leaf_ nodes,GBM就會(huì)忽略前面的max_depth。
max_ features
決定了用于分類的特征數(shù),是人為隨機(jī)定義的。
根據(jù)經(jīng)驗(yàn)一般選擇總特征數(shù)的平方根就可以工作得很好了,但還是應(yīng)該用不同的值嘗試,最多可以嘗試總特征數(shù)的30%-40%.
過(guò)多的分類特征可能也會(huì)導(dǎo)致過(guò)度擬合。
在繼續(xù)介紹其他參數(shù)前,我們先看一個(gè)簡(jiǎn)單的GBM二分類偽代碼:
1. 初始分類目標(biāo)的參數(shù)值
2. 對(duì)所有的分類樹進(jìn)行迭代:
2.1 根據(jù)前一輪分類樹的結(jié)果更新分類目標(biāo)的權(quán)重值(被錯(cuò)誤分類的有更高的權(quán)重)
2.2 用訓(xùn)練的子樣本建模
2.3 用所得模型對(duì)所有的樣本進(jìn)行預(yù)測(cè)
2.4 再次根據(jù)分類結(jié)果更新權(quán)重值
3. 返回最終結(jié)果
以上步驟是一個(gè)極度簡(jiǎn)化的BGM模型,而目前我們所提到的參數(shù)會(huì)影響2.2這一步,即建模的過(guò)程。現(xiàn)在我們來(lái)看看影響boosting過(guò)程的參數(shù):
learning_ rate
這個(gè)參數(shù)決定著每一個(gè)決定樹對(duì)于最終結(jié)果(步驟2.4)的影響。GBM設(shè)定了初始的權(quán)重值之后,每一次樹分類都會(huì)更新這個(gè)值,而learning_ rate控制著每次更新的幅度。
一般來(lái)說(shuō)這個(gè)值不應(yīng)該設(shè)的比較大,因?yàn)檩^小的learning rate使得模型對(duì)不同的樹更加穩(wěn)健,就能更好地綜合它們的結(jié)果。
n_ estimators
定義了需要使用到的決定樹的數(shù)量(步驟2)
雖然GBM即使在有較多決定樹時(shí)仍然能保持穩(wěn)健,但還是可能發(fā)生過(guò)度擬合。所以也需要針對(duì)learning rate用CV值檢驗(yàn)。
subsample
訓(xùn)練每個(gè)決定樹所用到的子樣本占總樣本的比例,而對(duì)于子樣本的選擇是隨機(jī)的。
用稍小于1的值能夠使模型更穩(wěn)健,因?yàn)檫@樣減少了方差。
一把來(lái)說(shuō)用~0.8就行了,更好的結(jié)果可以用調(diào)參獲得。
好了,現(xiàn)在我們已經(jīng)介紹了樹參數(shù)和boosting參數(shù),此外還有第三類參數(shù),它們能影響到模型的總體功能:
loss
指的是每一次節(jié)點(diǎn)分裂所要最小化的損失函數(shù)(loss function)
對(duì)于分類和回歸模型可以有不同的值。一般來(lái)說(shuō)不用更改,用默認(rèn)值就可以了,除非你對(duì)它及它對(duì)模型的影響很清楚。
init
它影響了輸出參數(shù)的起始化過(guò)程
如果我們有一個(gè)模型,它的輸出結(jié)果會(huì)用來(lái)作為GBM模型的起始估計(jì),這個(gè)時(shí)候就可以用init
random_ state
作為每次產(chǎn)生隨機(jī)數(shù)的隨機(jī)種子
使用隨機(jī)種子對(duì)于調(diào)參過(guò)程是很重要的,因?yàn)槿绻覀兠看味加貌煌碾S機(jī)種子,即使參數(shù)值沒(méi)變每次出來(lái)的結(jié)果也會(huì)不同,這樣不利于比較不同模型的結(jié)果。
任一個(gè)隨即樣本都有可能導(dǎo)致過(guò)度擬合,可以用不同的隨機(jī)樣本建模來(lái)減少過(guò)度擬合的可能,但這樣計(jì)算上也會(huì)昂貴很多,因而我們很少這樣用
verbose
決定建模完成后對(duì)輸出的打印方式:
0:不輸出任何結(jié)果(默認(rèn))
1:打印特定區(qū)域的樹的輸出結(jié)果
>1:打印所有結(jié)果
warm_ start
這個(gè)參數(shù)的效果很有趣,有效地使用它可以省很多事
使用它我們就可以用一個(gè)建好的模型來(lái)訓(xùn)練額外的決定樹,能節(jié)省大量的時(shí)間,對(duì)于高階應(yīng)用我們應(yīng)該多多探索這個(gè)選項(xiàng)。
presort
決定是否對(duì)數(shù)據(jù)進(jìn)行預(yù)排序,可以使得樹分裂地更快。
默認(rèn)情況下是自動(dòng)選擇的,當(dāng)然你可以對(duì)其更改
我知道我列了太多的參數(shù),所以我在我的GitHub里整理出了一張表,可以直接下載:GitHub地址
5.參數(shù)調(diào)節(jié)實(shí)例
City這個(gè)變量已經(jīng)被我舍棄了,因?yàn)橛刑喾N類了。
DOB轉(zhuǎn)為Age|DOB,舍棄了DOB
創(chuàng)建了EMI_Loan_Submitted_Missing這個(gè)變量,當(dāng)EMI_Loan_Submitted?變量值缺失時(shí)它的值為1,否則為0。然后舍棄了EMI_Loan_Submitted。
EmployerName的值也太多了,我把它也舍棄了
Existing_EMI的缺失值被填補(bǔ)為0(中位數(shù)),因?yàn)橹挥?11個(gè)缺失值
創(chuàng)建了Interest_Rate_Missing變量,類似于#3,當(dāng)Interest_Rate有值時(shí)它的值為0,反之為1,原來(lái)的Interest_Rate變量被舍棄了
Lead_Creation_Date也被舍棄了,因?yàn)閷?duì)結(jié)果看起來(lái)沒(méi)什么影響
用Loan_Amount_Applied和?Loan_Tenure_Applied的中位數(shù)填補(bǔ)了缺失值
創(chuàng)建了Loan_Amount_Submitted_Missing變量,當(dāng)Loan_Amount_Submitted有缺失值時(shí)為1,反之為0,原本的Loan_Amount_Submitted變量被舍棄
創(chuàng)建了Loan_Tenure_Submitted_Missing變量,當(dāng)Loan_Tenure_Submitted有缺失值時(shí)為1,反之為0,原本的Loan_Tenure_Submitted變量被舍棄
舍棄了LoggedIn,和Salary_Account
創(chuàng)建了Processing_Fee_Missing變量,當(dāng)Processing_Fee有缺失值時(shí)為1,反之為0,原本的Processing_Fee變量被舍棄
Source-top保留了2個(gè),其他組合成了不同的類別
對(duì)一些變量采取了數(shù)值化和獨(dú)熱編碼(One-Hot-Coding)操作
你們可以從GitHub里data_preparation iPython notebook中看到這些改變。
首先,我們加載需要的library和數(shù)據(jù):
#Import libraries:
import pandas as pd
import numpy as np
from sklearn.ensemble import GradientBoostingClassifier #GBM algorithm
from sklearn import cross_validation, metrics #Additional scklearn functions
from sklearn.grid_search import GridSearchCV #Perforing grid search
import matplotlib.pylab as plt
%matplotlib inline
from matplotlib.pylab import rcParams
rcParams['figure.figsize'] = 12, 4
train = pd.read_csv('train_modified.csv')
target = 'Disbursed'
IDcol = 'ID'
然后我們來(lái)寫一個(gè)創(chuàng)建GBM模型和CV值的函數(shù)。
def modelfit(alg, dtrain, predictors, performCV=True, printFeatureImportance=True, cv_folds=5):
#Fit the algorithm on the data
alg.fit(dtrain[predictors], dtrain['Disbursed'])
#Predict training set:
dtrain_predictions = alg.predict(dtrain[predictors])
dtrain_predprob = alg.predict_proba(dtrain[predictors])[:,1]
#Perform cross-validation:
if performCV:
cv_score = cross_validation.cross_val_score(alg, dtrain[predictors], dtrain['Disbursed'], cv=cv_folds, scoring='roc_auc')
#Print model report:
print "\nModel Report"
print "Accuracy : %.4g" % metrics.accuracy_score(dtrain['Disbursed'].values, dtrain_predictions)
print "AUC Score (Train): %f" % metrics.roc_auc_score(dtrain['Disbursed'], dtrain_predprob)
if performCV:
print "CV Score : Mean - %.7g | Std - %.7g | Min - %.7g | Max - %.7g" % (np.mean(cv_score),np.std(cv_score),np.min(cv_score),np.max(cv_score))
#Print Feature Importance:
if printFeatureImportance:
feat_imp = pd.Series(alg.feature_importances_, predictors).sort_values(ascending=False)
feat_imp.plot(kind='bar', title='Feature Importances')
plt.ylabel('Feature Importance Score')
接著就要?jiǎng)?chuàng)建一個(gè)基線模型(baseline model)。這里我們用AUC來(lái)作為衡量標(biāo)準(zhǔn),所以用常數(shù)的話AUC就是0.5。一般來(lái)說(shuō)用默認(rèn)參數(shù)設(shè)置的GBM模型就是一個(gè)很好的基線模型,我們來(lái)看看這個(gè)模型的輸出和特征重要性:
#Choose all predictors except target & IDcols
predictors = [x for x in train.columns if x not in [target, IDcol]]
gbm0 = GradientBoostingClassifier(random_state=10)
modelfit(gbm0, train, predictors)
從圖上看出,CV的平均值是0.8319,后面調(diào)整的模型會(huì)做得比這個(gè)更好。
5.1 參數(shù)調(diào)節(jié)的一般方法
之前說(shuō)過(guò),我們要調(diào)節(jié)的參數(shù)有兩種:樹參數(shù)和boosting參數(shù)。learning rate沒(méi)有什么特別的調(diào)節(jié)方法,因?yàn)橹灰覀冇?xùn)練的樹足夠多l(xiāng)earning rate總是小值來(lái)得好。
雖然隨著決定樹的增多GBM并不會(huì)明顯得過(guò)度擬合,高learing rate還是會(huì)導(dǎo)致這個(gè)問(wèn)題,但如果我們一味地減小learning rate、增多樹,計(jì)算就會(huì)非常昂貴而且需要運(yùn)行很長(zhǎng)時(shí)間。了解了這些問(wèn)題,我們決定采取以下方法調(diào)參:
選擇一個(gè)相對(duì)來(lái)說(shuō)稍微高一點(diǎn)的learning rate。一般默認(rèn)的值是0.1,不過(guò)針對(duì)不同的問(wèn)題,0.05到0.2之間都可以
決定當(dāng)前l(fā)earning rate下最優(yōu)的決定樹數(shù)量。它的值應(yīng)該在40-70之間。記得選擇一個(gè)你的電腦還能快速運(yùn)行的值,因?yàn)橹筮@些樹會(huì)用來(lái)做很多測(cè)試和調(diào)參。
接著調(diào)節(jié)樹參數(shù)來(lái)調(diào)整learning rate和樹的數(shù)量。我們可以選擇不同的參數(shù)來(lái)定義一個(gè)決定樹,后面會(huì)有這方面的例子
降低learning rate,同時(shí)會(huì)增加相應(yīng)的決定樹數(shù)量使得模型更加穩(wěn)健
5.2固定 learning rate和需要估測(cè)的決定樹數(shù)量
為了決定boosting參數(shù),我們得先設(shè)定一些參數(shù)的初始值,可以像下面這樣:
min_ samples_ split=500:?這個(gè)值應(yīng)該在總樣本數(shù)的0.5-1%之間,由于我們研究的是不均等分類問(wèn)題,我們可以取這個(gè)區(qū)間里一個(gè)比較小的數(shù),500。
min_ samples_ leaf=50:?可以憑感覺選一個(gè)合適的數(shù),只要不會(huì)造成過(guò)度擬合。同樣因?yàn)椴痪确诸惖脑?#xff0c;這里我們選擇一個(gè)比較小的值。
max_ depth=8:?根據(jù)觀察數(shù)和自變量數(shù),這個(gè)值應(yīng)該在5-8之間。這里我們的數(shù)據(jù)有87000行,49列,所以我們先選深度為8。
max_ features=’sqrt’:?經(jīng)驗(yàn)上一般都選擇平方根。
subsample=0.8:?開始的時(shí)候一般就用0.8
注意我們目前定的都是初始值,最終這些參數(shù)的值應(yīng)該是多少還要靠調(diào)參決定。現(xiàn)在我們可以根據(jù)learning rate的默認(rèn)值0.1來(lái)找到所需要的最佳的決定樹數(shù)量,可以利用網(wǎng)格搜索(grid search)實(shí)現(xiàn),以10個(gè)數(shù)遞增,從20測(cè)到80。
#Choose all predictors except target & IDcols
predictors = [x for x in train.columns if x not in [target, IDcol]]
param_test1 = {'n_estimators':range(20,81,10)}
gsearch1 = GridSearchCV(estimator = GradientBoostingClassifier(learning_rate=0.1, min_samples_split=500,min_samples_leaf=50,max_depth=8,max_features='sqrt',subsample=0.8,random_state=10),
param_grid = param_test1, scoring='roc_auc',n_jobs=4,iid=False, cv=5)
gsearch1.fit(train[predictors],train[target])
來(lái)看一下輸出結(jié)果:
gsearch1.grid_scores_, gsearch1.best_params_, gsearch1.best_score_
1
可以看出對(duì)于0.1的learning rate, 60個(gè)樹是最佳的,而且60也是一個(gè)合理的決定樹數(shù)量,所以我們就直接用60。但在一些情況下上面這段代碼給出的結(jié)果可能不是我們想要的,比如:
如果給出的輸出是20,可能就要降低我們的learning rate到0.05,然后再搜索一遍。
如果輸出值太高,比如100,因?yàn)檎{(diào)節(jié)其他參數(shù)需要很長(zhǎng)時(shí)間,這時(shí)候可以把learniing rate稍微調(diào)高一點(diǎn)。
5.3 調(diào)節(jié)樹參數(shù)
樹參數(shù)可以按照這些步驟調(diào)節(jié):
調(diào)節(jié)max_depth和?num_samples_split
調(diào)節(jié)min_samples_leaf
調(diào)節(jié)max_features
需要注意一下調(diào)參順序,對(duì)結(jié)果影響最大的參數(shù)應(yīng)該優(yōu)先調(diào)節(jié),就像max_depth和num_samples_split。
重要提示:接著我會(huì)做比較久的網(wǎng)格搜索(grid search),可能會(huì)花上15-30分鐘。你在自己嘗試的時(shí)候應(yīng)該根據(jù)電腦情況適當(dāng)調(diào)整需要測(cè)試的值。
max_depth可以相隔兩個(gè)數(shù)從5測(cè)到15,而min_samples_split可以按相隔200從200測(cè)到1000。這些完全憑經(jīng)驗(yàn)和直覺,如果先測(cè)更大的范圍再用迭代去縮小范圍也是可行的。
param_test2 = {'max_depth':range(5,16,2), 'min_samples_split':range(200,1001,200)}
gsearch2 = GridSearchCV(estimator = GradientBoostingClassifier(learning_rate=0.1, n_estimators=60, max_features='sqrt', subsample=0.8, random_state=10),
param_grid = param_test2, scoring='roc_auc',n_jobs=4,iid=False, cv=5)
gsearch2.fit(train[predictors],train[target])
gsearch2.grid_scores_, gsearch2.best_params_, gsearch2.best_score_
從結(jié)果可以看出,我們從30種組合中找出最佳的max_depth是9,而最佳的min_smaples_split是1000。1000是我們?cè)O(shè)定的范圍里的最大值,有可能真正的最佳值比1000還要大,所以我們還要繼續(xù)增加min_smaples_split。樹深就用9。接著就來(lái)調(diào)節(jié)min_samples_leaf,可以測(cè)30,40,50,60,70這五個(gè)值,同時(shí)我們也試著調(diào)大min_samples_leaf的值。
param_test3 = {'min_samples_split':range(1000,2100,200), 'min_samples_leaf':range(30,71,10)}
gsearch3 = GridSearchCV(estimator = GradientBoostingClassifier(learning_rate=0.1, n_estimators=60,max_depth=9,max_features='sqrt', subsample=0.8, random_state=10),
param_grid = param_test3, scoring='roc_auc',n_jobs=4,iid=False, cv=5)
gsearch3.fit(train[predictors],train[target])
gsearch3.grid_scores_, gsearch3.best_params_, gsearch3.best_score_
這樣min_samples_split的最佳值是1200,而min_samples_leaf的最佳值是60。注意現(xiàn)在CV值增加到了0.8396?,F(xiàn)在我們就根據(jù)這個(gè)結(jié)果來(lái)重新建模,并再次評(píng)估特征的重要性。
modelfit(gsearch3.best_estimator_, train, predictors)
1
比較之前的基線模型結(jié)果可以看出,現(xiàn)在我們的模型用了更多的特征,并且基線模型里少數(shù)特征的重要性評(píng)估值過(guò)高,分布偏斜明顯,現(xiàn)在分布得更加均勻了。
接下來(lái)就剩下最后的樹參數(shù)max_features了,可以每隔兩個(gè)數(shù)從7測(cè)到19。
param_test4 = {'max_features':range(7,20,2)}
gsearch4 = GridSearchCV(estimator = GradientBoostingClassifier(learning_rate=0.1, n_estimators=60,max_depth=9, min_samples_split=1200, min_samples_leaf=60, subsample=0.8, random_state=10),
param_grid = param_test4, scoring='roc_auc',n_jobs=4,iid=False, cv=5)
gsearch4.fit(train[predictors],train[target])
gsearch4.grid_scores_, gsearch4.best_params_, gsearch4.best_score_
最佳的結(jié)果是7,正好就是我們?cè)O(shè)定的初始值(平方根)。當(dāng)然你可能還想測(cè)測(cè)小于7的值,我也鼓勵(lì)你這么做。而按照我們的設(shè)定,現(xiàn)在的樹參數(shù)是這樣的:
min_samples_split: 1200
min_samples_leaf: 60
max_depth: 9
max_features: 7
5.4 調(diào)節(jié)子樣本比例來(lái)降低learning rate
接下來(lái)就可以調(diào)節(jié)子樣本占總樣本的比例,我準(zhǔn)備嘗試這些值:0.6,0.7,0.75,0.8,0.85,0.9。
param_test5 = {'subsample':[0.6,0.7,0.75,0.8,0.85,0.9]}
gsearch5 = GridSearchCV(estimator = GradientBoostingClassifier(learning_rate=0.1, n_estimators=60,max_depth=9,min_samples_split=1200, min_samples_leaf=60, subsample=0.8, random_state=10,max_features=7),
param_grid = param_test5, scoring='roc_auc',n_jobs=4,iid=False, cv=5)
gsearch5.fit(train[predictors],train[target])
gsearch5.grid_scores_, gsearch5.best_params_, gsearch5.best_score_
1
2
3
4
5
給出的結(jié)果是0.85。這樣所有的參數(shù)都設(shè)定好了,現(xiàn)在我們要做的就是進(jìn)一步減少learning rate,就相應(yīng)地增加了樹的數(shù)量。需要注意的是樹的個(gè)數(shù)是被動(dòng)改變的,可能不是最佳的,但也很合適。隨著樹個(gè)數(shù)的增加,找到最佳值和CV的計(jì)算量也會(huì)加大,為了看出模型執(zhí)行效率,我還提供了我每個(gè)模型在比賽的排行分?jǐn)?shù)(leaderboard score),怎么得到這個(gè)數(shù)據(jù)不是公開的,你很難重現(xiàn)這個(gè)數(shù)字,它只是為了更好地幫助我們理解模型表現(xiàn)。
現(xiàn)在我們先把learning rate降一半,至0.05,這樣樹的個(gè)數(shù)就相應(yīng)地加倍到120。
predictors = [x for x in train.columns if x not in [target, IDcol]]
gbm_tuned_1 = GradientBoostingClassifier(learning_rate=0.05, n_estimators=120,max_depth=9, min_samples_split=1200,min_samples_leaf=60, subsample=0.85, random_state=10, max_features=7)
modelfit(gbm_tuned_1, train, predictors)
排行得分:0.844139
接下來(lái)我們把learning rate進(jìn)一步減小到原值的十分之一,即0.01,相應(yīng)地,樹的個(gè)數(shù)變?yōu)?00。
predictors = [x for x in train.columns if x not in [target, IDcol]]
gbm_tuned_2 = GradientBoostingClassifier(learning_rate=0.01, n_estimators=600,max_depth=9, min_samples_split=1200,min_samples_leaf=60, subsample=0.85, random_state=10, max_features=7)
modelfit(gbm_tuned_2, train, predictors)
排行得分:0.848145
繼續(xù)把learning rate縮小至二十分之一,即0.005,這時(shí)候我們有1200個(gè)樹。
predictors = [x for x in train.columns if x not in [target, IDcol]]
gbm_tuned_3 = GradientBoostingClassifier(learning_rate=0.005, n_estimators=1200,max_depth=9, min_samples_split=1200, min_samples_leaf=60, subsample=0.85, random_state=10, max_features=7,
warm_start=True)
modelfit(gbm_tuned_3, train, predictors, performCV=False)
排行得分:0.848112
排行得分稍微降低了,我們停止減少learning rate,只單方面增加樹的個(gè)數(shù),試試1500個(gè)樹。
predictors = [x for x in train.columns if x not in [target, IDcol]]
gbm_tuned_4 = GradientBoostingClassifier(learning_rate=0.005, n_estimators=1500,max_depth=9, min_samples_split=1200, min_samples_leaf=60, subsample=0.85, random_state=10, max_features=7,
warm_start=True)
modelfit(gbm_tuned_4, train, predictors, performCV=False)
排行得分:0.848747
看,就這么簡(jiǎn)單,排行得分已經(jīng)從0.844升高到0.849了,這可是一個(gè)很大的提升。
還有一個(gè)技巧就是用“warm_start”選項(xiàng)。這樣每次用不同個(gè)數(shù)的樹都不用重新開始。所有的代碼都可以從我的Github里下載到。
6.總結(jié)
這篇文章詳細(xì)地介紹了GBM模型。我們首先了解了何為boosting,然后詳細(xì)介紹了各種參數(shù)。 這些參數(shù)可以被分為3類:樹參數(shù),boosting參數(shù),和其他影響模型的參數(shù)。最后我們提到了用GBM解決問(wèn)題的?一般方法,并且用AV Data Hackathon 3.x problem數(shù)據(jù)運(yùn)用了這些方法。最后,希望這篇文章確實(shí)幫助你更好地理解了GBM,在下次運(yùn)用GBM解決問(wèn)題的時(shí)候也更有信心。
總結(jié)
以上是生活随笔為你收集整理的python调参工作都是干啥的_Python中Gradient Boosting Machine(GBM)调参方法详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: P1616 疯狂的采药(洛谷,动态规划递
- 下一篇: data transformation