1 Xgboost簡介
??Xgboost是Boosting算法的其中一種炸站,Boosting算法的思想是將許多弱分類器集成在一起,形成一個(gè)強(qiáng)分類器乘客。因?yàn)閄gboost是一種提升樹模型蝙叛,所以它是將許多樹模型集成在一起,形成一個(gè)很強(qiáng)的分類器瓦堵。而所用到的樹模型則是CART回歸樹模型。
??Xgboost是在GBDT的基礎(chǔ)上進(jìn)行改進(jìn)歌亲,使之更強(qiáng)大菇用,適用于更大范圍。
??Xgboost一般和sklearn一起使用陷揪,但是由于sklearn中沒有集成Xgboost惋鸥,所以才需要單獨(dú)下載安裝杂穷。
2 Xgboost的優(yōu)點(diǎn)
??Xgboost算法可以給預(yù)測(cè)模型帶來能力的提升。當(dāng)我們對(duì)其表現(xiàn)有更多了解的時(shí)候卦绣,我們會(huì)發(fā)現(xiàn)他有如下優(yōu)勢(shì):
2.1 正則化
??實(shí)際上耐量,Xgboost是以“正則化提升(regularized boosting)” 技術(shù)而聞名。Xgboost在代價(jià)函數(shù)里加入了正則項(xiàng)滤港,用于控制模型的復(fù)雜度廊蜒。正則項(xiàng)里包含了樹的葉子節(jié)點(diǎn)個(gè)數(shù),每個(gè)葉子節(jié)點(diǎn)上輸出的score的L2模的平方和溅漾。從Bias-variance tradeoff角度來講劲藐,正則項(xiàng)降低了模型的variance,使學(xué)習(xí)出來的模型更加簡單樟凄,防止過擬合,這也是Xgboost優(yōu)于傳統(tǒng)GBDT的一個(gè)特征
2.2 并行處理
??Xgboost工具支持并行兄渺。眾所周知缝龄,Boosting算法是順序處理的,也是說Boosting不是一種串行的結(jié)構(gòu)嗎挂谍?怎么并行的叔壤?注意Xgboost的并行不是tree粒度的并行。Xgboost也是一次迭代完才能進(jìn)行下一次迭代的(第t次迭代的代價(jià)函數(shù)里包含)口叙。Xgboost的并行式在特征粒度上的炼绘,也就是說每一顆樹的構(gòu)造都依賴于前一顆樹。
??我們知道妄田,決策樹的學(xué)習(xí)最耗時(shí)的一個(gè)步驟就是對(duì)特征的值進(jìn)行排序(因?yàn)橐_定最佳分割點(diǎn))俺亮,Xgboost在訓(xùn)練之前,預(yù)先對(duì)數(shù)據(jù)進(jìn)行了排序疟呐,然后保存為block結(jié)構(gòu)脚曾,后面的迭代中重復(fù)使用這個(gè)結(jié)構(gòu),大大減小計(jì)算量启具。這個(gè)block結(jié)構(gòu)也使得并行成為了可能本讥,在進(jìn)行節(jié)點(diǎn)的分類時(shí),需要計(jì)算每個(gè)特征的增益鲁冯,大大減少計(jì)算量拷沸。這個(gè)block結(jié)構(gòu)也使得并行成為了可能,在進(jìn)行節(jié)點(diǎn)的分裂的時(shí)候薯演,需要計(jì)算每個(gè)特征的增益撞芍,最終選增益最大的那個(gè)特征去做分裂,那么各個(gè)特征的增益計(jì)算就可以開多線程進(jìn)行涣仿。
2.3 靈活性
??Xgboost支持用戶自定義目標(biāo)函數(shù)和評(píng)估函數(shù)勤庐,只要目標(biāo)函數(shù)二階可導(dǎo)就行示惊。它對(duì)模型增加了一個(gè)全新的維度,所以我們的處理不會(huì)受到任何限制愉镰。
2.4 缺失值處理
??對(duì)于特征的值有缺失的樣本米罚,Xgboost可以自動(dòng)學(xué)習(xí)出他的分裂方向。Xgboost內(nèi)置處理缺失值的規(guī)則丈探。用戶需要提供一個(gè)和其他樣本不同的值录择,然后把它作為一個(gè)參數(shù)穿進(jìn)去,以此來作為缺失值的取值碗降。Xgboost在不同節(jié)點(diǎn)遇到缺失值時(shí)采用不同的處理方法隘竭,并且會(huì)學(xué)習(xí)未來遇到缺失值時(shí)的處理方法。
2.5 剪枝
??Xgboost先從頂?shù)降捉⑺锌梢越⒌淖訕渌显ǎ購牡椎巾敺聪驒C(jī)芯剪枝动看,比起GBM,這樣不容易陷入局部最優(yōu)解
2.6 內(nèi)置交叉驗(yàn)證
??Xgboost允許在每一輪Boosting迭代中使用交叉驗(yàn)證爪幻。因此可以方便的獲得最優(yōu)Boosting迭代次數(shù)菱皆,而GBM使用網(wǎng)格搜索,只能檢測(cè)有限個(gè)值挨稿。
3 Xgboost的離線安裝
3.1 點(diǎn)擊此處仇轻,下載對(duì)應(yīng)自己Python版本的網(wǎng)址。
3.2 輸入安裝的程式:
pip install xgboost-0.81-cp37-cp37m-win_amd64.whl
4 Xgboost模型詳解
4.1 Xgboost能加載的各種數(shù)據(jù)格式解析
??Xgboost可以加載多種數(shù)據(jù)格式的訓(xùn)練數(shù)據(jù):
libsvm 格式的文本數(shù)據(jù)奶甘;
Numpy 的二維數(shù)組篷店;
XGBoost 的二進(jìn)制的緩存文件。加載的數(shù)據(jù)存儲(chǔ)在對(duì)象 DMatrix 中
??下面一一列舉:
??記載libsvm格式的數(shù)據(jù)
dtrain1 = xgb.DMatrix('train.svm.txt')
??記載二進(jìn)制的緩存文件
dtrain2 = xgb.DMatrix('train.svm.buffer')
??加載numpy的數(shù)組
data = np.random.rand(5,10) # 5行10列數(shù)據(jù)集
label = np.random.randint(2,size=5) # 二分類目標(biāo)值
dtrain = xgb.DMatrix(data,label=label) # 組成訓(xùn)練集
??將scipy.sparse格式的數(shù)據(jù)轉(zhuǎn)化為Dmatrix格式
csr = scipy.sparse.csr_matrix((dat,(row,col)))
dtrain = xgb.DMatrix( csr )
??將Dmatrix格式的數(shù)據(jù)保存成Xgboost的二進(jìn)制格式臭家,在下次加載時(shí)可以提高加載速度疲陕,使用方法如下:
dtrain = xgb.DMatrix('train.svm.txt')
dtrain.save_binary("train.buffer")
??可以使用如下方式處理DMatrix中的缺失值
dtrain = xgb.DMatrix( data, label=label, missing = -999.0)
??當(dāng)需要給樣本設(shè)置權(quán)重時(shí),可以用如下方式:
w = np.random.rand(5,1)
dtrain = xgb.DMatrix( data, label=label, missing = -999.0, weight=w)
4.2 Xgboost的模型參數(shù)
??Xgboost使用key-value字典的方式存儲(chǔ)參數(shù)
# xgboost模型
params = {
'booster':'gbtree',
'objective':'multi:softmax', # 多分類問題
'num_class':10, # 類別數(shù)侣监,與multi softmax并用
'gamma':0.1, # 用于控制是否后剪枝的參數(shù)鸭轮,越大越保守,一般0.1 0.2的樣子
'max_depth':12, # 構(gòu)建樹的深度橄霉,越大越容易過擬合
'lambda':2, # 控制模型復(fù)雜度的權(quán)重值的L2 正則化項(xiàng)參數(shù)窃爷,參數(shù)越大,模型越不容易過擬合
'subsample':0.7, # 隨機(jī)采樣訓(xùn)練樣本
'colsample_bytree':3,# 這個(gè)參數(shù)默認(rèn)為1姓蜂,是每個(gè)葉子里面h的和至少是多少
# 對(duì)于正負(fù)樣本不均衡時(shí)的0-1分類而言按厘,假設(shè)h在0.01附近,min_child_weight為1
#意味著葉子節(jié)點(diǎn)中最少需要包含100個(gè)樣本钱慢。這個(gè)參數(shù)非常影響結(jié)果逮京,
# 控制葉子節(jié)點(diǎn)中二階導(dǎo)的和的最小值,該參數(shù)值越小束莫,越容易過擬合
'silent':0, # 設(shè)置成1 則沒有運(yùn)行信息輸入懒棉,最好是設(shè)置成0
'eta':0.007, # 如同學(xué)習(xí)率
'seed':1000,
'nthread':7, #CPU線程數(shù)
#'eval_metric':'auc'
}
??在運(yùn)行Xgboost之前草描,必須設(shè)置三種類型成熟:general parameters,booster parameters和task parameters:
??通用參數(shù)(General Parameters):該參數(shù)控制在提升(boosting)過程中使用哪種booster策严,常用的booster有樹模型(tree)和線性模型(linear model)
??Booster參數(shù)(Booster Parameters):這取決于使用哪種booster
??學(xué)習(xí)目標(biāo)參數(shù)(Task Parameters):控制學(xué)習(xí)的場(chǎng)景穗慕,例如在回歸問題中會(huì)使用不同的參數(shù)控制排序
4.2.1 通用參數(shù)
booster [default=gbtree]
有兩種模型可以選擇gbtree和gblinear。gbtree使用基于樹的模型進(jìn)行提升計(jì)算妻导,gblinear使用線性模型進(jìn)行提升計(jì)算逛绵。缺省值為gbtree
[default=0]
取0時(shí)表示打印出運(yùn)行時(shí)信息,取1時(shí)表示以緘默方式運(yùn)行倔韭,不打印運(yùn)行時(shí)的信息术浪。缺省值為0
建議取0,過程中的輸出數(shù)據(jù)有助于理解模型以及調(diào)參寿酌。另外實(shí)際上我設(shè)置其為1也通常無法緘默運(yùn)行胰苏。。
nthread [default to maximum number of threads available if not set]
XGBoost運(yùn)行時(shí)的線程數(shù)醇疼。缺省值是當(dāng)前系統(tǒng)可以獲得的最大線程數(shù)
如果你希望以最大速度運(yùn)行碟联,建議不設(shè)置這個(gè)參數(shù),模型將自動(dòng)獲得最大線程
num_pbuffer [set automatically by xgboost, no need to be set by user]
size of prediction buffer, normally set to number of training instances. The buffers are used to save the prediction results of last boosting step.
num_feature [set automatically by xgboost, no need to be set by user]
boosting過程中用到的特征維數(shù)僵腺,設(shè)置為特征個(gè)數(shù)。XGBoost會(huì)自動(dòng)設(shè)置壶栋,不需要手工設(shè)置
4.2.2 tree booster參數(shù)
eta [default=0.3]
為了防止過擬合辰如,更新過程中用到的收縮步長。在每次提升計(jì)算之后贵试,算法會(huì)直接獲得新特征的權(quán)重琉兜。 eta通過縮減特征的權(quán)重使提升計(jì)算過程更加保守。缺省值為0.3
取值范圍為:[0,1]
通常最后設(shè)置eta為0.01~0.2
gamma [default=0]
minimum loss reduction required to make a further partition on a leaf node of the tree. the larger, the more conservative the algorithm will be.
range: [0,∞]
模型在默認(rèn)情況下毙玻,對(duì)于一個(gè)節(jié)點(diǎn)的劃分只有在其loss function 得到結(jié)果大于0的情況下才進(jìn)行豌蟋,而gamma 給定了所需的最低loss function的值
gamma值使得算法更c(diǎn)onservation,且其值依賴于loss function 桑滩,在模型中應(yīng)該進(jìn)行調(diào)參梧疲。
max_depth [default=6]
樹的最大深度。缺省值為6
取值范圍為:[1,∞]
指樹的最大深度
樹的深度越大运准,則對(duì)數(shù)據(jù)的擬合程度越高(過擬合程度也越高)幌氮。即該參數(shù)也是控制過擬合
建議通過交叉驗(yàn)證(xgb.cv ) 進(jìn)行調(diào)參
通常取值:3-10
min_child_weight [default=1]
孩子節(jié)點(diǎn)中最小的樣本權(quán)重和。如果一個(gè)葉子節(jié)點(diǎn)的樣本權(quán)重和小于min_child_weight則拆分過程結(jié)束胁澳。在現(xiàn)行回歸模型中该互,這個(gè)參數(shù)是指建立每個(gè)模型所需要的最小樣本數(shù)。該成熟越大算法越conservative韭畸。即調(diào)大這個(gè)參數(shù)能夠控制過擬合宇智。
取值范圍為: [0,∞]
max_delta_step [default=0]
Maximum delta step we allow each tree’s weight estimation to be. If the value is set to 0, it means there is no constraint. If it is set to a positive value, it can help making the update step more conservative. Usually this parameter is not needed, but it might help in logistic regression when class is extremely imbalanced. Set it to value of 1-10 might help control the update
取值范圍為:[0,∞]
如果取值為0蔓搞,那么意味著無限制。如果取為正數(shù)随橘,則其使得xgboost更新過程更加保守喂分。
通常不需要設(shè)置這個(gè)值,但在使用logistics 回歸時(shí)太防,若類別極度不平衡妻顶,則調(diào)整該參數(shù)可能有效果
subsample [default=1]
用于訓(xùn)練模型的子樣本占整個(gè)樣本集合的比例。如果設(shè)置為0.5則意味著XGBoost將隨機(jī)的從整個(gè)樣本集合中抽取出50%的子樣本建立樹模型蜒车,這能夠防止過擬合讳嘱。
取值范圍為:(0,1]
colsample_bytree [default=1]
在建立樹時(shí)對(duì)特征隨機(jī)采樣的比例。缺省值為1
取值范圍:(0,1]
colsample_bylevel[default=1]
決定每次節(jié)點(diǎn)劃分時(shí)子樣例的比例
通常不使用酿愧,因?yàn)閟ubsample和colsample_bytree已經(jīng)可以起到相同的作用了
scale_pos_weight[default=0]
A value greater than 0 can be used in case of high class imbalance as it helps in faster convergence.
大于0的取值可以處理類別不平衡的情況沥潭。幫助模型更快收斂
4.2.3 Linear Booster參數(shù)
lambda [default=0]
L2 正則的懲罰系數(shù)
用于處理XGBoost的正則化部分。通常不使用嬉挡,但可以用來降低過擬合
alpha [default=0]
L1 正則的懲罰系數(shù)
當(dāng)數(shù)據(jù)維度極高時(shí)可以使用钝鸽,使得算法運(yùn)行更快。
lambda_bias
在偏置上的L2正則庞钢。缺省值為0(在L1上沒有偏置項(xiàng)的正則拔恰,因?yàn)長1時(shí)偏置不重要)
4.2.4 學(xué)習(xí)目標(biāo)參數(shù)
這個(gè)參數(shù)是來控制理想的優(yōu)化目標(biāo)和每一步結(jié)果的度量方法。
* objective [ default=reg:linear ]
* 定義學(xué)習(xí)任務(wù)及相應(yīng)的學(xué)習(xí)目標(biāo)基括,可選的目標(biāo)函數(shù)如下:
* “reg:linear” –線性回歸颜懊。
* “reg:logistic” –邏輯回歸。
* “binary:logistic” –二分類的邏輯回歸問題风皿,輸出為概率河爹。
* “binary:logitraw” –二分類的邏輯回歸問題,輸出的結(jié)果為wTx桐款。
* “count:poisson” –計(jì)數(shù)問題的poisson回歸咸这,輸出結(jié)果為poisson分布。
* 在poisson回歸中魔眨,max_delta_step的缺省值為0.7媳维。(used to safeguard optimization)
* “multi:softmax” –讓XGBoost采用softmax目標(biāo)函數(shù)處理多分類問題,同時(shí)需要設(shè)置參數(shù)num_class(類別個(gè)數(shù))
* “multi:softprob” –和softmax一樣遏暴,但是輸出的是ndata * nclass的向量侨艾,可以將該向量reshape成ndata行nclass列的矩陣。每行數(shù)據(jù)表示樣本所屬于每個(gè)類別的概率拓挥。
* “rank:pairwise” –set XGBoost to do ranking task by minimizing the pairwise loss
* base_score [ default=0.5 ]
* the initial prediction score of all instances, global bias
* eval_metric [ default according to objective ]
* 校驗(yàn)數(shù)據(jù)所需要的評(píng)價(jià)指標(biāo)唠梨,不同的目標(biāo)函數(shù)將會(huì)有缺省的評(píng)價(jià)指標(biāo)(rmse for regression, and error for classification, mean average precision for ranking)
* 用戶可以添加多種評(píng)價(jià)指標(biāo),對(duì)于Python用戶要以list傳遞參數(shù)對(duì)給程序侥啤,而不是map參數(shù)list參數(shù)不會(huì)覆蓋’eval_metric’
* The choices are listed below:
* “rmse”: [root mean square error](http://en.wikipedia.org/wiki/Root_mean_square_error)
* “l(fā)ogloss”: negative [log-likelihood](http://en.wikipedia.org/wiki/Log-likelihood)
* “error”: Binary classification error rate. It is calculated as #(wrong cases)/#(all cases). For the predictions, the evaluation will regard the instances with prediction value larger than 0.5 as positive instances, and the others as negative instances.
* “merror”: Multiclass classification error rate. It is calculated as #(wrong cases)/#(all cases).
* “mlogloss”: Multiclass logloss
* “[auc](https://www.baidu.com/s?wd=auc&tn=24004469_oem_dg&rsv_dl=gh_pl_sl_csd)”: [Area under the curve](http://en.wikipedia.org/wiki/Receiver_operating_characteristic#Area_under_curve) for ranking evaluation.
* “ndcg”:[Normalized Discounted Cumulative Gain](http://en.wikipedia.org/wiki/NDCG)
* “map”:[Mean average precision](http://en.wikipedia.org/wiki/Mean_average_precision#Mean_average_precision)
* “ndcg@n”,”map@n”: n can be assigned as an integer to cut off the top positions in the lists for evaluation.
* “ndcg-“,”map-“,”ndcg@n-“,”map@n-“: In XGBoost, NDCG and MAP will evaluate the score of a list without any positive samples as 1\. By adding “-” in the evaluation metric XGBoost will evaluate these score as 0 to be consistent under some conditions.
training repeatively
* seed [ default=0 ]
* 隨機(jī)數(shù)的種子当叭。`缺省值為0`
* 可以用于產(chǎn)生可重復(fù)的結(jié)果(每次取一樣的seed即可得到相同的隨機(jī)劃分)
4.3 Xgboost基本方法和默認(rèn)參數(shù)
xgboost.train(params,dtrain,num_boost_round=10,evals(),obj=None,
feval=None,maximize=False,early_stopping_rounds=None,evals_result=None,
verbose_eval=True,learning_rates=None,xgb_model=None)
parms:這是一個(gè)字典茬故,里面包含著訓(xùn)練中的參數(shù)關(guān)鍵字和對(duì)應(yīng)的值,形式是parms = {'booster':'gbtree','eta':0.1}
dtrain:訓(xùn)練的數(shù)據(jù)
num_boost_round:這是指提升迭代的個(gè)數(shù)
evals:這是一個(gè)列表蚁鳖,用于對(duì)訓(xùn)練過程中進(jìn)行評(píng)估列表中的元素磺芭。形式是evals = [(dtrain,'train'),(dval,'val')] 或者是 evals =[(dtrain,'train')] 崖瞭,對(duì)于第一種情況迅诬,它使得我們可以在訓(xùn)練過程中觀察驗(yàn)證集的效果兜叨。
obj :自定義目的函數(shù)
feval:自定義評(píng)估函數(shù)
maximize:是否對(duì)評(píng)估函數(shù)進(jìn)行最大化
early_stopping_rounds:早起停止次數(shù)理逊,假設(shè)為100,驗(yàn)證集的誤差迭代到一定程度在100次內(nèi)不能再繼續(xù)降低跑筝,就停止迭代章蚣。這要求evals里至少有一個(gè)元素兜辞,如果有多個(gè)己英,按照最后一個(gè)去執(zhí)行间螟。返回的是最后的迭代次數(shù)(不是最好的)。如果early_stopping_rounds存在损肛,則模型會(huì)生成三個(gè)屬性厢破,bst.best_score ,bst.best_iteration和bst.best_ntree_limit
evals_result:字典,存儲(chǔ)在watchlist中的元素的評(píng)估結(jié)果
verbose_eval(可以輸入布爾型或者數(shù)值型):也要求evals里至少有一個(gè)元素治拿,如果為True摩泪,則對(duì)evals中元素的評(píng)估結(jié)果會(huì)輸出在結(jié)果中;如果輸入數(shù)字劫谅,假設(shè)為5加勤,則每隔5個(gè)迭代輸出一次。
learning_rates:每一次提升的學(xué)習(xí)率的列表
xgb_model:在訓(xùn)練之前用于加載的xgb_model
4.4 訓(xùn)練模型
??有了參數(shù)列表和數(shù)據(jù)就可以訓(xùn)練模型了
num_round = 10
bst = xgb.train( plst, dtrain, num_round, evallist )
4.5 模型預(yù)測(cè)
# X_test類型可以是二維List同波,也可以是numpy的數(shù)組
dtest = DMatrix(X_test)
ans = model.predict(dtest)
??完整代碼如下:
xgb_model.get_booster().save_model('xgb.model')
tar = xgb.Booster(model_file='xgb.model')
x_test = xgb.DMatrix(x_test)
pre=tar.predict(x_test)
act=y_test
print(mean_squared_error(act, pre))
4.6 保存模型
??在訓(xùn)練完成之后可以將模型保存下來,也可以查看模型內(nèi)部的結(jié)構(gòu)
bst.save_model('test.model')
??導(dǎo)出模型和特征映射(Map)
??你可以導(dǎo)出模型到txt文件并瀏覽模型的含義:
# 導(dǎo)出模型到文件
bst.dump_model('dump.raw.txt')
# 導(dǎo)出模型和特征映射
bst.dump_model('dump.raw.txt','featmap.txt')
4.7 加載模型
??通過如下方式可以加載模型
bst = xgb.Booster({'nthread':4}) # init model
bst.load_model("model.bin") # load data
5 Xgboost實(shí)戰(zhàn)
??Xgboost有兩大類接口:Xgboost原生接口 和sklearn接口叠国,并且Xgboost能夠?qū)崿F(xiàn)分類回歸兩種任務(wù)未檩。下面對(duì)這四種情況做以解析。
5.1 基于Xgboost原生接口的分類
from sklearn.datasets import load_iris
import xgboost as xgb
from xgboost import plot_importance
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score # 準(zhǔn)確率
# 記載樣本數(shù)據(jù)集
iris = load_iris()
X,y = iris.data,iris.target
# 數(shù)據(jù)集分割
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state=123457)
# 算法參數(shù)
params = {
'booster':'gbtree',
'objective':'multi:softmax',
'num_class':3,
'gamma':0.1,
'max_depth':6,
'lambda':2,
'subsample':0.7,
'colsample_bytree':0.7,
'min_child_weight':3,
'slient':1,
'eta':0.1,
'seed':1000,
'nthread':4,
}
plst = params.items()
# 生成數(shù)據(jù)集格式
dtrain = xgb.DMatrix(X_train,y_train)
num_rounds = 500
# xgboost模型訓(xùn)練
model = xgb.train(plst,dtrain,num_rounds)
# 對(duì)測(cè)試集進(jìn)行預(yù)測(cè)
dtest = xgb.DMatrix(X_test)
y_pred = model.predict(dtest)
# 計(jì)算準(zhǔn)確率
accuracy = accuracy_score(y_test,y_pred)
print('accuarcy:%.2f%%'%(accuracy*100))
# 顯示重要特征
plot_importance(model)
plt.show()
??輸出預(yù)測(cè)正確率以及特征重要性:
accuarcy:93.33%
5.2 基于Xgboost原生接口的回歸
import xgboost as xgb
from xgboost import plot_importance
from matplotlib import pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_boston
from sklearn.metrics import mean_squared_error
# 加載數(shù)據(jù)集,此數(shù)據(jù)集時(shí)做回歸的
boston = load_boston()
X,y = boston.data,boston.target
# Xgboost訓(xùn)練過程
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state=0)
# 算法參數(shù)
params = {
'booster':'gbtree',
'objective':'reg:gamma',
'gamma':0.1,
'max_depth':5,
'lambda':3,
'subsample':0.7,
'colsample_bytree':0.7,
'min_child_weight':3,
'slient':1,
'eta':0.1,
'seed':1000,
'nthread':4,
}
dtrain = xgb.DMatrix(X_train,y_train)
num_rounds = 300
plst = params.items()
model = xgb.train(plst,dtrain,num_rounds)
# 對(duì)測(cè)試集進(jìn)行預(yù)測(cè)
dtest = xgb.DMatrix(X_test)
ans = model.predict(dtest)
# 顯示重要特征
plot_importance(model)
plt.show()
??重要特征(值越大粟焊,說明該特征越重要)顯示結(jié)果:
5.3 Xgboost使用sklearn接口的分類(推薦)
from xgboost.sklearn import XGBClassifier
clf = XGBClassifier(
silent=0, # 設(shè)置成1則沒有運(yùn)行信息輸出冤狡,最好是設(shè)置為0,是否在運(yùn)行升級(jí)時(shí)打印消息
# nthread = 4 # CPU 線程數(shù) 默認(rèn)最大
learning_rate=0.3 , # 如同學(xué)習(xí)率
min_child_weight = 1,
# 這個(gè)參數(shù)默認(rèn)為1项棠,是每個(gè)葉子里面h的和至少是多少悲雳,對(duì)正負(fù)樣本不均衡時(shí)的0-1分類而言
# 假設(shè)h在0.01附近,min_child_weight為1 意味著葉子節(jié)點(diǎn)中最少需要包含100個(gè)樣本
# 這個(gè)參數(shù)非常影響結(jié)果香追,控制葉子節(jié)點(diǎn)中二階導(dǎo)的和的最小值合瓢,該參數(shù)值越小,越容易過擬合
max_depth=6, # 構(gòu)建樹的深度透典,越大越容易過擬合
gamma = 0,# 樹的葉子節(jié)點(diǎn)上做進(jìn)一步分區(qū)所需的最小損失減少晴楔,越大越保守顿苇,一般0.1 0.2這樣子
subsample=1, # 隨機(jī)采樣訓(xùn)練樣本,訓(xùn)練實(shí)例的子采樣比
max_delta_step=0, # 最大增量步長税弃,我們?cè)试S每個(gè)樹的權(quán)重估計(jì)
colsample_bytree=1, # 生成樹時(shí)進(jìn)行的列采樣
reg_lambda=1, #控制模型復(fù)雜度的權(quán)重值的L2正則化項(xiàng)參數(shù)纪岁,參數(shù)越大,模型越不容易過擬合
# reg_alpha=0, # L1正則項(xiàng)參數(shù)
# scale_pos_weight =1 # 如果取值大于0的話则果,在類別樣本不平衡的情況下有助于快速收斂幔翰,平衡正負(fù)權(quán)重
# objective = 'multi:softmax', # 多分類問題,指定學(xué)習(xí)任務(wù)和響應(yīng)的學(xué)習(xí)目標(biāo)
# num_class = 10, # 類別數(shù)西壮,多分類與multisoftmax并用
n_estimators=100, # 樹的個(gè)數(shù)
seed = 1000, # 隨機(jī)種子
# eval_metric ='auc'
)
基于Sckit-learn接口的分類
from sklearn.datasets import load_iris
import xgboost as xgb
from xgboost import plot_importance
from matplotlib import pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
# 加載樣本數(shù)據(jù)集
iris = load_iris()
X,y = iris.data,iris.target
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state=12343)
# 訓(xùn)練模型
model = xgb.XGBClassifier(max_depth=5,learning_rate=0.1,n_estimators=160,silent=True,objective='multi:softmax')
model.fit(X_train,y_train)
# 對(duì)測(cè)試集進(jìn)行預(yù)測(cè)
y_pred = model.predict(X_test)
#計(jì)算準(zhǔn)確率
accuracy = accuracy_score(y_test,y_pred)
print('accuracy:%2.f%%'%(accuracy*100))
# 顯示重要特征
plot_importance(model)
plt.show()
??輸出結(jié)果:
accuracy:93%
5.4 基于Scikit-learn接口的回歸
import xgboost as xgb
from xgboost import plot_importance
from matplotlib import pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_boston
# 導(dǎo)入數(shù)據(jù)集
boston = load_boston()
X ,y = boston.data,boston.target
# Xgboost訓(xùn)練過程
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state=0)
model = xgb.XGBRegressor(max_depth=5,learning_rate=0.1,n_estimators=160,silent=True,objective='reg:gamma')
model.fit(X_train,y_train)
# 對(duì)測(cè)試集進(jìn)行預(yù)測(cè)
ans = model.predict(X_test)
# 顯示重要特征
plot_importance(model)
plt.show()
5.5 整理代碼1(原生XGB)
from sklearn.model_selection import train_test_split
from sklearn import metrics
from sklearn.datasets import make_hastie_10_2
import xgboost as xgb
#記錄程序運(yùn)行時(shí)間
import time
start_time = time.time()
X, y = make_hastie_10_2(random_state=0)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, random_state=0)##test_size測(cè)試集合所占比例
#xgb矩陣賦值
xgb_train = xgb.DMatrix(X_train, label=y_train)
xgb_test = xgb.DMatrix(X_test,label=y_test)
##參數(shù)
params={
'booster':'gbtree',
'silent':1 ,#設(shè)置成1則沒有運(yùn)行信息輸出遗增,最好是設(shè)置為0.
#'nthread':7,# cpu 線程數(shù) 默認(rèn)最大
'eta': 0.007, # 如同學(xué)習(xí)率
'min_child_weight':3,
# 這個(gè)參數(shù)默認(rèn)是 1,是每個(gè)葉子里面 h 的和至少是多少茸时,對(duì)正負(fù)樣本不均衡時(shí)的 0-1 分類而言
#贡定,假設(shè) h 在 0.01 附近,min_child_weight 為 1 意味著葉子節(jié)點(diǎn)中最少需要包含 100 個(gè)樣本可都。
#這個(gè)參數(shù)非常影響結(jié)果缓待,控制葉子節(jié)點(diǎn)中二階導(dǎo)的和的最小值,該參數(shù)值越小渠牲,越容易 overfitting旋炒。
'max_depth':6, # 構(gòu)建樹的深度,越大越容易過擬合
'gamma':0.1, # 樹的葉子節(jié)點(diǎn)上作進(jìn)一步分區(qū)所需的最小損失減少,越大越保守签杈,一般0.1瘫镇、0.2這樣子。
'subsample':0.7, # 隨機(jī)采樣訓(xùn)練樣本
'colsample_bytree':0.7, # 生成樹時(shí)進(jìn)行的列采樣
'lambda':2, # 控制模型復(fù)雜度的權(quán)重值的L2正則化項(xiàng)參數(shù)答姥,參數(shù)越大铣除,模型越不容易過擬合。
#'alpha':0, # L1 正則項(xiàng)參數(shù)
#'scale_pos_weight':1, #如果取值大于0的話鹦付,在類別樣本不平衡的情況下有助于快速收斂尚粘。
#'objective': 'multi:softmax', #多分類的問題
#'num_class':10, # 類別數(shù),多分類與 multisoftmax 并用
'seed':1000, #隨機(jī)種子
#'eval_metric': 'auc'
}
plst = list(params.items())
num_rounds = 100 # 迭代次數(shù)
watchlist = [(xgb_train, 'train'),(xgb_test, 'val')]
#訓(xùn)練模型并保存
# early_stopping_rounds 當(dāng)設(shè)置的迭代次數(shù)較大時(shí)敲长,early_stopping_rounds 可在一定的迭代次數(shù)內(nèi)準(zhǔn)確率沒有提升就停止訓(xùn)練
model = xgb.train(plst, xgb_train, num_rounds, watchlist,early_stopping_rounds=100,pred_margin=1)
#model.save_model('./model/xgb.model') # 用于存儲(chǔ)訓(xùn)練出的模型
print "best best_ntree_limit",model.best_ntree_limit
y_pred = model.predict(xgb_test,ntree_limit=model.best_ntree_limit)
print ('error=%f' % ( sum(1 for i in range(len(y_pred)) if int(y_pred[i]>0.5)!=y_test[i]) /float(len(y_pred))))
#輸出運(yùn)行時(shí)長
cost_time = time.time()-start_time
print "xgboost success!",'\n',"cost time:",cost_time,"(s)......"
5.6 整理代碼2(XGB使用sklearn)
from sklearn.model_selection import train_test_split
from sklearn import metrics
from sklearn.datasets import make_hastie_10_2
from xgboost.sklearn import XGBClassifier
X, y = make_hastie_10_2(random_state=0)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, random_state=0)##test_size測(cè)試集合所占比例
clf = XGBClassifier(
silent=0 ,#設(shè)置成1則沒有運(yùn)行信息輸出郎嫁,最好是設(shè)置為0.是否在運(yùn)行升級(jí)時(shí)打印消息。
#nthread=4,# cpu 線程數(shù) 默認(rèn)最大
learning_rate= 0.3, # 如同學(xué)習(xí)率
min_child_weight=1,
# 這個(gè)參數(shù)默認(rèn)是 1祈噪,是每個(gè)葉子里面 h 的和至少是多少泽铛,對(duì)正負(fù)樣本不均衡時(shí)的 0-1 分類而言
#,假設(shè) h 在 0.01 附近辑鲤,min_child_weight 為 1 意味著葉子節(jié)點(diǎn)中最少需要包含 100 個(gè)樣本盔腔。
#這個(gè)參數(shù)非常影響結(jié)果,控制葉子節(jié)點(diǎn)中二階導(dǎo)的和的最小值,該參數(shù)值越小铲觉,越容易 overfitting澈蝙。
max_depth=6, # 構(gòu)建樹的深度,越大越容易過擬合
gamma=0, # 樹的葉子節(jié)點(diǎn)上作進(jìn)一步分區(qū)所需的最小損失減少,越大越保守撵幽,一般0.1灯荧、0.2這樣子。
subsample=1, # 隨機(jī)采樣訓(xùn)練樣本 訓(xùn)練實(shí)例的子采樣比
max_delta_step=0,#最大增量步長盐杂,我們?cè)试S每個(gè)樹的權(quán)重估計(jì)逗载。
colsample_bytree=1, # 生成樹時(shí)進(jìn)行的列采樣
reg_lambda=1, # 控制模型復(fù)雜度的權(quán)重值的L2正則化項(xiàng)參數(shù),參數(shù)越大链烈,模型越不容易過擬合厉斟。
#reg_alpha=0, # L1 正則項(xiàng)參數(shù)
#scale_pos_weight=1, #如果取值大于0的話,在類別樣本不平衡的情況下有助于快速收斂强衡。平衡正負(fù)權(quán)重
#objective= 'multi:softmax', #多分類的問題 指定學(xué)習(xí)任務(wù)和相應(yīng)的學(xué)習(xí)目標(biāo)
#num_class=10, # 類別數(shù)擦秽,多分類與 multisoftmax 并用
n_estimators=100, #樹的個(gè)數(shù)
seed=1000 #隨機(jī)種子
#eval_metric= 'auc'
)
clf.fit(X_train,y_train,eval_metric='auc')
#設(shè)置驗(yàn)證集合 verbose=False不打印過程
clf.fit(X_train, y_train,eval_set=[(X_train, y_train), (X_val, y_val)],eval_metric='auc',verbose=False)
#獲取驗(yàn)證集合結(jié)果
evals_result = clf.evals_result()
y_true, y_pred = y_test, clf.predict(X_test)
print"Accuracy : %.4g" % metrics.accuracy_score(y_true, y_pred)
#回歸
#m_regress = xgb.XGBRegressor(n_estimators=1000,seed=0)
6 Xgboost參數(shù)調(diào)優(yōu)的一般方法
調(diào)參步驟:
??1,選擇較高的學(xué)習(xí)速率(learning rate)漩勤。一般情況下感挥,學(xué)習(xí)速率的值為0.1.但是,對(duì)于不同的問題越败,理想的學(xué)習(xí)速率有時(shí)候會(huì)在0.05~0.3之間波動(dòng)触幼。選擇對(duì)應(yīng)于此學(xué)習(xí)速率的理想決策樹數(shù)量。Xgboost有一個(gè)很有用的函數(shù)“cv”究飞,這個(gè)函數(shù)可以在每一次迭代中使用交叉驗(yàn)證置谦,并返回理想的決策樹數(shù)量。
??2亿傅,對(duì)于給定的學(xué)習(xí)速率和決策樹數(shù)量媒峡,進(jìn)行決策樹特定參數(shù)調(diào)優(yōu)(max_depth , min_child_weight , gamma , subsample,colsample_bytree)在確定一棵樹的過程中,我們可以選擇不同的參數(shù)葵擎。
??3谅阿,Xgboost的正則化參數(shù)的調(diào)優(yōu)。(lambda , alpha)坪蚁。這些參數(shù)可以降低模型的復(fù)雜度,從而提高模型的表現(xiàn)镜沽。
??4敏晤,降低學(xué)習(xí)速率,確定理想?yún)?shù)缅茉。
下面詳細(xì)的進(jìn)行這些操作嘴脾。
第一步:確定學(xué)習(xí)速率和tree_based參數(shù)調(diào)優(yōu)的估計(jì)器數(shù)目
??為了確定Boosting參數(shù),我們要先給其他參數(shù)一個(gè)初始值。咱們先按照如下方法取值:
??1译打,max_depth = 5:這個(gè)參數(shù)的取值最好在3-10之間耗拓,我選的起始值為5,但是你可以選擇其他的值奏司。起始值在4-6之間都是不錯(cuò)的選擇乔询。
??2,min_child_weight = 1 :這里選擇了一個(gè)比較小的值韵洋,因?yàn)檫@是一個(gè)極不平衡的分類問題竿刁。因此,某些葉子節(jié)點(diǎn)下的值會(huì)比較小搪缨。
??3食拜,gamma = 0 :起始值也可以選擇其它比較小的值,在0.1到0.2之間就可以副编,這個(gè)參數(shù)后繼也是要調(diào)整的负甸。
??4,subsample,colsample_bytree = 0.8 這個(gè)是最常見的初始值了痹届。典型值的范圍在0.5-0.9之間呻待。
??5,scale_pos_weight =1 這個(gè)值時(shí)因?yàn)轭悇e十分不平衡短纵。
??注意带污,上面這些參數(shù)的值知識(shí)一個(gè)初始的估計(jì)值,后繼需要調(diào)優(yōu)香到。這里把學(xué)習(xí)速率就設(shè)成默認(rèn)的0.1鱼冀。然后用Xgboost中的cv函數(shù)來確定最佳的決策樹數(shù)量。
from xgboost import XGBClassifier
xgb1 = XGBClassifier(
learning_rate =0.1,
n_estimators=1000,
max_depth=5,
min_child_weight=1,
gamma=0,
subsample=0.8,
colsample_bytree=0.8,
objective= 'binary:logistic',
nthread=4,
scale_pos_weight=1,
seed=27)
第二步:max_depth和min_weight參數(shù)調(diào)優(yōu)
??我們先對(duì)這兩個(gè)參數(shù)調(diào)優(yōu)悠就,是因?yàn)樗麄儗?duì)最終結(jié)果有很大的影響千绪。首先,我們先大范圍地粗略參數(shù)梗脾,然后再小范圍的微調(diào)荸型。
??注意:在這一節(jié)我會(huì)進(jìn)行高負(fù)荷的柵格搜索(grid search),這個(gè)過程大約需要15-30分鐘甚至更久炸茧,具體取決于你系統(tǒng)的性能瑞妇,你也可以根據(jù)自己系統(tǒng)的性能選擇不同的值。
??網(wǎng)格搜索scoring = 'roc_auc' 只支持二分類梭冠,多分類需要修改scoring(默認(rèn)支持多分類)
param_test1 = {
'max_depth':range(3,10,2),
'min_child_weight':range(1,6,2)
}
#param_test2 = {
'max_depth':[4,5,6],
'min_child_weight':[4,5,6]
}
from sklearn import svm, grid_search, datasets
from sklearn import grid_search
gsearch1 = grid_search.GridSearchCV(
estimator = XGBClassifier(
learning_rate =0.1,
n_estimators=140, max_depth=5,
min_child_weight=1,
gamma=0,
subsample=0.8,
colsample_bytree=0.8,
objective= 'binary:logistic',
nthread=4,
scale_pos_weight=1,
seed=27),
param_grid = param_test1,
scoring='roc_auc',
n_jobs=4,
iid=False,
cv=5)
gsearch1.fit(train[predictors],train[target])
gsearch1.grid_scores_, gsearch1.best_params_,gsearch1.best_score_
#網(wǎng)格搜索scoring='roc_auc'只支持二分類辕狰,多分類需要修改scoring(默認(rèn)支持多分類)
第三步:gamma參數(shù)調(diào)優(yōu)
??在已經(jīng)調(diào)整好其他參數(shù)的基礎(chǔ)上,我們可以進(jìn)行g(shù)amma參數(shù)的調(diào)優(yōu)了控漠。Gamma參數(shù)取值范圍很大蔓倍,這里我們?cè)O(shè)置為5悬钳,其實(shí)你也可以取更精確的gamma值。
param_test3 = {
'gamma':[i/10.0 for i in range(0,5)]
}
gsearch3 = GridSearchCV(estimator = XGBClassifier( learning_rate =0.1,
n_estimators=140, max_depth=4,min_child_weight=6, gamma=0,
subsample=0.8, colsample_bytree=0.8,objective= 'binary:logistic',
nthread=4, scale_pos_weight=1,seed=27), 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_
param_test3 = {
'gamma':[i/10.0 for i in range(0,5)]
}
gsearch3 = GridSearchCV(
estimator = XGBClassifier(
learning_rate =0.1,
n_estimators=140,
max_depth=4,
min_child_weight=6,
gamma=0,
subsample=0.8,
colsample_bytree=0.8,
objective= 'binary:logistic',
nthread=4,
scale_pos_weight=1,
seed=27),
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_
第四步:調(diào)整subsample 和 colsample_bytree參數(shù)
??嘗試不同的subsample 和 colsample_bytree 參數(shù)偶翅。我們分兩個(gè)階段來進(jìn)行這個(gè)步驟默勾。這兩個(gè)步驟都取0.6,0.7,0.8,0.9作為起始值。
#取0.6,0.7,0.8,0.9作為起始值
param_test4 = {
'subsample':[i/10.0 for i in range(6,10)],
'colsample_bytree':[i/10.0 for i in range(6,10)]
}
gsearch4 = GridSearchCV(
estimator = XGBClassifier(
learning_rate =0.1,
n_estimators=177,
max_depth=3,
min_child_weight=4,
gamma=0.1,
subsample=0.8,
colsample_bytree=0.8,
objective= 'binary:logistic',
nthread=4,
scale_pos_weight=1,
seed=27),
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_
第五步:正則化參數(shù)調(diào)優(yōu)
??由于gamma函數(shù)提供了一種更加有效的降低過擬合的方法聚谁,大部分人很少會(huì)用到這個(gè)參數(shù)母剥,但是我們可以嘗試用一下這個(gè)參數(shù)。
param_test6 = {
'reg_alpha':[1e-5, 1e-2, 0.1, 1, 100]
}
gsearch6 = GridSearchCV(
estimator = XGBClassifier(
learning_rate =0.1,
n_estimators=177,
max_depth=4,
min_child_weight=6,
gamma=0.1,
subsample=0.8,
colsample_bytree=0.8,
objective= 'binary:logistic',
nthread=4,
scale_pos_weight=1,
seed=27),
param_grid = param_test6,
scoring='roc_auc',
n_jobs=4,
iid=False,
cv=5)
gsearch6.fit(train[predictors],train[target])
gsearch6.grid_scores_, gsearch6.best_params_, gsearch6.best_score_
第六步 降低學(xué)習(xí)速率
??最后垦巴,我們使用較低的學(xué)習(xí)速率媳搪,以及使用更多的決策樹,我們可以用Xgboost中CV函數(shù)來進(jìn)行這一步工作骤宣。
xgb4 = XGBClassifier(
learning_rate =0.01,
n_estimators=5000,
max_depth=4,
min_child_weight=6,
gamma=0,
subsample=0.8,
colsample_bytree=0.8,
reg_alpha=0.005,
objective= 'binary:logistic',
nthread=4,
scale_pos_weight=1,
seed=27)
modelfit(xgb4, train, predictors)
??總結(jié)一下秦爆,要想模型的表現(xiàn)有大幅的提升,調(diào)整每個(gè)參數(shù)帶來的影響也必須清楚憔披,僅僅靠著參數(shù)的調(diào)整和模型的小幅優(yōu)化等限,想要讓模型的表現(xiàn)有個(gè)大幅度提升是不可能的。要想模型的表現(xiàn)有質(zhì)的飛躍芬膝,需要依靠其他的手段望门。諸如,特征工程(feature egineering) 锰霜,模型組合(ensemble of model),以及堆疊(stacking)等筹误。
第七步:Python示例
import xgboost as xgb
import pandas as pd
#獲取數(shù)據(jù)
from sklearn import cross_validation
from sklearn.datasets import load_iris
iris = load_iris()
#切分?jǐn)?shù)據(jù)集
X_train, X_test, y_train, y_test = cross_validation.train_test_split(iris.data, iris.target, test_size=0.33, random_state=42)
#設(shè)置參數(shù)
m_class = xgb.XGBClassifier(
learning_rate =0.1,
n_estimators=1000,
max_depth=5,
gamma=0,
subsample=0.8,
colsample_bytree=0.8,
objective= 'binary:logistic',
nthread=4,
seed=27)
#訓(xùn)練
m_class.fit(X_train, y_train)
test_21 = m_class.predict(X_test)
print "Accuracy : %.2f" % metrics.accuracy_score(y_test, test_21)
#預(yù)測(cè)概率
#test_2 = m_class.predict_proba(X_test)
#查看AUC評(píng)價(jià)標(biāo)準(zhǔn)
from sklearn import metrics
print "Accuracy : %.2f" % metrics.accuracy_score(y_test, test_21)
##必須二分類才能計(jì)算
##print "AUC Score (Train): %f" % metrics.roc_auc_score(y_test, test_2)
#查看重要程度
feat_imp = pd.Series(m_class.booster().get_fscore()).sort_values(ascending=False)
feat_imp.plot(kind='bar', title='Feature Importances')
import matplotlib.pyplot as plt
plt.show()
#回歸
#m_regress = xgb.XGBRegressor(n_estimators=1000,seed=0)
#m_regress.fit(X_train, y_train)
#test_1 = m_regress.predict(X_test)
7 XGBoost輸出特征重要性以及篩選特征
7.1 梯度提升算法是如何計(jì)算特征重要性的?
??使用梯度提升算法的好處是在提升樹被創(chuàng)建后癣缅,可以相對(duì)直接地得到每個(gè)屬性的重要性得分厨剪。一般來說,重要性分?jǐn)?shù)友存,衡量了特征在模型中的提升決策樹構(gòu)建中的價(jià)值祷膳。一個(gè)屬性越多的被用來在模型中構(gòu)建決策樹,它的重要性就相對(duì)越高屡立。
??屬性重要性是通過對(duì)數(shù)據(jù)集中的每個(gè)屬性進(jìn)行計(jì)算直晨,并進(jìn)行排序得到。在單個(gè)決策樹中通過每個(gè)屬性分裂點(diǎn)改進(jìn)性能度量的量來計(jì)算屬性重要性膨俐。由節(jié)點(diǎn)負(fù)責(zé)加權(quán)和記錄次數(shù)勇皇,也就是說一個(gè)屬性對(duì)分裂點(diǎn)改進(jìn)性能度量越大(越靠近根節(jié)點(diǎn)),權(quán)值越大焚刺;被越多提升樹所選擇敛摘,屬性越重要。性能度量可以是選擇分裂節(jié)點(diǎn)的Gini純度檩坚,也可以是其他度量函數(shù)着撩。
??最終將一個(gè)屬性在所有提升樹中的結(jié)果進(jìn)行加權(quán)求和后然后平均,得到重要性得分匾委。
7.2 繪制特征重要性
??一個(gè)已訓(xùn)練的Xgboost模型能夠自動(dòng)計(jì)算特征重要性拖叙,這些重要性得分可以通過成員變量feature_importances_得到÷咐郑可以通過如下命令打邮眵ⅰ:
print(model.feature_importances_)
??我們可以直接在條形圖上繪制這些分?jǐn)?shù),以便獲得數(shù)據(jù)集中每個(gè)特征的相對(duì)重要性的直觀顯示挨措,例如:
# plot
pyplot.bar(range(len(model.feature_importances_)), model.feature_importances_)
pyplot.show()
??我們可以通過在the Pima Indians onset of diabetes 數(shù)據(jù)集上訓(xùn)練XGBoost模型來演示挖滤,并從計(jì)算的特征重要性中繪制條形圖。
# plot feature importance manually
from numpy import loadtxt
from xgboost import XGBClassifier
from matplotlib import pyplot
from sklearn.datasets import load_iris
# load data
dataset = load_iris()
# split data into X and y
X = dataset.data
y = dataset.target
# fit model no training data
model = XGBClassifier()
model.fit(X, y)
# feature importance
print(model.feature_importances_)
# plot
pyplot.bar(range(len(model.feature_importances_)), model.feature_importances_)
pyplot.show()
??運(yùn)行這個(gè)實(shí)例浅役,首先輸出特征重要性分?jǐn)?shù):
[0.17941953 0.11345647 0.41556728 0.29155672]
??相對(duì)重要性條形圖:
??這種繪制的缺點(diǎn)在于斩松,只顯示了特征重要性而沒有排序,可以在繪制之前對(duì)特征重要性得分進(jìn)行排序觉既。
??通過內(nèi)建的繪制函數(shù)進(jìn)行特征重要性得分排序后的繪制惧盹,這個(gè)函數(shù)就是plot_importance(),示例如下:
# plot feature importance manually
from numpy import loadtxt
from xgboost import XGBClassifier
from matplotlib import pyplot
from sklearn.datasets import load_iris
from xgboost import plot_importance
# load data
dataset = load_iris()
# split data into X and y
X = dataset.data
y = dataset.target
# fit model no training data
model = XGBClassifier()
model.fit(X, y)
# feature importance
print(model.feature_importances_)
# plot feature importance
plot_importance(model)
pyplot.show()
??示例得到條形圖:
??根據(jù)其在輸入數(shù)組的索引瞪讼,特征被自動(dòng)命名為f0~f3钧椰,在問題描述中手動(dòng)的將這些索引映射到名稱,我們可以看到符欠,f2具有最高的重要性嫡霞,f1具有最低的重要性。
7.3 根據(jù)Xgboost特征重要性得分進(jìn)行特征選擇
??特征重要性得分希柿,可以用于在scikit-learn中進(jìn)行特征選擇诊沪。通過SelectFromModel類實(shí)現(xiàn),該類采用模型并將數(shù)據(jù)集轉(zhuǎn)換為具有選定特征的子集狡汉。這個(gè)類可以采取預(yù)先訓(xùn)練的模型娄徊,例如在整個(gè)數(shù)據(jù)集上訓(xùn)練的模型。然后盾戴,它可以閾值來決定選擇哪些特征寄锐。當(dāng)在SelectFromModel實(shí)例上調(diào)用transform()方法時(shí),該閾值被用于在訓(xùn)練集和測(cè)試集上一致性選擇相同特征尖啡。
??在下面的示例中橄仆,我們首先在訓(xùn)練集上訓(xùn)練xgboost模型,然后在測(cè)試上評(píng)估衅斩。使用從訓(xùn)練數(shù)據(jù)集計(jì)算的特征重要性盆顾,然后,將模型封裝在一個(gè)SelectFromModel實(shí)例中畏梆。我們使用這個(gè)來選擇訓(xùn)練集上的特征您宪,用所選擇的特征子集訓(xùn)練模型奈懒,然后在相同的特征方案下對(duì)測(cè)試集進(jìn)行評(píng)估。
# select features using threshold
selection = SelectFromModel(model, threshold=thresh, prefit=True)
select_X_train = selection.transform(X_train)
# train model
selection_model = XGBClassifier()
selection_model.fit(select_X_train, y_train)
# eval model
select_X_test = selection.transform(X_test)
y_pred = selection_model.predict(select_X_test)
??我們可以通過測(cè)試多個(gè)閾值宪巨,來從特征重要性中選擇特征磷杏。具體而言,每個(gè)輸入變量的特征重要性捏卓,本質(zhì)上允許我們通過重要性來測(cè)試每個(gè)特征子集极祸。
??完整代碼如下:
# plot feature importance manually
import numpy as np
from xgboost import XGBClassifier
from matplotlib import pyplot
from sklearn.datasets import load_iris
from xgboost import plot_importance
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.feature_selection import SelectFromModel
# load data
dataset = load_iris()
# split data into X and y
X = dataset.data
y = dataset.target
# split data into train and test sets
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.33,random_state=7)
# fit model no training data
model = XGBClassifier()
model.fit(X_train, y_train)
# feature importance
print(model.feature_importances_)
# make predictions for test data and evaluate
y_pred = model.predict(X_test)
predictions = [round(value) for value in y_pred]
accuracy = accuracy_score(y_test,predictions)
print("Accuracy:%.2f%%"%(accuracy*100.0))
#fit model using each importance as a threshold
thresholds = np.sort(model.feature_importances_)
for thresh in thresholds:
# select features using threshold
selection = SelectFromModel(model,threshold=thresh,prefit=True )
select_X_train = selection.transform(X_train)
# train model
selection_model = XGBClassifier()
selection_model.fit(select_X_train, y_train)
# eval model
select_X_test = selection.transform(X_test)
y_pred = selection_model.predict(select_X_test)
predictions = [round(value) for value in y_pred]
accuracy = accuracy_score(y_test,predictions)
print("Thresh=%.3f, n=%d, Accuracy: %.2f%%" % (thresh, select_X_train.shape[1], accuracy * 100.0))
??運(yùn)行示例,得到輸出:
[0.20993228 0.09029345 0.54176074 0.15801354]
Accuracy:92.00%
Thresh=0.090, n=4, Accuracy: 92.00%
Thresh=0.158, n=3, Accuracy: 92.00%
Thresh=0.210, n=2, Accuracy: 86.00%
Thresh=0.542, n=1, Accuracy: 90.00%
??我們可以看到怠晴,模型的性能通常隨著所選擇的特征的數(shù)量減少遥金,在這一問題上,可以對(duì)測(cè)試集準(zhǔn)確率和模型復(fù)雜度做一個(gè)權(quán)衡蒜田,例如選擇三個(gè)特征稿械,接受準(zhǔn)確率為92%,這可能是對(duì)這樣一個(gè)小數(shù)據(jù)集的清洗冲粤,但是對(duì)于更大的數(shù)據(jù)集和使用交叉驗(yàn)證作為模型評(píng)估方案可能是更有用的策略溜哮。
7.4 網(wǎng)格搜索
??代碼1
from sklearn.model_selection import GridSearchCV
tuned_parameters= [{'n_estimators':[100,200,500],
'max_depth':[3,5,7], ##range(3,10,2)
'learning_rate':[0.5, 1.0],
'subsample':[0.75,0.8,0.85,0.9]
}]
tuned_parameters= [{'n_estimators':[100,200,500,1000]
}]
clf = GridSearchCV(XGBClassifier(silent=0,nthread=4,learning_rate= 0.5,min_child_weight=1, max_depth=3,gamma=0,subsample=1,colsample_bytree=1,reg_lambda=1,seed=1000), param_grid=tuned_parameters,scoring='roc_auc',n_jobs=4,iid=False,cv=5)
clf.fit(X_train, y_train)
##clf.grid_scores_, clf.best_params_, clf.best_score_
print(clf.best_params_)
y_true, y_pred = y_test, clf.predict(X_test)
print"Accuracy : %.4g" % metrics.accuracy_score(y_true, y_pred)
y_proba=clf.predict_proba(X_test)[:,1]
print "AUC Score (Train): %f" % metrics.roc_auc_score(y_true, y_proba)
??代碼2
from sklearn.model_selection import GridSearchCV
parameters= [{'learning_rate':[0.01,0.1,0.3],'n_estimators':[1000,1200,1500,2000,2500]}]
clf = GridSearchCV(XGBClassifier(
max_depth=3,
min_child_weight=1,
gamma=0.5,
subsample=0.6,
colsample_bytree=0.6,
objective= 'binary:logistic', #邏輯回歸損失函數(shù)
scale_pos_weight=1,
reg_alpha=0,
reg_lambda=1,
seed=27
),
param_grid=parameters,scoring='roc_auc')
clf.fit(X_train, y_train)
print(clf.best_params_)
y_pre= clf.predict(X_test)
y_pro= clf.predict_proba(X_test)[:,1]
print "AUC Score : %f" % metrics.roc_auc_score(y_test, y_pro)
print"Accuracy : %.4g" % metrics.accuracy_score(y_test, y_pre)
??輸出特征重要性:
import pandas as pd
import matplotlib.pylab as plt
feat_imp = pd.Series(clf.booster().get_fscore()).sort_values(ascending=False)
feat_imp.plot(kind='bar', title='Feature Importances')
plt.ylabel('Feature Importance Score')
plt.show()
8 補(bǔ)充:關(guān)于隨機(jī)種子——random_state
??random_state是一個(gè)隨機(jī)種子,是在任意帶有隨機(jī)性的類或者函數(shù)里作為參數(shù)來控制隨機(jī)模式色解。random_state取某一個(gè)值的時(shí)候茂嗓,也就確定了一種規(guī)則。
??random_state可以用于很多函數(shù)科阎,比如訓(xùn)練集測(cè)試集的劃分述吸;構(gòu)建決策樹;構(gòu)建隨機(jī)森林
1锣笨,劃分訓(xùn)練集和測(cè)試集的類train_test_split
??隨機(jī)數(shù)種子控制每次劃分訓(xùn)練集和測(cè)試集的模式蝌矛,其取值不變時(shí)劃分得到的結(jié)果一模一樣,其值改變時(shí)错英,劃分得到的結(jié)果不同入撒。若不設(shè)置此參數(shù),則函數(shù)會(huì)自動(dòng)選擇一種隨機(jī)模式椭岩,得到的結(jié)果也就不同茅逮。
2,構(gòu)建決策樹的函數(shù)
clf = tree.DecisionTreeClassifier(criterion="entropy",random_state=30,splitter="random")
??其取值不變時(shí)判哥,用相同的訓(xùn)練集建樹得到的結(jié)果一模一樣献雅,對(duì)測(cè)試集的預(yù)測(cè)結(jié)果也是一樣的
??其取值改變時(shí),得到的結(jié)果不同塌计;
??若不設(shè)置此參數(shù)(即設(shè)置為None)挺身,則函數(shù)會(huì)自動(dòng)選擇一種隨機(jī)模式,每次得到的結(jié)果也就不同锌仅,可能稍微有所波動(dòng)章钾。
3墙贱,構(gòu)建隨機(jī)森林
clf = RandomForestClassifier(random_state=0)
??其取值不變時(shí),用相同的訓(xùn)練集建樹得到的結(jié)果一模一樣贱傀,對(duì)測(cè)試集的預(yù)測(cè)結(jié)果也是一樣的
??其取值改變時(shí)嫩痰,得到的結(jié)果不同;
??若不設(shè)置此參數(shù)(即設(shè)置為None)窍箍,則函數(shù)會(huì)自動(dòng)選擇一種隨機(jī)模式,每次得到的結(jié)果也就不同丽旅,可能稍微有所波動(dòng)椰棘。
4,總結(jié)
??在需要設(shè)置random_state的地方給其賦值榄笙,當(dāng)多次運(yùn)行此段代碼得到完全一樣的結(jié)果邪狞,別人運(yùn)行代碼也可以復(fù)現(xiàn)你的過程。若不設(shè)置此參數(shù)則會(huì)隨機(jī)選擇一個(gè)種子茅撞,執(zhí)行結(jié)果也會(huì)因此不同帆卓。雖然可以對(duì)random_state進(jìn)行調(diào)參,但是調(diào)參后再訓(xùn)練集上表現(xiàn)好的模型未必在陌生訓(xùn)練集上表現(xiàn)好米丘,所以一般會(huì)隨便選擇一個(gè)random_state的值作為參數(shù)剑令。
??對(duì)于那些本質(zhì)上是隨機(jī)的過程,我們有必要控制隨機(jī)的狀態(tài)拄查,這樣才能重復(fù)的展現(xiàn)相同的結(jié)果吁津。如果對(duì)隨機(jī)狀態(tài)不加控制,那么實(shí)驗(yàn)的結(jié)果就無法固定堕扶,而是隨機(jī)的顯示碍脏。
??其實(shí)random_state 與 random seed作用是相同的,下面我們通過 random seed來學(xué)習(xí)一下 random_state:
??第一段代碼和第二段代碼完全相同稍算,在1~100中取10個(gè)隨機(jī)數(shù)典尾,都沒有設(shè)置 random seed,它每次取的結(jié)果就不太糊探,它的隨機(jī)數(shù)種子與當(dāng)前系統(tǒng)的時(shí)間有關(guān)钾埂。
??第三段代碼和第四段代碼設(shè)置了相同的 random seed(123),他們?nèi)〉碾S機(jī)數(shù)就完全相同科平,你多運(yùn)行幾次也是這樣勃教。
??第五段代碼設(shè)置了 random seed(456),但是與之前設(shè)置的不同匠抗,于是運(yùn)行取隨機(jī)數(shù)的結(jié)果也不同故源。