從CART到經典GBDT到XGBoost——樹模型重溫
正如 從AdaBoost到GBM到LambdaMART——Boosting方法重溫 所提到的,GBM中應用最廣泛的模型是GBDT,即以CART回歸樹為基函數的梯度提升樹模型。XGBoost作為實現Gradient Boosting的主流框架之一,除了在計算性能上作優化之外,在演算法層面也作了一些改變。這裡挑若干值得一提的點稍作對比和總結。
減輕過擬合的手段
機器學習上的優化和一般優化問題最大的區別在於真實數據分佈未知,因此無法對真實的優化目標期望泛化誤差直接進行優化,只能從分佈中抽樣出訓練集,通過優化訓練集上的經驗風險函數來間接優化期望泛化誤差。這就意味著在經驗風險函數上的最優解不一定是期望泛化誤差的最優解,通常的情況是在經驗風險函數上表現良好,但基於測試集來做估計的泛化誤差高,也即所謂的過擬合。從優化的角度來看,可以通過一些約束將經驗風險函數上的最優解「往隔壁挪一挪」,讓它沒那麼完美,但在泛化誤差上表現更好,從而減輕過擬合。
決策樹本身是一個容易高方差的模型,因為它挑選切分特徵和切分點是完全基於訓練數據的分佈來的,也就是多次抽樣下訓練集 之間的差異很容易導致得到的決策樹 也顯著不同,因此方差 理論上會比較大。
理論上GBDT作為多個決策樹的組合,會得到一個相對單棵決策樹更平滑的模型,因此能一定程度上降低方差,也就沒那麼容易過擬合。但這並非意味著GBDT不存在過擬合,畢竟無論如何它都只能基於訓練數據來學習。Friedman在提出GBM時給出了一些降低GBDT過擬合程度的方法,而XGBoost也相應地做了一些補充和改良。
首先將GBDT模型記為 ,其中 . 那麼 . 又記 ,因此 .
GBDT模型化簡之後可以看作擬合負梯度方向的是決定 的一系列規則,而 是步長。由於 之間的互斥關係,一個 對應於唯一一個前進方向和步長。
1)控制迭代次數和步長
由於Boosting的過程可以看作是在函數空間通過line search方法求最優值解,因此為了減輕過擬合,可以在Boosting層面上可以控制迭代次數和步長,分別對應於 和 . 的最優值可以由交叉檢驗實驗得出,而控制 的常見方法有兩種:
- shrinkage
即指定收縮因子 ,使收縮後的模型變為 。
這種做法可以從多個角度進行解釋,比如從Boosting角度可以看成是通過引入學習率 對步長進行收縮;從決策樹角度看是對葉節點輸出值作收縮;若是將 記為一棵新的決策樹 , 又可以看作是降低每個基函數的影響力。
- L2正則化
即在 損失函數上加上 對應向量 的L2模,使得第 次boost的損失函數為 。
這種方法相當於在原優化目標中加入 的約束,其中常數 與 存在某種關聯。相比起shrinkage方法的人為指定收縮因子, 這種方法對各個分量產生的影響是不均等的,比如說對絕對值大的分量 上的收縮力度會大一些。
2)控制決策樹的結構
以上這些方法能影響的是樹的數目、葉節點輸出值的平滑程度,若要通過調整樹的結構來降低過擬合程度,常用的方法是從隨機森林借鑒過來的row subsampling和column subsampling,分別控制每棵樹採用的樣本集和特徵集,從而使得樹的結構與使用全集時有所不同。
相對於經典CART樹上的後剪枝,以上這些策略更為高效,畢竟GBDT需要擬合多個CART樹,假如讓每棵CART樹都完全生長再剪枝,一是低效,二是讓單棵CART樹儘可能榨乾訓練數據的信息對於Boosting方法來說沒有必要。
雖然XGBoost也支持shrinkage和subsampling等方法,但使其與經典GBDT區別開來的還是它在經典GBDT的損失函數上加上L2正則項和決策樹大小,即損失函數變為 , 其中 為當前這棵決策樹的葉節點數目。這也使得它的參數估計方法與經典GBDT有所不同。
正則化損失函數下的參數估計
傳統GBDT每一步的損失函數為
在參數估計時只需要找到最優的 來擬合負梯度方向 ,再求出最優步長 。由於 之間的互斥關係, ,即各分量的最優解僅與其對應的子區域上的樣本有關。
而正如上文所提到的,XGBoost使用正則化的目標函數
這個目標函數對 並非連續可導的,因此求最優 無法直接通過擬合負梯度方向 來完成。但實際上負梯度方向也是通過對損失函數作一階泰勒近似推導而來的,因此不妨直接通過對損失函數作二階泰勒近似推導出最優的 和 。
1)估計
假設現在處於第 次Boosting,當前的樹結構是 , 劃分出了 個子區域。同樣由子區域之間的互斥關係得到在當前樹結構下 的最優解:
對 作二階泰勒近似得到
很容易可以求出
相比起無正則化約束時的經典GBDT的解
可以直觀而不嚴謹地看作是用Hessian矩陣和正則化係數對負梯度方向作了修正。
2)估計
由於目前是處於第 次boost,因此 是常數,因此在考慮 的生成時可以忽略 ,因此將 代入到 就得到 結構下 這個子區域的損失函數極小值, 個子區域的整體損失函數為
假設現在在結構 的基礎上要對某一個葉節點 繼續進行切分成兩個新的葉節點 和 ,那麼切分之後的整體損失函數的下降值為
使此下降值最大的即是這一次生長的最優切分特徵和最優切分點。使得下降值最大顯然也等價於生長後的損失函數最小,這與CART的生成邏輯是一致的。
另一方面,XGBoost利用了損失函數的二階展開來迭代求解,理論上這會比傳統GBDT的收斂速度更快。
對缺失值和無序離散型特徵的處理方式
缺失值和離散特徵本身也是CART樹生成過程中的的重要話題。之所以要強調「無序」是因為有序的離散特徵在切分時的做法可以和連續特徵一樣,而無序離散特徵的難點在於它總共有 這麼多種切分可能,其中 為該特徵的取值個數。
1)缺失值
先以CART回歸樹為例,生成過程決定切分特徵和切分點的目標函數是
其中 和 根據 在第 維特徵上的值與切分點 的大小關係來定義。
在訓練時假如 在第 維上的特徵缺失,那麼目標函數將無法考慮到這個樣本的信息,相當於將它丟棄;而在預測時,第 維上的特徵缺失的樣本也無法得到預測結果。
CART處理缺失值的常見方式有兩種:
- 將缺失值看作是這個特徵的新取值,填充為「missing」或「NaN」(這是lightGBM採用的方式)
- 採用代理切分特徵。仍然是以回歸樹為例,每次基於非缺失數據上的目標函數找到最優的 之後,再從 以外的特徵尋找和 的「切分行為」很相似的若干個代理特徵。在針對 維特徵缺失的樣本 做預測時,在這些代理特徵裡面找一個 上不缺失且與 相近程度最高的代理特徵來完成切分
XGBoost採用一種叫「default direction」的方法來處理缺失值,有點類似CART的第二種方法,但它決定將 維特徵上缺失的樣本分到 還是 並不是依據具體的某一維代理切分特徵,而是依據將其分到 還是 能使得整體損失函數下降最快。
採用代理切分特徵的缺點在於如果一個樣本最優切分特徵和前面幾個最優代理特徵都缺失,那麼它將會依據一個與最優切分特徵的行為不那麼接近的特徵來做劃分,這就意味著損失函數的增加。而基於整體數據分佈學習出來的「default direction」則能保證損失函數最優。
這種情形在推薦中比較常見,比如以用戶購買列表作為特徵,每個用戶的購買列表都只能覆蓋是全量商品庫裏的少量數目,因此樣本數據必定是高度稀疏的,很有可能會依據很後的代理特徵做劃分。
2)無序離散特徵的切分
CART樹針對無序離散特徵的做法來自於 On Grouping For Maximum Homogeneity ,主要是用於二分類或連續型目標變數的問題,簡單來說是將各取值依據對應的目標變數均值或與目標變數的相關性來排序,依照這個順序來逐個驗證切分點,類似於連續變數上的做法。
lightGBM和Mllib的GBT採用的做法和CART樹的一致,畢竟經典GBDT每棵回歸樹擬合的是負梯度方向,這正好是一個連續型的psuedo-response.
XGBoost比較特殊,它只處理數值型特徵,即默認特徵之間的大小可比較,當成是連續或有序變數那樣來找切分點。因此它對於連續型變數和有序離散型變數比較友好,但無序離散型最好轉為one-hot編碼,否則會誤引入序信息。
參考資料
Greedy Function Approximation: A Gradient Boosting Machine
The Elements of Statistical Learning
XGBoost: A Scalable Tree Boosting System
LightGBM: A Highly Efficient Gradient Boosting Decision Tree
On Grouping For Maximum Homogeneity
Advanced Topics - LightGBM documentationFeatures - LightGBM documentation
Understand your dataset with XGBoost
Multi-Layered Gradient Boosting Decision Trees
推薦閱讀: