1. 程式人生 > >XGBoost應用於“時間序列預測問題”實戰與疑問(包含dump model的booster分析)

XGBoost應用於“時間序列預測問題”實戰與疑問(包含dump model的booster分析)

使用原始碼

1. 概述(摘錄與理解)

XGBoost的全稱為eXtreme Gradient Boosting,直接翻譯過來是“極限梯度提升”;另外下面是摘要原文。可以看出,XGBoost構建的是提升樹的系統,是一種整合學習的方法,而非一種獨立的演算法。本文主要預研的是XGBoost在預測任務上的應用,可以理解XGBoost在預測任務上即為很多CART(Classfication and Regression Trees)迴歸樹的整合。
在這裡插入圖片描述
先摘抄下論文裡提到的XGBoost的創新點:
在這裡插入圖片描述
翻譯過來:

  1. 我們設計和構建高度可擴充套件的端到端提升樹系統。
  2. 我們提出了一個理論上合理的加權分位數略圖。 推薦分割點的時候,可以只用部分點近似地表示,不用遍歷所有的點以節省時間。
  3. 我們引入了一種新穎的稀疏感知演算法用於並行樹學習。 令缺失值有預設方向,並行的選擇最佳分裂點。
  4. 我們提出了一個有效的用於核外樹形學習的快取感知塊結構。 用快取加速尋找排序後被打亂的索引的列資料的過程。

2. XGBoost建樹的過程

概念1:迴歸樹與決策樹
事實上,分類與迴歸是一個型號的東西,只不過分類的結果是離散值,迴歸是連續的,本質是一樣的,都是特徵(feature)到結果/標籤(label)之間的對映。說說決策樹和迴歸樹,在上面決策樹的講解中相信決策樹分類已經很好理解了。

迴歸樹是個啥呢?

直接摘抄人家的一句話,分類樹的樣本輸出(即響應值)是類的形式,如判斷蘑菇是有毒還是無毒,週末去看電影還是不去。而回歸樹的樣本輸出是數值的形式,比如給某人發放房屋貸款的數額就是具體的數值,可以是0到120萬元之間的任意值。

那麼,這時候你就沒法用上述的資訊增益、資訊增益率、基尼係數來判定樹的節點分裂了,你就會採用新的方式,預測誤差,常用的有均方誤差、對數誤差等。而且節點不再是類別,是數值(預測值),那麼怎麼確定呢,有的是節點內樣本均值,有的是最優化算出來的比如Xgboost。
細節http://blog.csdn.net/app_12062011/article/details/52136117博主講的不錯

概念2:boosting整合學習,由多個相關聯的決策樹聯合決策,什麼叫相關聯,舉個例子,有一個樣本[資料->標籤]是[(2,4,5)-> 4],第一棵決策樹用這個樣本訓練得預測為3.3,那麼第二棵決策樹訓練時的輸入,這個樣本就變成了[(2,4,5)-> 0.7],也就是說,下一棵決策樹輸入樣本會與前面決策樹的訓練和預測相關。

與之對比的是random foreast(隨機森林)演算法,各個決策樹是獨立的、每個決策樹在樣本堆裡隨機選一批樣本,隨機選一批特徵進行獨立訓練,各個決策樹之間沒有啥毛線關係。

所以首先Xgboost首先是一個boosting的整合學習,這樣應該很通俗了

這個時候大家就能感覺到一個迴歸樹形成的關鍵點:(1)分裂點依據什麼來劃分(如前面說的均方誤差最小,loss);(2)分類後的節點預測值是多少(如前面說,有一種是將葉子節點下各樣本實際值得均值作為葉子節點預測誤差,或者計算所得)

總的來說,通過計算預測誤差來判斷特徵的重要性選擇最佳節點分裂,在前一個迴歸樹的基礎上,再以同樣的方式進行樹的構建,最後形成森林。樹的每個葉節點對應的是一個數也成為權重,最後預測值就是各個符合條件的葉節點的權重相加。

3. XGBoost目標函式以及loss function的構建

(這裡過於麻煩,在應用階段先省略…)

4. XGBoost論文的創新點在構建迴歸樹的解釋

是最優化求出來的,不是啥平均值或規則指定的,這個算是一個思路上的新穎吧;

正則化防止過擬合的技術,上述看到了,直接loss function裡面就有;

支援自定義loss function,哈哈,不用我多說,只要能泰勒展開(能求一階導和二階導)就行,你開心就好;

支援並行化,這個地方有必要說明下,因為這是xgboost的閃光點,直接的效果是訓練速度快,boosting技術中下一棵樹依賴上述樹的訓練和預測,所以樹與樹之間應該是隻能序列!那麼大家想想,哪裡可以並行?!
沒錯,在選擇最佳分裂點,進行列舉的時候並行!(據說恰好這個也是樹形成最耗時的階段)

Attention:同層級節點可並行。具體的對於某個節點,節點內選擇最佳分裂點,候選分裂點計算增益用多執行緒並行。

5. XGBoost程式碼中引數的理論解釋

  • early stop: n 當發現n棵樹預測已經很好了,不需要進一步學習殘差了,即停止建樹。
  • max_depth: 最大數的深度。當樹達到最大深度時則停止建樹。
  • min_child_weight:最小的樣本權重和,樣本權重和就是∑hi,當樣本權重和小於設定閾值時則停止建樹。在這裡,min_child_weight代表的意思是,當一個節點下的樣本數小於給定的閾值時,則停止分裂!
  • 除了以上提到了正則項以外,我們還有shrinkage與列取樣技術來避免過擬合的出現。所謂shrinkage就是在每個迭代中樹中,對葉子結點乘以一個縮減權重eta。該操作的作用就是減少每顆樹的影響力,留更多的空間給後來的樹提升。
  • 另一個技術則是取樣的技術,有兩種,一種是列取樣(colsample_bytreecolsample_bylevel),一種是行取樣(subsample)。其中列取樣的實現一般有兩種方式,一種是按層隨機colsample_bylevel(一般來講這種效果會好一點),另一種是建樹前就隨機選擇特徵colsample_bytree
    按層隨機colsample_bylevel的意思就是,上文提到每次分裂一個結點的時候,我們都要遍歷所有的特徵和分割點,從而確定最優的分割點,那麼如果加入了列取樣,我們會在對同一層內每個結點分裂之前,先隨機選擇一部分特徵,於是我們只需要遍歷這部分的特徵,來確定最優的分割點。
    建樹前就隨機選擇特徵colsample_bytree就表示我們在建樹前就隨機選擇一部分特徵,然後之後所有葉子結點的分裂都只使用這部分特徵。
  • 上式中的gamma即閾值,它是正則項裡葉子節點數T的係數,所以xgboost在優化目標函式的同時相當於做了預剪枝
  • scale_pos_weight是用來調節正負樣本不均衡問題的,用助於樣本不平衡時訓練的收斂。

疑問池

  1. XGBoost中確定特徵重要性的方法?

程式碼中用dump model切分森林可以得到如下形式:
在這裡插入圖片描述
有幾個問題:
1 其中特徵的切分依據是什麼?
2 leaf計算出來的是什麼?
3 為什麼沒顯示全部特徵,顯示的依據是什麼?

個人理解:
2. Xgboost的實質可以說是迴歸樹(分段線性迴歸)或決策樹構成的森林(這裡不確定到底屬於什麼樹,貌似都涉及到了,畢竟Xgboost只是一種提升策略),因此,切分點的依據可以是決策樹中的劃分特徵方法(ID3——資訊增益;C4.5——增益率;CART——Gini index);
3. leaf葉節點生成的是函式(離散的是常函式;連續的是線性函式) ;
4. “因為 Random Forest 由於每個樹都是獨立的,因此每個樹都會進行一次隨機選擇變數,導致兩個相關性很高的變數的共同稀釋重要性。 然而 Xgboost 每一次round,如果某個變數已經確定了和y變數的關係,那麼Xgboost 不會再進行對這個變數的訓練。 因此其他相關性高的變數也不會進行訓練了。” 參考自https://jiaxiangli.netlify.com/2018/04/training-model/#importancesdef 感謝!

  • 如有不對,請指點,不勝感激!

參考資料: