Xgboost调参小结
? XGBoost全稱是eXtreme Gradient Boosting,由陳天奇所設計,和傳統的梯度提升算法相比,XGBoost進行了許多改進,它能夠比其他使用梯度提升的集成算法更加快速。關于xgboost的使用教程以及推導過程可以參考之前寫的文章。
? 本文主要介紹xgb算法的調參過程,xgb本質上是boosting方法,即通過在數據上逐一構建多個弱評估器,經過多次迭代逐漸累積多個弱評估器的方法。xgb中的每個分類器是cart樹,因此樹模型對變量交叉會有較好的效果,但因此也容易產生過擬合。調參的步驟網上有很多教程,參數搜索的過程可以用網格搜索和貝葉斯優(yōu)化(有空研究)。下面采用波士頓房產數據集,對xgb中調參做簡單的學習介紹。
? 首先,建模并查看各類參數。
? xgb建模可以使用xgboost庫,或者是使用sklearnAPI調用。實際情況中xgboost庫本身訓練模型效果會更優(yōu)秀,且本身調參也方便許多。Xgboost自身有xgboost.cv()方法調參,如果是skleanAPI的話有GridSearchCV()方法進行調參。下面就用xgboost庫建模,用xgboost.cv()的方法進行調參。
? 首先從設定默認參數開始,觀察默認參數下交叉驗證曲線的形狀。
dfull = xgb.DMatrix(X,y)param1 = {'silent':True,'obj':'reg:linear',"subsample":1,"max_depth":6,"eta":0.3,"gamma":0,"lambda":1,"alpha":0,"colsample_bytree":1,"colsample_bylevel":1,"colsample_bynode":1,"nfold":5} num_round = 200cvresult1 = xgb.cv(param1, dfull, num_round)fig,ax = plt.subplots(1,figsize=(15,8)) ax.set_ylim(top=5) ax.grid() ax.plot(range(1,201),cvresult1.iloc[:,0],c="red",label="train,original") ax.plot(range(1,201),cvresult1.iloc[:,2],c="orange",label="test,original") ax.legend(fontsize="xx-large") plt.show()[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-FgBINfyj-1598229157502)(https://imgkr2.cn-bj.ufileos.com/bd1f050b-54dd-4ae4-b16c-34d52612d26e.png?UCloudPublicKey=TOKEN_8d8b72be-579a-4e83-bfd0-5f6ce1546f13&Signature=6NaIiGfVLWbLu%252BiFTwTX0k2ti58%253D&Expires=1598275140)]
? 從曲線上可以看出模型處于過擬合狀態(tài),需要進行剪枝。剪枝的目的是訓練集和測試集的結果盡量接近,即上圖中訓練集的曲線上升,測試集的曲線下降。
下面用三組曲線展示調參結果,一組是原始數據的結果,一組是上一個參數調節(jié)結束的結果,還有一組是現在在調節(jié)參數的結果。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-3kzqOeBb-1598229157506)(https://imgkr2.cn-bj.ufileos.com/e8777aae-82d2-4862-8684-347ce59e2bec.png?UCloudPublicKey=TOKEN_8d8b72be-579a-4e83-bfd0-5f6ce1546f13&Signature=3OIgIAOk26JtFx%252BRX6h0NtRxp6M%253D&Expires=1598275152)]
? 這里用到的是手動調參的方法,需要一定的調參經驗結合損失函數的變化。網格搜索需要足夠的計算機資源,且往往運行速度很慢,建議先用xgboost.cv()來確認參數的范圍,而且調參過程中用np.linespace()還是np.arange()也會影響調參結果。
? 調參順序也會會影響調參結果。所以一般會優(yōu)先調對模型影響較大的參數。一般先n_estimators和eta共同調節(jié),然后gamma和max_depth,再是采樣和抽樣參數,最后是正則化的兩個參數。
調參常用參數介紹
附上之前學習xgboost時的筆記,記錄了各個參數的含義及調參步驟。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Cah5GjLr-1598229157510)(https://imgkr2.cn-bj.ufileos.com/f4bb58db-5161-42c6-9742-bdfda7bcdde7.jpg?UCloudPublicKey=TOKEN_8d8b72be-579a-4e83-bfd0-5f6ce1546f13&Signature=5kLqPU57viLMKa89uQpGVPGzW%252BY%253D&Expires=1598275162)]
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-TtafZLh7-1598229157515)(https://imgkr2.cn-bj.ufileos.com/3d288610-9faf-4dd6-9d8e-29e5ac4d0d8e.jpg?UCloudPublicKey=TOKEN_8d8b72be-579a-4e83-bfd0-5f6ce1546f13&Signature=8ZAzojDOnzwzQNiDIJmDvGaLhdg%253D&Expires=1598275174)]
1.n_estimators
? n_estimators是集成中弱估計器的數量,即樹的個數。使用參數學習曲線觀察n_estimators對模型的影響。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-1rplHV9Z-1598229157518)(https://imgkr2.cn-bj.ufileos.com/7542bb0a-6c12-4496-bf59-7cf988ebd665.png?UCloudPublicKey=TOKEN_8d8b72be-579a-4e83-bfd0-5f6ce1546f13&Signature=58qsGMQxzqyGsTtQAJr7nBhgVzE%253D&Expires=1598275186)]
? 從上圖看出n_estimators在80附近的時候準確率已達到最高,這里無需選擇準確率達到最高的n_estiamtors。
? 在機器學習中,我們用來衡量模型在未知數據上的準確率的指標,叫做泛化誤差。泛化誤差由方差、偏差和噪聲共同決定。其中,偏差是指模型的擬合程度,方差是指模型的穩(wěn)定性,噪音則是隨機因素。在繪制學習曲線時,不僅要考慮偏差的大小,還要考慮方差的大小。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-idEjxluH-1598229157521)(https://imgkr2.cn-bj.ufileos.com/047b4e8c-336b-4f42-a238-ee0eac212ac0.png?UCloudPublicKey=TOKEN_8d8b72be-579a-4e83-bfd0-5f6ce1546f13&Signature=6Sz4B%252Fnlg8xNBZi9beT77BTDA74%253D&Expires=1598275197)]
? 基于這種思路,來改進學習曲線:
axisx = range(50,1050,50) rs = [] var = [] ge = [] for i in axisx:reg = XGBR(n_estimators=i,random_state=420)cvresult = CVS(reg,Xtrain,Ytrain,cv=cv)#記錄1-偏差rs.append(cvresult.mean())#記錄方差var.append(cvresult.var())#計算泛化誤差的可控部分ge.append((1 - cvresult.mean())**2+cvresult.var()) #打印R2最高所對應的參數取值,并打印這個參數下的方差 print(axisx[rs.index(max(rs))],max(rs),var[rs.index(max(rs))]) #打印方差最低時對應的參數取值,并打印這個參數下的R2 print(axisx[var.index(min(var))],rs[var.index(min(var))],min(var)) #打印泛化誤差可控部分的參數取值,并打印這個參數下的R2,方差以及泛化誤差的可控部分 print(axisx[ge.index(min(ge))],rs[ge.index(min(ge))],var[ge.index(min(ge))],min(ge)) plt.figure(figsize=(20,5)) plt.plot(axisx,rs,c="red",label="XGB") plt.legend() plt.show()[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-3ldaRHvn-1598229157523)(https://imgkr2.cn-bj.ufileos.com/549c8c92-03a7-4a03-8e39-654540f55f2a.png?UCloudPublicKey=TOKEN_8d8b72be-579a-4e83-bfd0-5f6ce1546f13&Signature=2W28Nsw6LF052Xkh3SpTUoH4ir4%253D&Expires=1598275207)]
? 由上圖可知,泛化誤差可控制的部分在n_estimators取150的時候最小。將模型的方差、偏差、泛化誤差中可控部分繪制在一張圖上:
axisx = range(100,300,10) rs = [] var = [] ge = [] for i in axisx:reg = XGBR(n_estimators=i,random_state=420)cvresult = CVS(reg,Xtrain,Ytrain,cv=cv)rs.append(cvresult.mean())var.append(cvresult.var())ge.append((1 - cvresult.mean())**2+cvresult.var()) print(axisx[rs.index(max(rs))],max(rs),var[rs.index(max(rs))]) print(axisx[var.index(min(var))],rs[var.index(min(var))],min(var)) print(axisx[ge.index(min(ge))],rs[ge.index(min(ge))],var[ge.index(min(ge))],min(ge)) rs = np.array(rs) var = np.array(var)*0.01 plt.figure(figsize=(20,5)) plt.plot(axisx,rs,c="black",label="XGB") #添加方差線 plt.plot(axisx,rs+var,c="red",linestyle='-.') plt.plot(axisx,rs-var,c="red",linestyle='-.') plt.legend() plt.show()[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-vB4xtsEa-1598229157526)(https://imgkr2.cn-bj.ufileos.com/5515e389-77c5-4ba9-9f49-bbc03abad7b0.png?UCloudPublicKey=TOKEN_8d8b72be-579a-4e83-bfd0-5f6ce1546f13&Signature=THzYeJZ5GzEejTOyTsMKnxpM9rM%253D&Expires=1598275218)]
? 可以看到n_estimators在180時的時候模型效果最優(yōu),n_estimators是xgb中一般調整的第一個參數,300以下為佳。其它單個參數的調節(jié)方法可以以此類推。
2.subsample
? 確認了樹的數目之后,對每一顆樹如果都使用全量數據進行訓練的話,會導致計算非常緩慢。因此需要對訓練數據集進行抽樣。有放回的抽樣每次只能抽取一個樣本,若我們需要總共N個樣本,就需要抽取N次。每次抽取一個樣本的過程是獨立的。實際應用中,每次抽取50%左右的數據就能夠有不錯的效果。
? 在梯度提升樹中,每一次迭代都要建立一棵新的樹,因此每次迭代中,都要有放回抽取一個新的訓練樣本。為了保證每次建新樹后,集成的效果都比之前要好。因此在梯度提升樹中,每構建一個評估器,都讓模型更加集中于數據集中容易被判錯的那些樣本。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-hBP2strh-1598229157528)(https://imgkr2.cn-bj.ufileos.com/8af3f798-35f9-44ce-b3e4-14766909bef7.png?UCloudPublicKey=TOKEN_8d8b72be-579a-4e83-bfd0-5f6ce1546f13&Signature=GLePatHuSpvIIR%252FWp3fqd7WDrM4%253D&Expires=1598275227)]
3.eta
? 迭代決策樹時的步長,又叫學習率。eta越大,迭代的速度越快,算法的極限很快被達到,有可能無法收斂到真正的最佳。 越小,越有可能找到更精確的最佳值,更多的空間被留給了后面建立的樹,但迭代速度會比較緩慢。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-z6RcOk04-1598229157529)(https://imgkr2.cn-bj.ufileos.com/b70bcf19-1905-468f-aa43-fea75a234a6e.png?UCloudPublicKey=TOKEN_8d8b72be-579a-4e83-bfd0-5f6ce1546f13&Signature=93CWh1MFZmDx4iy7wVfO1tSHQr4%253D&Expires=1598275239)]
? eta默認值為0.1,而且更小的步長更利于現在的數據,但由于無
法確定對于其他數據會有怎么樣的效果,所以通常對eta不做調整 ,即便調整,一般只會在[0.01,0.2]之間變動。
4.Gamma
? gamma是用來防止過擬合的重要參數,是梯度提升樹影響最大的參數之一,同時也是停止樹生長的重要參數之一。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-2F0wohGM-1598229157531)(https://imgkr2.cn-bj.ufileos.com/082239b4-e394-41ee-a2bc-c2f5bc02fc9a.jpg?UCloudPublicKey=TOKEN_8d8b72be-579a-4e83-bfd0-5f6ce1546f13&Signature=rEYxWNG0eevGizDsddCNUR7i0Ug%253D&Expires=1598275251)]
? gamma是每增加一片葉子就會被減去的懲罰項,增加的葉子越多,結構分數之差Gain就會懲罰越重,因此gamma又被稱作復雜性控制。只要Gain大于0,即只要目標函數還能夠繼續(xù)減小,樹就可以進行繼續(xù)分枝。所以gamma可以定義為在樹的節(jié)點上進行進一步分支所需要的最小目標函數減少量。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-fifCJnwk-1598229157533)(https://imgkr2.cn-bj.ufileos.com/f8b0fe1b-1ce9-4102-99d0-479d6684ae26.png?UCloudPublicKey=TOKEN_8d8b72be-579a-4e83-bfd0-5f6ce1546f13&Signature=tYWrxENgmQhc3DqsmMFlimATBVQ%253D&Expires=1598275267)]
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-AoWWRdX2-1598229157534)(https://imgkr2.cn-bj.ufileos.com/066b7d06-28dc-4b83-bb41-16a0cbdd7ecb.png?UCloudPublicKey=TOKEN_8d8b72be-579a-4e83-bfd0-5f6ce1546f13&Signature=YG7aoGCZ1mvUBIx8PZFX71DbeuQ%253D&Expires=1598275280)]
? 這里的評價函數用的是RMASE,當gamma越小算法越復雜,相應的RMSE就會越低。在上圖中表現就是gamma為0的曲線(紅色)要低于gamma為20的曲線。在樹增加到10棵之后,評價函數就不再有明顯的下降趨勢了。
? 作為天生過擬合的模型,XGBoost應用的核心之一就是減輕過擬合帶來的影響。作為樹模型,減輕過擬合的方式主要是靠對決策樹剪枝來降低模型的復雜度,以求降低方差。用來防止過擬合的參數,有復雜度控制gamma ,正則化的兩個參數lambda和alpha,控制迭代速度的參數eta以及隨機有放回抽樣的參數subsample。所有的這些參數都可以用來減輕過擬合。除此之外,還有幾個影響重大的,專用于剪枝的參數:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-oGOUX299-1598229157536)(https://imgkr2.cn-bj.ufileos.com/b41e6076-a486-4ec8-9cb2-dee88d289dfa.png?UCloudPublicKey=TOKEN_8d8b72be-579a-4e83-bfd0-5f6ce1546f13&Signature=XWxMf4GCTNad5lFNqAkYFOolfVw%253D&Expires=1598275291)]
1.這些參數中,樹的最大深度是決策樹中的剪枝法寶,算是最常用的剪枝參數,不過在XGBoost中,最大深度的功能與參數gamma相似,因此如果先調節(jié)了gamma,則最大深度可能無法展示出巨大的效果。通常來說,這兩個參數中只使用一個。
2.三個隨機抽樣特征的參數中,前兩個比較常用。在建立樹時對特征進行抽樣其實是決策樹和隨機森林中比較常見的一種方法,但是在XGBoost之前,這種方法并沒有被使用到boosting算法當中過。Boosting算法一直以抽取樣本(橫向抽樣)來調整模型過擬合的程度,而實踐證明其實縱向抽樣(抽取特征)更能夠防止過擬合。
3.參數min_child_weight不太常用,它是一篇葉子上的二階導數 之和,當樣本所對應的二階導數很小時,比如說為
0.01,min_child_weight若設定為1,則說明一片葉子上至少需要100個樣本。本質上來說,這個參數其實是在控制葉子上所需的最小樣本量,因此對于樣本量很大的數據會比較有效。如果樣本量很小則這個參數效用不大。
【作者】:Labryant
【原創(chuàng)公眾號】:風控獵人
【簡介】:某創(chuàng)業(yè)公司策略分析師,積極上進,努力提升。乾坤未定,你我都是黑馬。
【轉載說明】:轉載請說明出處,謝謝合作!~
總結
以上是生活随笔為你收集整理的Xgboost调参小结的全部內容,希望文章能夠幫你解決所遇到的問題。