本文作者:王 歌
文字編輯:戴 雯
技術總編:張 邯
我們上一次介紹了集成學習中的Bagging算法以及由它拓展的隨機森林忧便,今天我們繼續(xù)介紹集成學習的另一類——Boosting算法头岔。
1算法介紹
相比于Bagging
的并行垒棋,Boosting
是串行生成的算法,即每一次的訓練都是對上一次的修正蕉堰,更注重上一次訓練時出現(xiàn)判斷錯誤的樣本,對分錯的樣本賦予更大的權重。在訓練得到n個學習器后再對這些學習器進行加權結合莽龟,這就是Boosting
的基本思想。Boosting
一般有兩種更新權重的方法锨天,一是給 樣本重新賦權 毯盈,二是 重新在原始樣本中按照權重進行有放回抽樣 。
在Boosting
算法中有幾個算法是經(jīng)常用到的病袄,這也是我們今天要講解的重點——AdaBoost
搂赋、GBDT
和XGBoost
。這三種算法都是源于Boosting
算法的基本思想益缠,下面我們主要介紹這三種算法在Boosting
的基礎上有哪些差別脑奠。
對于 AdaBoost(Adaptive Boosting) 算法,首先從每一輪權值改變的方式設置上幅慌,該算法在初始化時宋欺,將所有弱學習器的權重都設置為1/N,在后續(xù)的迭代中欠痴,那些在上一輪迭代中被預測錯的樣本的權重將增加迄靠,最后對得到的所有學習器進行加權組合。為了防止過擬合喇辽,還可以在迭代中加入正則化項掌挚。AdaBoost不像我們下面介紹的兩種方法,它可以自己定義使用的基學習器菩咨,在這一點上要更有優(yōu)勢吠式。
GBDT(Gradient Boosting Decision Tree 或 Gradient Tree Boosting ,梯度樹提升抽米,回歸時也簡稱GBRT特占,這里統(tǒng)一使用GBDT)并不是通過AdaBoost那樣在每一輪迭代中更改權重,而是使用新的分類器去擬合前面分類器預測的殘差云茸,使每一次的計算都能減少上一輪的殘差是目,并在殘差減少的方向建立新的學習器,也就是在每一輪迭代中對損失函數(shù)的負梯度方向構造決策樹标捺,該方法將基學習器限定在只能使用CART決策樹來進行分類和回歸懊纳。我們可以通過剪枝或子采樣揉抵、正則化來防止出現(xiàn)過擬合。所以GBDT的基學習器是決策樹嗤疯,通過梯度提升(Gradient Boosting)進行集成冤今。相比于同樣使用決策樹為基學習器的隨機森林,GBDT 減少了模型的偏差茂缚,而隨機森林減少的是模型的方差戏罢。
XGBoost(eXtreme Gradient Boosting) 算法就是 GBDT的改進,因此使用的依然是決策樹作為基學習器脚囊。它對GBDT的改進主要是兩個方面龟糕,一是GBDT將目標函數(shù)泰勒公式展開到一階,而XGBoost將目標函數(shù)泰勒公式展開到了二階凑术,提升了預測效果翩蘸;二是XGBoost增加了自動處理缺失值特征的策略;三是XGBoost在損失函數(shù)中加入了正則項淮逊,控制了模型的復雜度催首,因此XGBoost的表現(xiàn)通常要優(yōu)于GBDT。
2類參數(shù)介紹
在sklearn中AdaBoost算法有兩個類泄鹏,即AdaBoostClassifier
和AdaBoostRegressor
郎任,前者用于分類,后者用于回歸备籽。我們這里主要介紹AdaBoostClassifier
舶治,由于基學習器主要使用的是默認的決策樹算法,因此其中大部分參數(shù)我們在上一次以及之前的介紹中已經(jīng)提到過车猬,不再贅述霉猛,另有兩個新的參數(shù)要了解:
(1)algorithm
:設定AdaBoost分類使用的算法,可以選擇SAMME和SAMME.R珠闰,兩者使用的弱學習器權重不同惜浅,其中SAMME使用對樣本集分類效果作為弱學習器權重,SAMME.R使用了對樣本集分類的預測概率作為弱學習器權重伏嗜,由于SAMME.R使用了連續(xù)值坛悉,迭代速度一般比SAMME快,默認使用的也是SAMME.R算法承绸;
(2)learning_rate
:設定弱學習器的權重縮減系數(shù)v裸影,0<v≤1,要達到同樣的擬合效果军熏,較小的v比較大的v需要更多次的迭代轩猩,默認為1。
GradientBoostingClassifier
為GBDT分類算法的類,GradientBoostingRegressor
為GBDT的回歸類界轩。在GradientBoostingClassifier
類中画饥,主要有以下幾個新的參數(shù)要注意:
(1)subsample
:設定訓練每個決策樹所用到的子樣本占總樣本的比例衔瓮,取值為(0浊猾,1]這里使用的是不放回抽樣,默認取1热鞍,即不使用子采樣葫慎;
(2)init
:設定初始化的弱學習器,若我們有先驗模型薇宠,可以將其作為初始化的學習器偷办;
(3)loss
:設定每次結點分裂所使用的最小化損失函數(shù),有對數(shù)似然損失函數(shù)"deviance"和指數(shù)損失函數(shù)"exponential"兩種選擇澄港,默認為"deviance"椒涯。
而XGBoost算法要使用xgboost
類庫來實現(xiàn)。sklearn中沒有集成xgboost回梧,因此首先要單獨下載安裝废岂。xgboost有兩種接口,一種是自帶的原生python接口狱意,另一種是sklearn接口湖苞,兩種接口的使用基本一致,得到的結果也是一樣的详囤,只是在三個參數(shù)名上會稍有不同财骨,并且在導入時,原生接口可直接使用以下命令:
import xgboost as xgb
而sklearn的接口可以使用(若為回歸則使用XGBRegressor):
from xgboost.sklearn import XGBClassifier
一般我們更推薦使用sklearn的接口藏姐,我們這里也是以sklearn接口為基礎來介紹和演示隆箩。除了base_score
、learning_rate
羔杨、max_depth
捌臊、n_estimators
、n_jobs
问畅、random_state
娃属、subsample
和前面介紹的類相同的參數(shù)外,還有以下參數(shù):
(1)objective
:確定使用的目標函數(shù)护姆,默認為'binary:logistic'矾端,若為回歸問題,也可選擇'reg:linear'卵皂、'reg:logistic'秩铆,若為二分類,可以選擇'binary:logistic'、'binary:logitraw'殴玛,前者得到概率捅膘,后者得到類別,若為多分類滚粟,可以選擇'multi:softmax num_class=n'寻仗、'multi:softprob num_class=n',前者得到類別凡壤,后者得到概率署尤;
(2)booster
:確定弱學習器類型,默認為gbtree亚侠,即CART決策樹曹体,也可選擇gbliner(線性模型)作為基分類器;
(3)gamma
:設定結點分裂所需要的最小損失函數(shù)下降值,當損失函數(shù)下降值低于這個值時不再向下劃分,默認為None丐膝;
(4)min_child_weight
:設定子結點權重的最小值苗胀,小于此值時不再分裂,默認為None;
(5)max_delta_step
:設定每棵樹權重改變的最大步長,默認為None;
(6)colsample_bytree
:訓練每棵樹時的屬性采樣比例厨诸,默認為None,即不采樣使用所有屬性禾酱;
(7)colsample_bynode
:訓練某一個樹結點時的屬性采樣比例微酬,默認為None;
(8)colsample_bylevel
:訓練某一層時的屬性采樣比例颤陶,默認為None颗管;
(9)reg_alpha
:設定L1正則化系數(shù),默認為None滓走;
(10)reg_lambda
:設定L2正則化系數(shù)垦江,默認為None;
(11)scale_pos_weight
:類別不平衡時設定負例和正例的比例搅方,默認為None比吭;
(12)importance_type
:用來設置如何計算各個屬性的重要程度,默認為'gain'姨涡,還可選擇'weight'衩藤、'cover'、'total_gain'或'total_cover'涛漂,'gain'和'total_gain'分別表示通過計算屬性被選作分裂屬性時帶來的平均增益和總增益來計算重要性赏表,'cover'和'total_cover'則分別通過計算屬性被選作分裂時的平均樣本覆蓋度和總體樣本覆蓋度來計算重要性检诗,'weight'通過屬性被選作分裂特征的次數(shù)來計算重要性,可以通過調(diào)用booster的get_score方法查看對應的屬性權重瓢剿。
3算法實例
針對我們上面介紹的三個庫逢慌,我們來實際操作對比一下,這里我們以分類算法為例间狂,使用鳶尾花的數(shù)據(jù)攻泼,首先我們分別輸出三種算法的預測值和準確度,程序如下:
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import AdaBoostClassifier, GradientBoostingClassifier
from xgboost.sklearn import XGBClassifier
from sklearn.metrics import accuracy_score
iris_sample = load_iris()
x_train, x_test, y_train, y_test = train_test_split(
iris_sample.data, iris_sample.target, test_size=0.25, random_state=123)
print('真實值:', y_test)
# AdaBoost分類
adbclf = AdaBoostClassifier(learning_rate=0.1, n_estimators=100)
adbclf.fit(x_train, y_train)
y_adb_pre = adbclf.predict(x_test)
print('AdaBoost預測:', y_adb_pre)
print('AdaBoost準確度:', accuracy_score(y_test, y_adb_pre))
# GBDT分類
gbdtclf = GradientBoostingClassifier(
max_depth=5, learning_rate=0.7, n_estimators=100)
gbdtclf.fit(x_train, y_train)
y_gbdt_pre = gbdtclf.predict(x_test)
print('GBDT預測:', y_gbdt_pre)
print('GBDT準確度:', accuracy_score(y_test, y_gbdt_pre))
# XGBoost分類
xgbclf = XGBClassifier(max_depth=5, learning_rate=0.7,
n_estimators=100, objective='multi:softmax')
xgbclf.fit(x_train, y_train)
y_xgb_pre = xgbclf.predict(x_test)
print('XGBoost預測:', y_xgb_pre)
print('XGBoost準確度:', accuracy_score(y_test, y_xgb_pre))
預測結果如下圖:
可以看到按照既定參數(shù)得到的模型中前标,XGBoost的預測準確度最高坠韩。在此基礎上我們查看一下XGBoost模型中的屬性重要性并輸出重要性圖,程序如下:
from matplotlib import pyplot as plt
from xgboost import plot_importance
plot_importance(xgbclf)
plt.show()
結果如下圖:
由上圖可以看到炼列,第四個屬性petal width(花瓣寬度)的重要性最高。
相比而言音比,AdaBoost可以使用各種模型來構建弱學習器俭尖,并且不容易發(fā)生過擬合,但對異常數(shù)據(jù)較敏感洞翩,容易受到噪聲的干擾稽犁;GBDT算法則對異常點是魯棒的,可以處理混合類型的特征骚亿,比較適合低維數(shù)據(jù)已亥,能夠處理非線性數(shù)據(jù);而XGBoost算法由于是對GBDT的改進来屠,因此它的運算速度和算法都會優(yōu)于GBDT虑椎,不容易發(fā)生過擬合,計算量較小俱笛。目前在結構化數(shù)據(jù)上捆姜,XGBoost算法的表現(xiàn)會更好,因此也受到各種比賽的歡迎迎膜。大家快去試試吧泥技!