xgboost學習筆記

1. 介紹

以前看過一點CNN圖像識別,這兩天看一下基於樹的XGBOOST。先了解其原理,加上自己不成熟的直覺理解,還有幾個疑問。最後用一個例子,使用python試用一下,僅作爲學習筆記,不繫統整理下來,就會看了又看,忘了又看。

我覺得直覺理解的好處是更容易記憶,更容易觸類旁通,也容易歸納與推廣。有時候解決問題就是直覺+驗證的過程

陳天奇在Quora上的解答如下:引用: https://www.codercto.com/a/5669.html

不同的機器學習模型適用於不同類型的任務。深度神經網絡通過對時空位置建模,能夠很好地捕獲圖像、語音、文本等高維數據。而基於樹模型的XGBoost則能很好地處理表格數據,同時還擁有一些深度神經網絡所沒有的特性(如:模型的可解釋性、輸入數據的不變性、更易於調參等)。

這兩類模型都很重要,並廣泛用於數據科學競賽和工業界。

  • XGBoost專注於模型的可解釋性,而基於人工神經網絡的深度學習,則更關注模型的準確度。

  • XGBoost更適用於變量數較少的表格數據,而深度學習則更適用於圖像或其他擁有海量變量的數據。

     

2. 原理+直覺描述

通過樣本每次進行樹分類後的值,計算損失函數,產生一個新的樹,讓損失超來越少,最後結果越接近(當然還有正則去懲罰複雜度,防止過捏合)。樹是不斷提升的過程,每增加樹的結果之和,與結果越近。

實戰的流程一般是先將數據預處理,成爲我們模型可處理的數據,包括丟失值處理,數據拆解,類型轉換等等。然後將其導入模型運行,最後根據結果正確率調整參數,反覆調參數達到最優。

2.1 公式推導

圖片引用:https://blog.csdn.net/sxf1061926959/article/details/78303555

 

上圖上:L是損失函數,有兩個參數,一個是樣本的結果,一個是前一次預測值加本次預測值。後面是正則。總體上要求所有樣本的損失和最小。

f(x)算是新樹對一組數據的映射,經過分類得到的一個值,是一個葉子節點的值。f(x)可以認爲是樹的特點,樹的關鍵特點就是是結構與葉子值兩個變量。樹的複雜性,就是特點的函數。

 

上圖下:由於目標是可以逐步接近的一個函數,而且是按每 + 一個樹,進行接近。所以前一個樹得到的值是知道的,要推斷後面的值,從歷史去預測未來,這種遞推可以用泰勒公式。自變量的差值就是增加了這個樹。

前一個的葉子與目標的差距,用來確定這一次的葉子值,但無法用前一次的結構(劃分)與目標的差距,確定這一次的結構。那麼結構這個問題暫緩。

 

上圖上:有了上次預測值,及差距,還有損失函數---L (已經知道了,或者先設置好了),二階導數就有了。

上圖下:目標就是,上次的絕對函數損失值與損失的梯度對新樹特徵變化的影響。就是找到下次怎麼構建樹。樹的特徵要隨着損失的兩階梯度變化,讓目標趨向緩和,接近,收斂...

樹的特徵先拋去結構(劃分),主要就是這個葉子值。本次葉子值與之前葉子值的一階導數+本次葉子值^2與之前二階導數積,共同影響目標的變化趨勢。

 

上圖:q就是第一組數據的導數,h是二階。f(x)值就是拋棄結構後就是這組所在的葉子值。上次的損失是常量了,只看損失的兩階趨勢。

葉子個數,與葉子值兩個構成了懲罰函數,葉子太多,值太離散就不好了。所以這個也要有變小的趨勢要求。

 

上圖:原來是按樣本數彙總,可以按葉子分組後,就變個樣子。這樣把公式的懲罰部分與損失部分可以按葉子進行組合。一個樣本對葉子值的變化趨勢要求,變成落在這個葉子上的樣本對這個葉子值的趨勢要求小彙總。

現在大概總結一下這個函數中的自變量:

葉子的個數,葉子節點的值是,當然樹的的結構也是。之前把f(x)變成w是一種簡化。等適當的時候,再把w迴歸爲對結構的考慮。上面公式中的3個變量中,葉子的個數與劃分都先不考慮(也沒辦法考慮,或者說葉子數有限的,劃分也是有限的,相對於樣本數的量來說,影響會小)。

 

這時候僅僅看看葉子值對目標的偏導影響要趨0,得到下面的最佳葉子值。也就是從之前一個樹的葉子值對樣本目標函數的趨勢,來推斷出本次的葉子值。

其實如果與前一次的結構保持一致的話,就是單一變量,純的葉子值的了。結構是很難講的東西,如果每次結構不同,那每次同一個葉子上的樣本組合也是變化的東西。現在新葉子值隨歷史葉子值的趨勢得到的新值有了,葉子值與目標的關係早有了,所以歷史葉子值趨勢與目標的關係也有了。

現在新葉子值隨歷史葉子值的趨勢得到的新值有了,葉子值與目標的關係早有了,所以歷史葉子值趨勢與目標的關係也有了。

如果只用一階導數,目標對葉子值的偏導數是Gj,無法找到最優葉子值。

綜上,新的樹的影響來源於葉子值與結構兩個變量。葉子值要讓目標函數趨勢變小,好的結構也要讓目標函數變小。

2.2 樹的結構

在生成結構的時候,就要考慮劃分後,樣本的歷史葉子值趨勢對目標函數值的變化是怎麼的。那麼可以試着多種劃分,看看哪個劃分出來的目標函數值最小,當然也可能不劃分比較好。

劃分當然會造成模型複雜,所以有要代價的。

 

 

劃分略

 

3. 總結、感悟與疑問

3.1 總結

XGBoost是在構建一個個樹,值累加,讓目標(主要是損失)變的最小。

已經構建了t-1個樹,新的樹要根據歷史樹趨勢進行優化構建。歷史樹上能拿到的趨勢只是歷史葉子節點值,拿不到結構的歷史趨勢,那就只能以歷史葉子值,去找新葉子值。

目標函數的3個變量中(樹結構,葉子個數與葉子值),葉子值是唯一有趨勢變化的東西,而且與樣本結果值密切相關。結構每次也變化,但無法從歷史推出當前,葉子數忽略。

通過通用公式以及配合樹這種結構的特點,找到葉子與目標的偏導數關係,找出最優的葉子值。葉子值與樹結構是沒有關係的,所以保持葉子值最優的情況下,找到對目標函數值最好的結構,按這個劃分產生結構。

3.2 感悟

總的來說,建模過程中,目標就是結果損失要小(頭),模型複雜度小(尾);

損失方面,可能有多個變量影響,有可以計算損失確定的值變化,也有不可琢磨的變化。

根據採用的結構的特色,把損失與正則中的變量合併起來,如果同一個變量不能把損失與正則進行統一,那多個變量更是無從下手。作者通過同一個葉子的彙總,越是巧妙,越可能有好的成果。

目標=(變量1頭+變量1尾)+(變量2頭+變量2尾)+(變量3頭+變量3尾)--》 目標=(變量1)+(變量2)+(變量3)

變量之間無關,根據具體每個變量特點,變量的變化情況,與結果的關聯,及趨勢值特點是什麼,導數求變量最優值,或者根據結果值反推另外變量的最優。

3.3 疑問

  1. 如果儘量按樣本項目構建一個比較複雜的樹,每次只調整葉子值,會有什麼效果?或者在劃分點增加一個變量是怎麼的?這有點像網絡了。

  2. 如何損失函數只考慮一階,效果是怎麼的?找不出自變量葉子值的最優值。三階呢?估計計算太多了。

  3. 很想知道作者最初是怎麼有靈光一現,搞出xgboost的?

 

4. 例子

找到一個有數據的例子,源碼引用在:https://blog.csdn.net/m_buddy/article/details/79341058

用的原生版,非sklearn接口版。

print (predict_res)//修改加了括號

4.1 兩個庫的安裝

import matplotlib.pyplot as plt
import xgboost as xgb

https://blog.csdn.net/ifreewolf_csdn/article/details/82988179

安裝解決方法:沒有在pycharm中安裝,因爲超時失敗,找到E:\pythonproj36\pythonproj\Scripts下的pip.exe,在cmd下安裝的。

Microsoft Windows [版本 10.0.17134.1130]
(c) 2018 Microsoft Corporation。保留所有權利。
​
C:\Users\ACER>E:\pythonproj36\pythonproj\Scripts\pip.exe install -i https://pypi.tuna.tsinghua.edu.cn/simple matplotlib
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
Collecting matplotlib
  Using cached https://pypi.tuna.tsinghua.edu.cn/packages/44/fb/132de6a4b803d8ce909a89043b7d3f775f64e0a39398fc98c02e3e144b61/matplotlib-3.1.2-cp36-cp36m-win_amd64.whl
。。。。。
Installing collected packages: kiwisolver, cycler, python-dateutil, pyparsing, matplotlib
Successfully installed cycler-0.10.0 kiwisolver-1.1.0 matplotlib-3.1.2 pyparsing-2.4.5 python-dateutil-2.8.1
​
C:\Users\ACER>E:\pythonproj36\pythonproj\Scripts\pip.exe list
Package                Version
​
------
​
。。。
lxml                   4.3.3
Markdown               3.1
matplotlib             3.1.2---------------------------
。。。
Werkzeug               0.15.4
wheel                  0.33.4
xgboost                0.90--------------------
​
C:\Users\ACER>

(1)加時間

pip install -U --timeout 1000 matplotlib

(2)換成清華的鏡像源

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple matplotlib

 

4.2 可視化

#自己在這基礎上加了這麼幾句,輸出三棵樹
plot_tree(bst,num_trees=0)
plt.show()
plot_tree(bst, num_trees=1)
plt.show()
plot_tree(bst, num_trees=2)
plt.show()

要運行,要先下載graphviz,配置環境變量,重啓PyCharm,或者import os

pip也要安裝:pip install pydot 與 pip install graphviz。

4.3 運行結果

前三棵樹:

 

4.4 調參簡介

xgboost 有很多可調參數,具有極大的自定義靈活性。比如說:
(1)objective [ default=reg:linear ] 定義學習任務及相應的學習目標,可選的目標函數如下:
“reg:linear” –線性迴歸。
“reg:logistic” –邏輯迴歸。
“binary:logistic” –二分類的邏輯迴歸問題,輸出爲概率。
“multi:softmax” –處理多分類問題,同時需要設置參數num_class(類別個數)
(2)’eval_metric’ The choices are listed below,評估指標:
“rmse”: root mean square error
“logloss”: negative log-likelihood
(3)max_depth [default=6] 數的最大深度。缺省值爲6 ,取值範圍爲:[1,∞]

 

發佈了38 篇原創文章 · 獲贊 6 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章