GBDT(Gradient Boosting Decision Tree 梯度提升決策樹(shù))算法近年十分流行,被廣泛應(yīng)用于各類(lèi)數(shù)據(jù)挖掘以及機(jī)器學(xué)習(xí)的比賽之中并有著良好的表現(xiàn)庇麦。下面讓我們來(lái)走進(jìn)這個(gè)算法喜德。
起源
提起GBDT的起源山橄,我們不得不引出以下幾個(gè)概念住诸。
集成學(xué)習(xí)
引用百科中的一段話:
集成學(xué)習(xí)是使用一系列學(xué)習(xí)器進(jìn)行學(xué)習(xí)涣澡,并使用某種規(guī)則把各個(gè)學(xué)習(xí)結(jié)果進(jìn)行整合從而獲得比單個(gè)學(xué)習(xí)器更好的學(xué)習(xí)效果的一種機(jī)器學(xué)習(xí)方法丧诺。一般情況下,集成學(xué)習(xí)中的多個(gè)學(xué)習(xí)器都是同質(zhì)的"弱學(xué)習(xí)器"驳阎。
所謂“同質(zhì)”,是指集成中只包含同種類(lèi)型的個(gè)體學(xué)習(xí)器呵晚。所謂“弱學(xué)習(xí)器”,是指泛化性能略?xún)?yōu)于隨機(jī)猜測(cè)的學(xué)習(xí)器饵隙,例如在二分類(lèi)問(wèn)題上精度略高于50%的分類(lèi)器。換句話說(shuō)芯急,弱學(xué)習(xí)器的結(jié)果接近于靠猜驶俊。
集成學(xué)習(xí)通過(guò)將多個(gè)學(xué)習(xí)器進(jìn)行結(jié)合娶耍,通潮穑可以獲得比單一學(xué)習(xí)器顯著優(yōu)越的泛化性能,這對(duì)弱學(xué)習(xí)器尤明顯想鹰。如何結(jié)合個(gè)體學(xué)習(xí)器,就是集成學(xué)習(xí)研究的核心。目前的集成學(xué)習(xí)方法大致可分為兩大類(lèi):1)個(gè)體學(xué)習(xí)器間存在強(qiáng)依賴(lài)關(guān)系刚陡、必須串行生成的序列化方法,代表是Boosting蝙云;2)個(gè)體學(xué)習(xí)器間不存在強(qiáng)依賴(lài)關(guān)系路召、可同時(shí)生成的并行化方法,代表是Bagging和隨機(jī)森林(Random Forest)身隐。
Boosting
Boosting是一族可將弱學(xué)習(xí)器提升為強(qiáng)學(xué)習(xí)器的算法贾铝。
Boosting算法原理:
- 先對(duì)N個(gè)訓(xùn)練樣本S1的學(xué)習(xí)得到一個(gè)基分類(lèi)器M1;
- 將S1中分錯(cuò)的樣本和其他新的數(shù)據(jù)一起構(gòu)成新的N個(gè)訓(xùn)練樣本S2玖绿,再得到一個(gè)基分類(lèi)器M2斑匪;
- 將S1和S2中都分錯(cuò)的樣本和其他新的數(shù)據(jù)一起構(gòu)成新的N個(gè)訓(xùn)練樣本S3蚀瘸,再得到一個(gè)基分類(lèi)器M3宙刘;
- 以此類(lèi)推悬包,直至基學(xué)習(xí)器數(shù)達(dá)到事先指定的值T,最終將所有基學(xué)習(xí)器進(jìn)行加權(quán)結(jié)合垫释。
簡(jiǎn)單來(lái)說(shuō)棵譬,就是基于同一訓(xùn)練集和同一個(gè)算法訓(xùn)練出T個(gè)基學(xué)習(xí)器订咸,每一輪訓(xùn)練都針對(duì)上一輪的訓(xùn)練結(jié)果調(diào)整樣本分布酬诀。
Boosting族算法最著名的代表是AdaBoost瞒御。
Bagging
Bagging是Bootstrap AGGregatING的縮寫(xiě),基于自助采樣法(bootstrap sampling)(一種有放回的抽樣方法涌乳,即可能抽到重復(fù)的樣本)。
Bagging算法原理:
- 使用自助采樣法采樣出T個(gè)含有m個(gè)訓(xùn)練樣本的采樣集带欢,然后基于每個(gè)采樣集訓(xùn)練出一個(gè)基學(xué)習(xí)器乔煞,再將這些基本學(xué)習(xí)器進(jìn)行結(jié)合。
- 在對(duì)預(yù)測(cè)輸出進(jìn)行結(jié)合時(shí)逗宜,Bagging通常對(duì)分了任務(wù)使用簡(jiǎn)單投票法纺讲,對(duì)回歸任務(wù)使用簡(jiǎn)單平均法囤屹。
Gradient Boosting
Gradient Boosting是一種Boosting的方法肋坚,它主要的思想是,每一次建立模型是在之前建立模型損失函數(shù)的梯度下降方向诲泌。損失函數(shù)是評(píng)價(jià)模型性能(一般為擬合程度+正則項(xiàng))敷扫,認(rèn)為損失函數(shù)越小葵第,性能越好合溺。而讓損失函數(shù)持續(xù)下降,就能使得模型不斷改性提升性能,其最好的方法就是使損失函數(shù)沿著梯度方向下降将硝。Gradient Boost是一個(gè)框架,里面可以套入很多不同的算法痰腮。
GBDT應(yīng)用
分類(lèi)
from sklearn import ensemble
clf = ensemble.GradientBoostingClassifier()
gbdt_model = clf.fit(X_train, y_train) # Training model
predicty_x = gbdt_model.predict_proba(test_x)[:, 1] # predict: probablity of 1
# 包含的參數(shù)
# loss = loss, learning_rate = learning_rate, n_estimators = n_estimators,
# min_samples_split = min_samples_split,
# min_samples_leaf = min_samples_leaf,
# min_weight_fraction_leaf = min_weight_fraction_leaf,
# max_depth = max_depth, init = init, subsample = subsample,
# max_features = max_features,
# random_state = random_state, verbose = verbose,
# max_leaf_nodes = max_leaf_nodes, warm_start = warm_start,
# presort = presort
回歸
from sklearn import ensemble
clf = ensemble.GradientBoostingRegressor()
gbdt_model = clf.fit(X_train, y_train) # Training model
y_upper = gbdt_model.predict(x_test) # predict
構(gòu)建新特征
思想:GBDT每棵樹(shù)的路徑直接作為L(zhǎng)R輸入特征使用膀值。
用已有特征訓(xùn)練GBDT模型沧踏,然后利用GBDT模型學(xué)習(xí)到的樹(shù)來(lái)構(gòu)造新特征,最后把這些新特征加入原有特征一起訓(xùn)練模型翘狱。構(gòu)造的新特征向量是取值0/1的潦匈,向量的每個(gè)元素對(duì)應(yīng)于GBDT模型中樹(shù)的葉子結(jié)點(diǎn)。當(dāng)一個(gè)樣本點(diǎn)通過(guò)某棵樹(shù)最終落在這棵樹(shù)的一個(gè)葉子結(jié)點(diǎn)上赤惊,那么在新特征向量中這個(gè)葉子結(jié)點(diǎn)對(duì)應(yīng)的元素值為1未舟,而這棵樹(shù)的其他葉子結(jié)點(diǎn)對(duì)應(yīng)的元素值為0寡夹。新特征向量的長(zhǎng)度等于GBDT模型里所有樹(shù)包含的葉子結(jié)點(diǎn)數(shù)之和菩掏。
# 弱分類(lèi)器的數(shù)目
n_estimator = 10
# 隨機(jī)生成分類(lèi)數(shù)據(jù)智绸。
X, y = make_classification(n_samples=80000)
# 切分為測(cè)試集和訓(xùn)練集,比例0.5
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5)
# 將訓(xùn)練集切分為兩部分斯稳,一部分用于訓(xùn)練GBDT模型挣惰,另一部分輸入到訓(xùn)練好的GBDT模型生成GBDT特征,然后作為L(zhǎng)R的特征珍语。這樣分成兩部分是為了防止過(guò)擬合竖幔。
X_train, X_train_lr, y_train, y_train_lr = train_test_split(X_train, y_train, test_size=0.5)
# 調(diào)用GBDT分類(lèi)模型拳氢。
grd = GradientBoostingClassifier(n_estimators=n_estimator)
# 調(diào)用one-hot編碼。
grd_enc = OneHotEncoder()
# 調(diào)用LR分類(lèi)模型放接。
grd_lm = LogisticRegression()
# 使用X_train訓(xùn)練GBDT模型透乾,后面用此模型構(gòu)造特征
grd.fit(X_train, y_train)
# fit one-hot編碼器
grd_enc.fit(grd.apply(X_train)[:, :, 0])
# 使用訓(xùn)練好的GBDT模型構(gòu)建特征磕秤,然后將特征經(jīng)過(guò)one-hot編碼作為新的特征輸入到LR模型訓(xùn)練市咆。
grd_lm.fit(grd_enc.transform(grd.apply(X_train_lr)[:, :, 0]), y_train_lr)
# 用訓(xùn)練好的LR模型多X_test做預(yù)測(cè)
y_pred_grd_lm = grd_lm.predict_proba(grd_enc.transform(grd.apply(X_test)[:, :, 0]))[:, 1]
# 根據(jù)預(yù)測(cè)結(jié)果輸出
fpr_grd_lm, tpr_grd_lm, _ = roc_curve(y_test, y_pred_grd_lm)