目錄html
更新、更全的《機器學習》的更新網站,更有python、go、數據結構與算法、爬蟲、人工智能教學等着你:http://www.javashuo.com/article/p-vozphyqp-cm.htmlpython
XgBoost算法(eXtreme Gradient Boosting)屬於Boosting系列算法,更多的是基於GBDT算法的一個進階算法。本文假設XgBoost算法使用的弱學習器爲決策樹。算法
假設咱們獲取了XgBoost的模型和它的目標函數,如今咱們的任務就是最小化目標函數\(J(\theta)\)找到最佳的\(\theta\),可是這個參數是什麼呢?XgBoost由一堆CART樹組成,所以這個參數很明顯存在於每顆CART樹中。可是CART樹的參數又是什麼呢?CART樹若是被肯定以後,子節點是能夠丟掉的,剩下的只有每個葉子節點以及每個葉子節點上的分數,這就是CART樹的參數即XgBoost的參數,仍是不清楚繼續往下看。數據結構
經過真實值和預測值以及xboost模型咱們能獲得一個目標函數,該目標函數假設存在一個\(L\)代價函數和一個正則項\(\sum_{i=1}^t\Omega(f_k)\)(相似於線性迴歸的L一、L2正則化,以後會詳細解釋,此處是t棵樹的正則化項加和,如今假設咱們有t棵樹,n個訓練樣本,既得一個目標函數
\[ J(\theta)=\sum_{i=1}^nL(y_i^t,\hat{y}_i^{(t)}))+\sum_{i=1}^t\Omega(f_i) \]
若是咱們假設\(C\)是t-1棵樹的正則化項加和,而且代入XgBoost的模型,得
\[ J(\theta)=\sum_{i=1}^nL(y_i^t,\hat{y}_i^{(t-1)}+f_t(x_i))+\Omega(f_t)+C \]
泰勒展開式公式爲:
\[ f(x+\Delta{x})\approx{f(x)}+f'(x)\Delta{x}+{\frac{1}{2}}f''(x)\Delta{x^2} \]
假設
\[ \begin{align} & f(x)=\hat{y}_i^{(t-1)} \\ & \Delta=f_t(x_i) \\ & gi=\partial_{\hat{y}_i^{(t-1)}}L(y_i^t,\hat{y}_i^{(t-1)}) \\ & hi=\partial_{\hat{y}_i^{(t-1)}}^2L(y_i^t,\hat{y}_i^{(t-1)}) \end{align} \]
在這些假設的基礎上,咱們假設存在一個代價函數\(L\),咱們能夠把\(J(\theta)\)泰勒二階展開:
\[ \begin{align} J(\theta) & = \sum_{i=1}^nL(y_i^t,\hat{y}_i^{(t)}))+\sum_{i=1}^t\Omega(f_i) \\ & = \sum_{i=1}^nL(y_i^t,\hat{y}_i^{(t-1)}+f_t(x_i))+\Omega(f_t)+C \\ & = \sum_{i=1}^n[L(y_i^t,\hat{y}_i^{(t-1)})+g_if_t(x_i)+{\frac{1}{2}}h_if_t^2(x_i)]+\Omega(f_t)+C \end{align} \]
其中\(y_i^t\)和\(\hat{y}_i^{(t-1)}\)已知,即\(L(y_i^t,\hat{y}_i^{(t-1)})\)是一個常數項(由於咱們假設了這個代價函數\(L\)是已知的一個代價函數,能夠是MSE,能夠是MSA,能夠是任何一個已知的代價函數);\(C\)是前t-1棵樹的正則化項加和,也是一個常數,這兩個常數項對目標函數求最小值無心義,所以咱們能夠去掉,既得
\[ J(\theta)=\sum_{i=1}^n[g_if_t(x_i)+{\frac{1}{2}}h_if_t^2(x_i)]+\Omega(f_t) \]
如今若是咱們假設損失函數\(L\)使用的是MSE,那麼上述式子會變成
\[ \begin{align} J(\theta) & = \sum_{i=1}^n(y_i^t-(\hat{y}_i^{(t-1)}+f_t(x_i)))^2+\Omega(f_t)+C \\ & = \sum_{i=1}^n((y_i^t-\hat{y}_i^{(t-1)})-f_t(x_i))^2+\Omega(f_t)+C \\ & =\sum_{i=1}^n[(y_i^t-\hat{y}_i^{(t-1)})^2-2(y_i^t-\hat{y}_i^{(t-1)})f_t(x_i)+f_t(x_i)^2]+\Omega(f_t)+C \end{align} \]
去掉常數項能夠獲得
\[ J(\theta)=\sum_{i=1}^n[-2(y_i^t-\hat{y}_i^{(t-1)})f_t(x_i)+f_t(x_i)^2]+\Omega(f_t) \]
若是你代入驗證很明顯能夠發現咱們使用泰勒展開式獲得的式子是沒有問題的app
其實走到這裏咱們的XgBoost已經算是結束了,是否是忘了咱們在作什麼,哈哈!咱們在作的是經過前t-1棵的預測值加和咱們是否能算出第t棵樹的最優預測值。機器學習
如線性迴歸的正則化項同樣,你可使用L1正則化,你也可使用L2正則化。這裏我就講講我對XgBoost使用的正則化項。函數
正則化前咱們先對CART樹作處理:假設一棵樹有T個葉子節點,這T個葉子節點組成了一個T維向量\(w\),而\(q(x)\)是一個映射,用來將樣本映射成1到T的某個值,即\(q(x)\)表示了CART樹的結構,\(w_q(x)\)表示了這棵樹對樣本x的預測值
\[ f_t(x)=w_{q(x)},w\in{R^T},a:R^d\rightarrow\{1,2,\cdots,T\} \]
由此咱們能夠假設XgBoost的正則化項
\[ \Omega(f_t)=\gamma{T}+{\frac{1}{2}}\lambda\sum_{j=1}^T{w_j^2} \]
其中\(\gamma\)和\(\lambda\)是咱們自定義的一個數(相似線性迴歸的學習率),若是\(\gamma\)越大,表示但願得到結構簡單的樹,由於\(\gamma\)越大對葉子節點多的樹懲罰更大;\(\lambda\)越大也是如此。學習
這個時候咱們有了泰勒二階展開的目標函數,有了自定義的正則化項,咱們能夠把自定義的正則項代入目標函數中
\[ J(\theta)=\sum_{i=1}^n[g_if_t(x_i)+{\frac{1}{2}}h_if_t^2(x_i)]+\gamma{T}+{\frac{1}{2}}\lambda\sum_{j=1}^T{w_j^2} \]
代入\(f_t(x)=w_{q(x)}\),得
\[ J(\theta)=\sum_{i=1}^n[g_iw_{q(x_i)}+{\frac{1}{2}}h_i{w_{q(x_i)}^2}]+\gamma{T}+{\frac{1}{2}}\lambda\sum_{j=1}^T{w_j^2} \]
這個時候咱們須要考慮,若是一個葉子節點上難道只會對應一個樣本嗎?很明顯若是樣本不少,一個葉子可能會對應多個樣本。所以咱們用\(I_j\)表示一個葉子節點上的全部樣本,即\(\sum_{i\in{I_j}}\)對應一個葉子節點上全部樣本的對應值的加和,咱們須要計算的就是T個葉子節點上的樣本預測值的加和,這也是爲何用\(\sum_{j=1}^T\)開頭的緣由
\[ \begin{align} J(\theta) & =\sum_{j=1}^T{[(\sum_{i\in{I_j}}g_i)w_j+{\frac{1}{2}}(\sum_{i\in{I_j}}hi)w_j^2]+\gamma{T}+{\frac{1}{2}}\lambda\sum_{j=1}^T{w_j^2}} \\ & = \sum_{j=1}^T{[(\sum_{i\in{I_j}}g_i)w_j+{\frac{1}{2}}(\sum_{i\in{I_j}}hi+\lambda)w_j^2]+\gamma{T}} \end{align} \]
假設\(G_j=\sum_{i\in{I_j}}g_i,H_j=\sum_{i\in{I_j}}h_i\)
\[ J(\theta)=\sum_{j=1}^T[G_jw_j+{\frac{1}{2}}(H_j+\lambda)w_j^2]+\gamma{T} \]
經過上式咱們能夠對目標函數對\(w\)求偏導找到最優\(w^{*}\)爲
\[ {\frac{\partial{J(f_t)}}{\partial{w_J}}}=G_j+(H_j+\lambda)w_j==0\Rightarrow{w_j^*}=-{\frac{G_j}{H_j+\lambda}} \]
回代最優\(w^{*}\)得
\[ J(\theta)^*=-{\frac{1}{2}}\sum_{j=1}^T{\frac{G_j^2}{H_j+\lambda}}+\gamma{T} \]
由於\(J(\theta)^*\)的推導過程當中只和\(G_j\)和\(H_j\)和有關,而它們又只和樹的結構\(q(x)\)有關,這表示\(J(\theta)^*\)表明了這顆樹的結構有多好,值越小,表明這樣的結構越好。優化
其實聰明的同窗已經發現了咱們的\(\theta\)這個參數徹底能夠當作\(f_t\),它表示的是第t顆樹的結構,也就能夠當作咱們的\(\theta\)呀?不是嗎?嘻嘻,你仔細思考下。固然\(f_t\)也是咱們本身定義的。網站
如今咱們假設咱們有一家五口的數據,見下表
兒子 | 媽媽 | 爸爸 | 奶奶 | 爺爺 |
---|---|---|---|---|
g1,h1 | g2,h2 | g3,h3 | g4,h4 | g5,h5 |
兒子+媽媽
\[ G_L=g_1+g_2 \]
爸爸+奶奶+爺爺
\[ G_R=g_3+g_4+g_5 \]
\[ J(\theta)^*=-{\frac{1}{2}}\sum_{j=1}^T{\frac{G_j^2}{H_j+\lambda}}+\gamma{T} \]
若是咱們不對這5個樣本分開,把數據代入\(J(\theta)\),他們的目標值是
\[ {\frac{1}{2}}{\frac{(G_L+G_R)^2}{H_L+H_R+\lambda}} \]
若是咱們把他們五我的按照年齡排列並從空格列分開,即該決策樹會有兩個葉子,一個葉子會有兒子+媽媽的分數;另外一個葉子會有爸爸+奶奶+爺爺的分數
把數據代入\(J(\theta)\)目標值是
\[ {\frac{1}{2}}[{\frac{G_L^2}{H_L+\lambda}}+{\frac{G_R^2}{H_R+\lambda}}] \]
由此能夠計算Gain值
\[ Gain={\frac{1}{2}}[{\frac{G_L^2}{H_L+\lambda}}+{\frac{G_R^2}{H_R+\lambda}}-{\frac{(G_L+G_R)^2}{H_L+H_R+\lambda}}]+\gamma \]
總結:該Gain值是單節點的目標值減去切分後的全部節點的目標值,Gain值若是是正的,而且Gain值越大,就越值得切分,而後不斷重複上述過程;若是Gain值是負的,代表切分後目標值變大了。而\(\gamma\)在這裏控制目標值的降低幅度。Gain值相似於信息增益,而且相比較傳統的GBDT,XgBoost使用了二階泰勒展開,能夠更快的在訓練集上收斂,雖然XgBoost須要計算每一個樣本的g和h值,可是XgBoost使用了並行/多核運算,這都不是問題。
XgBoost算法是GBDT算法的一個提高,他們二者之間的主要區別在於目標函數形式不一樣。而且XgBoost使用了二階泰勒展開,使得XgBoost算法收斂速度更快。