XGBoost論文閱畢

kewlgrl發表於2018-10-01

花了兩天讀了陳天奇大神的XGBoost論文,瞭解了大概原理,水平有限,如有錯誤,煩請指正,記錄如下。

一、簡要介紹

1、模型

提升樹(Boosted tree )最基本的組成部分叫做迴歸樹(regression tree),稱為CART。

XGBoost Tree由多個CART整合,按照策略選取最佳分隔點,對稀疏資料進行處理,並加入了例如並行化等優化方法。

2、特點

1、設計並構建了高可擴充套件(規模化的)的端到端的提升樹系統(a highly scalable end-to-end tree
boosting system )

(end-to-end(端對端)的方法是指:一端輸入我的原始資料,一端輸出我想得到的結果。只關心輸入和輸出,中間的步驟全部都不管。)

2、在樹的並行學習過程中引入了新的稀疏感知演算法

3、在理論上證明了分散式加權直方圖演算法能提高計算效率

4、針對樹的核外學習提出了有效的快取感知塊結構

 

提升樹每一次進行迴歸樹生成時採用的訓練資料都是上次預測結果與訓練資料值之間的殘差

 

梯度提升樹其學習流程與提升樹類似只是不再使用殘差作為新的訓練資料而是使用損失函式的梯度作為新的新的訓練資料的y值

 

二、公式推導

目標函式=訓練損失+正則化

 

常用的損失函式有以下兩種:

1、平方損失

2、邏輯迴歸損失

f(x)是單棵樹的葉子結點的得分相加,對於K棵Cart迴歸樹這個過程可以表示如下:

當前模型如下:

採用前向分步演算法來計算函式f(x):

代入模型的公式,其中我們選用平方損失來評估:

使用二階泰勒公式展開:

移除常數項整理得到模型:

重新用向量定義樹的葉子結點:

選取一種方式定義樹的複雜度:

代入模型公式,整理如下:

增加定義,修改公式形式:

我們定義每個葉子結點的權重為:

最終得到的對樹的評估模型:

 

這個模型的得分越小表示樹的分隔點選取得越好~

3、剪枝

優化這個目標對應了樹的剪枝, 當引入的分割帶來的增益小於一個閥值的時候,我們可以剪掉這個分割。

4、防止過擬合

(1)縮減(Shrinkage)

在梯度提升的每一步之後,增加權重,類似於隨機優化過程中的學習率,減少單棵樹的影響

(2)對列的二次取樣(Column Subsampling)

常用於隨機森林,此前從未被應用到提升樹中。從使用者反饋來看,優於傳統的對行的二次取樣,而且還能提高並行演算法的計算速度。

 

三、分隔點查詢演算法

1、基礎貪心演算法

在所有特徵上遍歷,每個特徵中選擇該特徵下的每個值作為其分裂點,計算增益損失。當遍歷完所有特徵之後,增益損失最大的特徵值將作為其分裂點。由此可以看出這其實就是一種窮舉演算法,而整個樹構造過程最耗時的過程就是尋找最優分裂點的過程。

 

缺點:當資料量很大不能全都放入記憶體中的時候,不能高效操作

 

2、近似演算法

根據特徵分佈的百分數取樣,選擇待分隔點,將連續的特徵對映到一個桶(buckets)中,基於統計資訊選擇最佳分隔方案。選擇分隔點的方式有兩個,一種是global,一種是local。

global是在樹構建的初始階段選出所有候選分隔點,後面每層都使用相同的策略選擇分隔點;

local在每次split後重新選出候選分隔點,適合較深的樹,這樣步驟比global多。

綜上,local只需要較少的候選點,而global必須要有足夠多的候選點(桶)才能達到和local差不多的精確度。

對每一個特徵進行「值」取樣,原來需要對每一個特徵的每一個可能分割點進行嘗試,取樣之後只針對取樣的點進行分割嘗試,這種方法很明顯可以減少計算量,取樣密度越小計算的越快,擬合程度也會越差,所以取樣還可以防止過擬合。

 

3、帶權重直方圖演算法

樣本的所有第k個特徵構造一個集合:{特徵的值,二階導數}

序函式表示第k個特徵的值小於z的樣本比例,為了找到滿足相鄰兩個分隔點的值相差不大於閾值e的分隔點。

相當於將特徵的值排序,在這個序列上根據計算帶權的序函式選擇合適的分隔點,使得每個含有不同權重的特徵值區間分佈均勻。

對於帶權重的資料集合,此前還沒有直方圖演算法來處理。

 

4、稀疏感知的分隔點查詢演算法

指定一個預設方向。

這裡只遍歷特徵非空的樣本上對應的所有特徵值,分別嘗試將該缺失特徵分配到左右子樹,分別計算這兩種情況下的打分函式的值,選擇分數較大的方向為缺失資料的預設方向:

計算複雜度是線性的,速度提升50倍。

 

四、並行化

1、按列分塊並行化

對每個特徵的值排序,使用CSC結構儲存資料到塊(block)中。

在不同的特徵屬性上採用多執行緒並行方式尋找最佳分隔點

每一次Split Finding的時候是需要對當前節點中的樣本按照特徵值進行排序的,其實這個排序可以在初始化的時候進行一次就夠了,比如有n個樣本m維特徵,只需要預先生成一個n*m的矩陣,第m列表示的是按照第m個特徵從小到大對樣本的排序索引。 通過指標儲存,一個指標也就是四個位元組,耗費的空間有限。

 

2、快取感知存取

因為對特徵的值排序後,其對應的二階梯度在記憶體中不是連續存放的,所以需要一個新演算法能夠通過行索引直接獲取梯度資料。

在每個執行緒內開闢內部緩衝區,儲存梯度統計資料,以小批量方式執行累加。

預取改變直接讀取相依性為長相依性

也就是說本來每次操作的時候都要尋找特徵對應的梯度,現在放入緩衝區之後,可以很快找到對應資訊並計算。

 

3、核外計算的塊

為了可模組化的學習,將資料分成多個block存在磁碟上,在計算過程中,用其他的執行緒預取資料到主要的記憶體緩衝區,這樣計算和讀資料就可以併發進行。

(1)塊壓縮

但是由於磁碟IO速度太慢,通常更不上計算的速度,將block按列壓縮,對於行索引,只儲存第一個索引值,然後只儲存其餘資料與第一個索引值之差(offset),實驗得到的較好情況是使用16個bits來儲存 offset,因此,一個block一般有2的16次方個樣本。

(2)塊碎片

將資料分片到不同的磁碟上,預取執行緒分配到各個磁碟上,取得的資料放入記憶體緩衝區中,之後訓練執行緒從各個記憶體緩衝區中獲取資料。

有多個磁碟的時候,有助於增加磁碟讀資料的吞吐量。

相關文章