利用GBDT構造新的特徵-Python實現

  • 2019 年 10 月 28 日
  • 筆記
  1. 背景 1.1 Gradient Boosting Gradient Boosting是一種Boosting的方法,它主要的思想是,每一次建立模型是在之前建立模型損失函數的梯度下降方向。損失函數是評價模型性能(一般為擬合程度+正則項),認為損失函數越小,性能越好。而讓損失函數持續下降,就能使得模型不斷改性提升性能,其最好的方法就是使損失函數沿著梯度方向下降(講道理梯度方向上下降最快)。 Gradient Boost是一個框架,裡面可以套入很多不同的演算法。 1.2 Gradient Boosting Decision Tree 每一次建立樹模型是在之前建立模型損失函數的梯度下降方向。即利用了損失函數的負梯度在當前模型的值作為回歸問題提升樹演算法的殘差近似值,去擬合一個回歸樹。 具體演算法算理:GBDT原理-Gradient Boosting Decision Tree http://blog.csdn.net/shine19930820/article/details/65633436

1.3 GBDT應用-回歸和分類

GBDT分類:每一顆樹擬合當前整個模型的損失函數的負梯度,構建新的樹加到當前模型中形成新模型,下一棵樹擬合新模型的損失函數的負梯度。下面是其在Python的sklearn包下簡單調用方法。

GBDT回歸:每一顆樹擬合當前整個模型的殘差,構建新的樹加到當前模型中形成新模型,下一棵樹擬合新模型的損失函數的負梯度。

GBDT調參問題:sklearn中GBDT調參

http://chuansong.me/n/296022746725

GBDT運用的正則化技巧,防止模型過於複雜,參考這篇文章GBDT運用的正則化技巧

https://chuan92.com/2016/04/11/regularization-on-gbdt

2. GBDT構建新的特徵思想 特徵決定模型性能上界,例如深度學習方法也是將數據如何更好的表達為特徵。如果能夠將數據表達成為線性可分的數據,那麼使用簡單的線性模型就可以取得很好的效果。GBDT構建新的特徵也是使特徵更好地表達數據。 主要參考Facebook,原文提升效果:

https://www.baidu.com/s?wd=Facebook&tn=24004469_oem_dg&rsv_dl=gh_pl_sl_csd

在預測Facebook廣告點擊中,使用一種將決策樹與邏輯回歸結合在一起的模型,其優於其他方法,超過3%。 主要思想:GBDT每棵樹的路徑直接作為LR輸入特徵使用。 用已有特徵訓練GBDT模型,然後利用GBDT模型學習到的樹來構造新特徵,最後把這些新特徵加入原有特徵一起訓練模型。構造的新特徵向量是取值0/1的,向量的每個元素對應於GBDT模型中樹的葉子結點。當一個樣本點通過某棵樹最終落在這棵樹的一個葉子結點上,那麼在新特徵向量中這個葉子結點對應的元素值為1,而這棵樹的其他葉子結點對應的元素值為0。新特徵向量的長度等於GBDT模型里所有樹包含的葉子結點數之和。

上圖為混合模型結構。輸入特徵通過增強的決策樹進行轉換。每個單獨樹的輸出被視為稀疏線性分類器的分類輸入特徵。增強的決策樹被證明是非常強大的特徵轉換。 例子1:上圖有兩棵樹,左樹有三個葉子節點,右樹有兩個葉子節點,最終的特徵即為五維的向量。對於輸入x,假設他落在左樹第一個節點,編碼[1,0,0],落在右樹第二個節點則編碼[0,1],所以整體的編碼為[1,0,0,0,1],這類編碼作為特徵,輸入到線性分類模型(LR or FM)中進行分類。 論文中GBDT的參數,樹的數量最多500顆(500以上就沒有提升了),每棵樹的節點不多於12。 3. GBDT與LR融合方案 在CTR預估中,如何利用AD ID是一個問題。 直接將AD ID作為特徵建樹不可行,而onehot編碼過於稀疏,為每個AD ID建GBDT樹,相當於發掘出區分每個廣告的特徵。而對於曝光不充分的樣本即長尾部分,無法單獨建樹。 綜合方案為:使用GBDT對非ID和ID分別建一類樹。 非ID類樹: 不以細粒度的ID建樹,此類樹作為base,即這些ID一起構建GBDT。即便曝光少的廣告、廣告主,仍可以通過此類樹得到有區分性的特徵、特徵組合。 ID類樹: 以細粒度 的ID建一類樹(每個ID構建GBDT),用於發現曝光充分的ID對應有區分性的特徵、特徵組合。如何根據GBDT建的兩類樹,對原始特徵進行映射?以如下圖3為例,當一條樣本x進來之後,遍歷兩類樹到葉子節點,得到的特徵作為LR的輸入。當AD曝光不充分不足以訓練樹時,其它樹恰好作為補充。 方案如圖:

其中kaggle競賽一般樹的數目最多為30,通過GBDT轉換得到特徵空間相比於原始ID低了很多。

4. 源碼內容

具體kaggle-2014-criteo實現的GitHub源碼:https://github.com/guestwalk/kaggle-2014-criteo

generate GBDT features: 使用GBDT生成特徵。 使用了30顆深度為7的樹。 一共生成30個特徵。 基於下面的演算法:http://statweb.stanford.edu/~jhf/ftp/trebst.pdf 例子2:下圖假設訓練了3顆深度2的樹模型,對於輸入X,在第1個樹屬於節點4,在第2個樹屬於節點7,第3顆樹屬於節點6,所以生成的特徵為」1:4 2:7 3:6」

FFM詳細資料>>

https://www.csie.ntu.edu.tw/~r01922136/slides/ffm.pdf

5. Python實現 上面的源碼用到了多執行緒實現,Python的sklearn庫中提供了該方法,下面簡單的實踐: 首先要明確使用libFFM還是邏輯回歸,兩者不同之處在於: libFFM適用於例子2的情況,即只用使用每棵樹的index。 邏輯回歸適用於例子1的情況,須將節點使用one-hot編碼,核心程式碼如下:其中關鍵方法為樹模型(GBDT)的apply()方法。

這只是一個簡單的demo,具體參數還需要根據具體業務情景調整。 官方例子介紹:http://scikit-learn.org/stable/auto_examples/ensemble/plot_feature_transformation.html#example-ensemble-plot-feature-transformation-py

總結 對於樣本量大的數據,線性模型具有訓練速度快的特點,但線性模型學習能力限於線性可分數據,所以就需要特徵工程將數據儘可能地從輸入空間轉換到線性可分的特徵空間。GBDT與LR的融合模型,其實使用GBDT來發掘有區分度的特徵以及組合特徵,來替代人工組合特徵。工業種GBDT+LR、GBDT+FM都是應用比較廣泛。 原文:https://blog.csdn.net/shine19930820/article/details/71713680