http://www-personal.umich.edu/~jizhu/jizhu/wuke/Friedman-AoS01.pdfhtml
https://www.cnblogs.com/bentuwuying/p/6667267.html面試
https://www.cnblogs.com/ModifyRong/p/7744987.html算法
https://www.cnblogs.com/bentuwuying/p/6264004.htmlapp
1.簡介框架
gbdt全稱梯度降低樹,在傳統機器學習算法裏面是對真實分佈擬合的最好的幾種算法之一,在前幾年深度學習尚未大行其道以前,gbdt在各類競賽是大放異彩。緣由大概有幾個,一是效果確實挺不錯。二是便可以用於分類也能夠用於迴歸。三是能夠篩選特徵。這三點實在是太吸引人了,致使在面試的時候你們也很是喜歡問這個算法。 gbdt的面試考覈點,大體有下面幾個:機器學習
2. 正式介紹函數
首先gbdt 是經過採用加法模型(即基函數的線性組合),以及不斷減少訓練過程產生的殘差來達到將數據分類或者回歸的算法。工具
咱們經過一張圖片,圖片來源來講明gbdt的訓練過程: post
圖 1:GBDT 的訓練過程學習
gbdt經過多輪迭代,每輪迭代產生一個弱分類器,每一個分類器在上一輪分類器的殘差基礎上進行訓練。對弱分類器的要求通常是足夠簡單,而且是低方差和高誤差的。由於訓練的過程是經過下降誤差來不斷提升最終分類器的精度,(此處是能夠證實的)。
弱分類器通常會選擇爲CART TREE(也就是分類迴歸樹)。因爲上述高誤差和簡單的要求 每一個分類迴歸樹的深度不會很深。最終的總分類器 是將每輪訓練獲得的弱分類器加權求和獲得的(也就是加法模型)。
模型最終能夠描述爲:
模型一共訓練M輪,每輪產生一個弱分類器 T(x;θm)T(x;θm)。弱分類器的損失函數
Fm−1(x)Fm−1(x) 爲當前的模型,gbdt 經過經驗風險極小化來肯定下一個弱分類器的參數。具體到損失函數自己的選擇也就是L的選擇,有平方損失函數,0-1損失函數,對數損失函數等等。若是咱們選擇平方損失函數,那麼這個差值其實就是咱們日常所說的殘差。
gbdt選擇特徵的細節實際上是想問你CART Tree生成的過程。這裏有一個前提,gbdt的弱分類器默認選擇的是CART TREE。其實也能夠選擇其餘弱分類器的,選擇的前提是低方差和高誤差。框架服從boosting 框架便可。
下面咱們具體來講CART TREE(是一種二叉樹) 如何生成。CART TREE 生成的過程其實就是一個選擇特徵的過程。假設咱們目前總共有 M 個特徵。第一步咱們須要從中選擇出一個特徵 j,作爲二叉樹的第一個節點。而後對特徵 j 的值選擇一個切分點 m. 一個 樣本的特徵j的值 若是小於m,則分爲一類,若是大於m,則分爲另一類。如此便構建了CART 樹的一個節點。其餘節點的生成過程和這個是同樣的。如今的問題是在每輪迭代的時候,如何選擇這個特徵 j,以及如何選擇特徵 j 的切分點 m:
1 def findLossAndSplit(x,y): 2 # 咱們用 x 來表示訓練數據 3 # 咱們用 y 來表示訓練數據的label 4 # x[i]表示訓練數據的第i個特徵 5 # x_i 表示第i個訓練樣本 6 7 # minLoss 表示最小的損失 8 minLoss = Integet.max_value 9 # feature 表示是訓練的數據第幾緯度的特徵 10 feature = 0 11 # split 表示切分點的個數 12 split = 0 13 14 # M 表示 樣本x的特徵個數 15 for j in range(0,M): 16 # 該維特徵下,特徵值的每一個切分點,這裏具體的切分方式能夠本身定義 17 for c in range(0,x[j]): 18 L = 0 19 # 第一類 20 R1 = {x|x[j] <= c} 21 # 第二類 22 R2 = {x|x[j] > c} 23 # 屬於第一類樣本的y值的平均值 24 y1 = ave{y|x 屬於 R1} 25 # 屬於第二類樣本的y值的平均值 26 y2 = ave{y| x 屬於 R2} 27 # 遍歷全部的樣本,找到 loss funtion 的值 28 for x_1 in all x 29 if x_1 屬於 R1: 30 L += (y_1 - y1)^2 31 else: 32 L += (y_1 - y2)^2 33 if L < minLoss: 34 minLoss = L 35 feature = i 36 split = c 37 return minLoss,feature ,split
其實說gbdt 可以構建特徵並不是很準確,gbdt 自己是不能產生特徵的,可是咱們能夠利用gbdt去產生特徵的組合。在CTR預估中,工業界通常會採用邏輯迴歸去進行處理,在個人上一篇博文當中已經說過,邏輯迴歸自己是適合處理線性可分的數據,若是咱們想讓邏輯迴歸處理非線性的數據,其中一種方式即是組合不一樣特徵,加強邏輯迴歸對非線性分佈的擬合能力。
長久以來,咱們都是經過人工的先驗知識或者實驗來得到有效的組合特徵,可是不少時候,使用人工經驗知識來組合特徵過於耗費人力,形成了機器學習當中一個很奇特的現象:有多少人工就有多少智能。關鍵是這樣經過人工去組合特徵並不必定可以提高模型的效果。因此咱們的從業者或者學界一直都有一個趨勢即是經過算法自動,高效的尋找到有效的特徵組合。Facebook 在2014年 發表的一篇論文即是這種嘗試下的產物,利用gbdt去產生有效的特徵組合,以便用於邏輯迴歸的訓練,提高模型最終的效果。
圖 2:用GBDT 構造特徵
如圖 2所示,咱們 使用 GBDT 生成了兩棵樹,兩顆樹一共有五個葉子節點。咱們將樣本 X 輸入到兩顆樹當中去,樣本X 落在了第一棵樹的第二個葉子節點,第二顆樹的第一個葉子節點,因而咱們即可以依次構建一個五緯的特徵向量,每個緯度表明了一個葉子節點,樣本落在這個葉子節點上面的話那麼值爲1,沒有落在該葉子節點的話,那麼值爲 0.
因而對於該樣本,咱們能夠獲得一個向量[0,1,0,1,0] 做爲該樣本的組合特徵,和原來的特徵一塊兒輸入到邏輯迴歸當中進行訓練。實驗證實這樣會獲得比較顯著的效果提高。
首先明確一點,gbdt 不管用於分類仍是迴歸一直都是使用的CART 迴歸樹。不會由於咱們所選擇的任務是分類任務就選用分類樹,這裏面的核心是由於gbdt 每輪的訓練是在上一輪的訓練的殘差基礎之上進行訓練的。這裏的殘差就是當前模型的負梯度值 。這個要求每輪迭代的時候,弱分類器的輸出的結果相減是有意義的。殘差相減是有意義的。
若是選用的弱分類器是分類樹,類別相減是沒有意義的。上一輪輸出的是樣本 x 屬於 A類,本一輪訓練輸出的是樣本 x 屬於 B類。 A 和 B 不少時候甚至都沒有比較的意義,A 類- B類是沒有意義的。
咱們具體到分類這個任務上面來,咱們假設樣本 X 總共有 K類。來了一個樣本 x,咱們須要使用gbdt來判斷 x 屬於樣本的哪一類。
圖三 gbdt 多分類算法流程
第一步 咱們在訓練的時候,是針對樣本 X 每一個可能的類都訓練一個分類迴歸樹。舉例說明,目前樣本有三類,也就是 K = 3。樣本 x 屬於 第二類。那麼針對該樣本 x 的分類結果,其實咱們能夠用一個 三維向量 [0,1,0] 來表示。0表示樣本不屬於該類,1表示樣本屬於該類。因爲樣本已經屬於第二類了,因此第二類對應的向量維度爲1,其餘位置爲0。
針對樣本有 三類的狀況,咱們實質上是在每輪的訓練的時候是同時訓練三顆樹。第一顆樹針對樣本x的第一類,輸入爲(x,0)(x,0)。第二顆樹輸入針對 樣本x 的第二類,輸入爲(x,1)(x,1)。第三顆樹針對樣本x 的第三類,輸入爲(x,0)(x,0)
在這裏每顆樹的訓練過程其實就是就是咱們以前已經提到過的CATR TREE 的生成過程。在此處咱們參照以前的生成樹的程序 便可以就解出三顆樹,以及三顆樹對x 類別的預測值f1(x),f2(x),f3(x)f1(x),f2(x),f3(x)。那麼在此類訓練中,咱們仿照多分類的邏輯迴歸 ,使用softmax 來產生機率,則屬於類別 1 的機率
而且咱們咱們能夠針對類別1 求出 殘差y11(x)=0−p1(x)y11(x)=0−p1(x);類別2 求出殘差y22(x)=1−p2(x)y22(x)=1−p2(x);類別3 求出殘差y33(x)=0−p3(x)y33(x)=0−p3(x).
而後開始第二輪訓練 針對第一類 輸入爲(x,y11(x)y11(x)), 針對第二類輸入爲(x,y22(x))y22(x)), 針對 第三類輸入爲 (x,y33(x)y33(x)).繼續訓練出三顆樹。一直迭代M輪。每輪構建 3顆樹。
因此當K =3。咱們其實應該有三個式子
當訓練完畢之後,新來一個樣本 x1 ,咱們須要預測該樣本的類別的時候,即可以有這三個式子產生三個值,f1(x),f2(x),f3(x)f1(x),f2(x),f3(x)。樣本屬於 某個類別c的機率爲
上面的理論闡述可能仍舊過於難懂,咱們下面將拿Iris 數據集中的六個數據做爲例子,來展現gbdt 多分類的過程。
樣本編號 | 花萼長度(cm) | 花萼寬度(cm) | 花瓣長度(cm) | 花瓣寬度 | 花的種類 |
1 | 5.1 | 3.5 | 1.4 | 0.2 | 山鳶尾 |
2 | 4.9 | 3.0 | 1.4 | 0.2 | 山鳶尾 |
3 | 7.0 | 3.2 | 4.7 | 1.4 | 雜色鳶尾 |
4 | 6.4 | 3.2 | 4.5 | 1.5 | 雜色鳶尾 |
5 | 6.3 | 3.3 | 6.0 | 2.5 | 維吉尼亞鳶尾 |
6 | 5.8 | 2.7 | 5.1 | 1.9 | 維吉尼亞鳶尾 |
這是一個有6個樣本的三分類問題。咱們須要根據這個花的花萼長度,花萼寬度,花瓣長度,花瓣寬度來判斷這個花屬於山鳶尾,雜色鳶尾,仍是維吉尼亞鳶尾。具體應用到gbdt多分類算法上面。咱們用一個三維向量來標誌樣本的label。[1,0,0] 表示樣本屬於山鳶尾,[0,1,0] 表示樣本屬於雜色鳶尾,[0,0,1] 表示屬於維吉尼亞鳶尾。
gbdt 的多分類是針對每一個類都獨立訓練一個 CART Tree。因此這裏,咱們將針對山鳶尾類別訓練一個 CART Tree 1。雜色鳶尾訓練一個 CART Tree 2 。維吉尼亞鳶尾訓練一個CART Tree 3,這三個樹相互獨立。
咱們以樣本 1 爲例。針對 CART Tree1 的訓練樣本是[5.1,3.5,1.4,0.2][5.1,3.5,1.4,0.2],label 是 1,最終輸入到模型當中的爲[5.1,3.5,1.4,0.2,1][5.1,3.5,1.4,0.2,1]。針對 CART Tree2 的訓練樣本也是[5.1,3.5,1.4,0.2][5.1,3.5,1.4,0.2],可是label 爲 0,最終輸入模型的爲[5.1,3.5,1.4,0.2,0][5.1,3.5,1.4,0.2,0]. 針對 CART Tree 3的訓練樣本也是[5.1,3.5,1.4,0.2][5.1,3.5,1.4,0.2],label 也爲0,最終輸入模型當中的爲[5.1,3.5,1.4,0.2,0][5.1,3.5,1.4,0.2,0].
下面咱們來看 CART Tree1 是如何生成的,其餘樹 CART Tree2 , CART Tree 3的生成方式是同樣的。CART Tree的生成過程是從這四個特徵中找一個特徵作爲CART Tree1 的節點。好比花萼長度作爲節點。6個樣本當中花萼長度 大於5.1 cm的就是 A類,小於等於 5.1 cm 的是B類。生成的過程其實很是簡單,問題 1.是哪一個特徵最合適? 2.是這個特徵的什麼特徵值做爲切分點? 即便咱們已經肯定了花萼長度作爲節點。花萼長度自己也有不少值。在這裏咱們的方式是遍歷全部的可能性,找到一個最好的特徵和它對應的最優特徵值可讓當前式子的值最小。
咱們以第一個特徵的第一個特徵值爲例。R1 爲全部樣本中花萼長度小於 5.1 cm 的樣本集合,R2 爲全部樣本當中花萼長度大於等於 5.1cm 的樣本集合。因此 R1={2}R1={2},R2={1,3,4,5,6}R2={1,3,4,5,6}.
圖 5 節點分裂示意圖
y1 爲 R1 全部樣本的label 的均值 1/1=11/1=1。y2 爲 R2 全部樣本的label 的均值 (1+0+0+0+0)/5=0.2(1+0+0+0+0)/5=0.2。
下面便開始針對全部的樣本計算這個式子的值。樣本1 屬於 R2 計算的值爲(1−0.2)2(1−0.2)2, 樣本2 屬於R1 計算的值爲(1−1)2(1−1)2, 樣本 3,4,5,6同理都是 屬於 R2的 因此值是(0−0.2)2(0−0.2)2. 把這六個值加起來,即是 山鳶尾類型在特徵1 的第一個特徵值的損失值。這裏算出來(1-0.2)^2+ (1-1)^2 + (0-0.2)^2+(0-0.2)^2+(0-0.2)^2 +(0-0.2)^2= 0.84
接着咱們計算第一個特徵的第二個特徵值,計算方式同上,R1 爲全部樣本中 花萼長度小於 4.9 cm 的樣本集合,R2 爲全部樣本當中 花萼長度大於等於 4.9 cm 的樣本集合.因此 R1={}R1={},R1={1,2,3,4,5,6}R1={1,2,3,4,5,6}. y1 爲 R1 全部樣本的label 的均值 = 0。y2 爲 R2 全部樣本的label 的均值 (1+1+0+0+0+0)/6=0.3333(1+1+0+0+0+0)/6=0.3333。
圖 6 第一個特徵的第二個特偵值的節點分裂狀況
咱們須要針對全部的樣本,樣本1 屬於 R2, 計算的值爲(1−0.333)2(1−0.333)2, 樣本2 屬於R2 ,計算的值爲(1−0.333)2(1−0.333)2, 樣本 3,4,5,6同理都是 屬於 R2的, 因此值是(0−0.333)2(0−0.333)2. 把這六個值加起來山鳶尾類型在特徵1 的第二個特徵值的損失值。這裏算出來 (1-0.333)^2+ (1-0.333)^2 + (0-0.333)^2+(0-0.333)^2+(0-0.333)^2 +(0-0.333)^2 = 2.244189. 這裏的損失值大於 特徵一的第一個特徵值的損失值,因此咱們不取這個特徵的特徵值。
圖 7 全部狀況說明
這樣咱們能夠遍歷全部特徵的全部特徵值,找到讓這個式子最小的特徵以及其對應的特徵值,一共有24種狀況,4個特徵*每一個特徵有6個特徵值。在這裏咱們算出來讓這個式子最小的特徵花萼長度,特徵值爲5.1 cm。這個時候損失函數最小爲 0.8。
因而咱們的預測函數此時也能夠獲得:
此處 R1 = {2},R2 = {1,3,4,5,6},y1 = 1,y2 = 0.2。訓練完之後的最終式子爲
藉由這個式子,咱們獲得對樣本屬於類別1 的預測值 f1(x)=1+0.2∗5=2f1(x)=1+0.2∗5=2。同理咱們能夠獲得對樣本屬於類別2,3的預測值f2(x)f2(x),f3(x)f3(x).樣本屬於類別1的機率 即爲
下面咱們用代碼來實現整個找特徵的過程,你們能夠本身再對照代碼看看。
1 # 定義訓練數據 2 train_data = [[5.1,3.5,1.4,0.2],[4.9,3.0,1.4,0.2],[7.0,3.2,4.7,1.4],[6.4,3.2,4.5,1.5],[6.3,3.3,6.0,2.5],[5.8,2.7,5.1,1.9]] 3 4 # 定義label 5 label_data = [[1,0,0],[1,0,0],[0,1,0],[0,1,0],[0,0,1],[0,0,1]] 6 # index 表示的第幾類 7 def findBestLossAndSplit(train_data,label_data,index): 8 sample_numbers = len(label_data) 9 feature_numbers = len(train_data[0]) 10 current_label = [] 11 12 # define the minLoss 13 minLoss = 10000000 14 15 # feature represents the dimensions of the feature 16 feature = 0 17 18 # split represents the detail split value 19 split = 0 20 21 # get current label 22 for label_index in range(0,len(label_data)): 23 current_label.append(label_data[label_index][index]) 24 25 # trans all features 26 for feature_index in range(0,feature_numbers): 27 ## current feature value 28 current_value = [] 29 30 for sample_index in range(0,sample_numbers): 31 current_value.append(train_data[sample_index][feature_index]) 32 L = 0 33 ## different split value 34 print current_value 35 for index in range(0,len(current_value)): 36 R1 = [] 37 R2 = [] 38 y1 = 0 39 y2 = 0 40 41 for index_1 in range(0,len(current_value)): 42 if current_value[index_1] < current_value[index]: 43 R1.append(index_1) 44 else: 45 R2.append(index_1) 46 47 ## calculate the samples for first class 48 sum_y = 0 49 for index_R1 in R1: 50 sum_y += current_label[index_R1] 51 if len(R1) != 0: 52 y1 = float(sum_y) / float(len(R1)) 53 else: 54 y1 = 0 55 56 ## calculate the samples for second class 57 sum_y = 0 58 for index_R2 in R2: 59 sum_y += current_label[index_R2] 60 if len(R2) != 0: 61 y2 = float(sum_y) / float(len(R2)) 62 else: 63 y2 = 0 64 65 ## trans all samples to find minium loss and best split 66 for index_2 in range(0,len(current_value)): 67 if index_2 in R1: 68 L += float((current_label[index_2]-y1))*float((current_label[index_2]-y1)) 69 else: 70 L += float((current_label[index_2]-y2))*float((current_label[index_2]-y2)) 71 72 if L < minLoss: 73 feature = feature_index 74 split = current_value[index] 75 minLoss = L 76 print "minLoss" 77 print minLoss 78 print "split" 79 print split 80 print "feature" 81 print feature 82 return minLoss,split,feature 83 84 findBestLossAndSplit(train_data,label_data,0)
目前,咱們總結了 gbdt 的算法的流程,gbdt如何選擇特徵,如何產生特徵的組合,以及gbdt 如何用於分類,這個目前能夠認爲是gbdt 最常常問到的四個部分。至於剩餘的問題,由於篇幅的問題,咱們準備再開一個篇幅來進行總結。.
ABSTRACT
這篇paper中做者結合GBDT和LR,取得了很好的效果,比單個模型的效果高出3%。隨後做者研究了對總體預測系統產生影響的幾個因素,發現Feature(能挖掘出用戶和廣告的歷史信息)+Model(GBDT+LR)的貢獻程度最大,而其餘因素(數據實時性,模型學習速率,數據採樣)的影響則較小。
1. INTRODUCTION
介紹了先前的一些相關paper。包括Google,Yahoo,MS的關於CTR Model方面的paper。
而在Facebook,廣告系統是由級聯型的分類器(a cascade of classifiers)組成,而本篇paper討論的CTR Model則是這個cascade classifiers的最後一環節。
2. EXPERIMENTAL SETUP
做者介紹瞭如何構建training data和testing data,以及Evaluation Metrics。包括Normalized Entropy和Calibration。
Normalized Entropy的定義爲每次展示時預測獲得的log loss的平均值,除以對整個數據集的平均log loss值。之因此須要除以整個數據集的平均log loss值,是由於backgroud CTR越接近於0或1,則越容易預測取得較好的log loss值,而作了normalization後,NE便會對backgroud CTR不敏感了。這個Normalized Entropy值越低,則說明預測的效果越好。下面列出表達式:
Calibration的定義爲預估CTR除以真實CTR,即預測的點擊數除以真實觀察到的點擊數。這個值越接近1,則代表預測效果越好。
3. PREDICTION MODEL STRUCTURE
做者介紹了兩種Online Learning的方法。包括Stochastic Gradient Descent(SGD)-based LR:
和Bayesian online learning scheme for probit regression(BOPR):
BOPR每輪迭代時的更新公式爲:
3.1 Decision tree feature transforms
Linear Model的表達能力不夠,須要feature transformation。第一種方法是對連續feature進行分段處理(怎樣分段,以及分段的分界點是很重要的);第二種方法是進行特徵組合,包括對離散feature作笛卡爾積,或者對連續feature使用聯合分段(joint binning),好比使用k-d tree。
而使用GBDT能做爲一種很好的feature transformation的工具,咱們能夠把GBDT中的每棵樹做爲一種類別的feature,把一個instance通過GBDT的流程(即從根節點一直往下分叉到一個特定的葉子節點)做爲一個instance的特徵組合的過程。這裏GBDT採用的是Gradient Boosting Machine + L2-TreeBoost算法。這裏是本篇paper的重點部分,放一張經典的原圖:
3.2 Data freshness
CTR預估系統是在一個動態的環境中,數據的分佈隨時在變化,因此本文探討了data freshness對預測效果的影響,代表training data的日期越靠近,效果越好。
3.3 Online linear classifier
探討了對SGD-based LR中learning rate的選擇。最好的選擇爲:
1)global效果差的緣由:每一個維度上訓練樣本的不平衡,每一個訓練樣本擁有不一樣的feature。那些擁有樣本數較少的維度的learning rate降低過快,致使沒法收斂到最優值。
2)per weight差的緣由:雖然對於各個維度有所區分,可是其對於各個維度的learning rate降低速度都太快了,訓練過早結束,沒法收斂到最優值。
SGD-based LR vs BOPR
1)SGD-based LR對比BOPR的優點:
1-1)模型參數少,內存佔用少。SGD-based LR每一個維度只有一個weight值,而BOPR每一個維度有1個均值 + 1個方差值。
1-2)計算速度快。SGD-LR只需1次內積計算,BOPR須要2次內積計算。
2)BOPR對比SGD-based LR的優點:
2-1)BOPR能夠獲得完整的預測點擊機率分佈。
4 ONLINE DATA JOINER
Online Data Joiner主要是用於在線的將label與相應的features進行join。同時做者也介紹了正負樣本的選取方式,以及選取負樣本時候的waiting time window的選擇。
5 CONTAINING MEMORY AND LATENCY
做者探討了GBDT中tree的個數,各類類型的features(包括contextual features和historical features),對預測效果的影響。結論以下:
1)NE的降低基原本自於前500棵樹。
2)最後1000棵樹對NE的下降貢獻低於0.1%。
3)Submodel 2 過擬合,數據量較少,只有其他2個模型的約四分之一。
4)Importance爲feature帶來的累積信息增益 / 平方差的減小
5)Top 10 features貢獻了將近一半的importance
6)最後的300個features的貢獻不足1%
6 COPYING WITH MASSIVE TRANING DATA
做者探討了如何進行樣本採樣的過程,包括了均勻採樣(Uniform subsampling),和負樣本降採樣(Negative down sampling),以及對預測效果的影響。
Function approximation是從function space方面進行numerical optimization,其將stagewise additive expansions和steepest-descent minimization結合起來。而由此而來的Gradient Boosting Decision Tree(GBDT)能夠適用於regression和classification,都具備完整的,魯棒性高,解釋性好的優勢。
在機器學習的任務中,咱們通常面對的問題是構造loss function,並求解其最小值。能夠寫成以下形式:
一般的loss function有:
1. regression:均方偏差(y-F)2,絕對偏差|y-F|
2. classification:negative binomial log-likelihood log(1+e-2yF)
通常狀況下,咱們會把F(x)看作是一系列帶參數的函數集合 F(x;P),因而進一步將其表示爲「additive」的形式:
咱們能夠經過選取一個參數模型F(x;P),來將function optimization問題轉化爲一個parameter optimization問題:
進一步,咱們能夠把要優化的參數也表示爲「additive」的形式:
梯度降低是最簡單,最經常使用的numerical optimization method之一。
首先,計算出當前的梯度:
where
而梯度降低的步長爲:
where ,稱爲「line search」。
如今,咱們考慮「無參數」模型,轉而考慮直接在function space 進行numerical optimization。這時候,咱們將在每一個數據點x處的函數值F(x)看作是一個「參數」,仍然是來對loss funtion求解最小值。
在function space,爲了表示一個函數F(x),理想情況下有無數個點,但在現實中,咱們用有限個(N個)離散點來表示它:。
按照以前的numerical optimization的方式,咱們須要求解:
使用steepest-descent,有:
where ,and
當咱們面對的狀況爲:用有限的數據集表示x,y的聯合分佈的時候,上述的方法就有點行不通了。咱們能夠試試「greedy-stagewise」的方法:
可是對於通常的loss function和base learner來講,(9)式是很難求解的。給定了m次迭代後的當前近似函數Fm-1(x),當步長的direction是指數函數集合
當中的一員時,
能夠看作是在求解最優值上的greedy step,一樣,它也能夠被看作是相同限制下的steepest-descent step。做爲比較,
給出了在無限制條件下,在Fm-1(x)處的steepest-descent step direction。一種行之有效的方法就是在求解
的時候,把它取爲無限制條件下的負梯度方向
:
where
這就把(9)式中較難求解的優化問題轉化爲了一個基於均方偏差的擬合問題。
Gradient Boosting的通用解法以下:
GBDT的全稱是Gradient Boosting Decision Tree,Gradient Boosting和Decision Tree是兩個獨立的概念。所以咱們先說說Boosting。Boosting的概念很好理解,意思是用一些弱分類器的組合來構造一個強分類器。所以,它不是某個具體的算法,它說的是一種理念。和這個理念相對應的是一次性構造一個強分類器。像支持向量機,邏輯迴歸等都屬於後者。一般,咱們經過相加來組合分類器,形式以下:
給定一個問題,咱們如何構造這些弱分類器呢?Gradient Boosting Modeling (GBM) 就是構造 這些弱分類的一種方法。一樣,它指的不是某個具體的算法,仍然只是一個理念。在理解 Gradient Boosting Modeling 以前,咱們先看看一個典型的優化問題:
針對這種優化問題,有一個經典的算法叫 Steepest Gradient Descent,也就是最深梯度降低法。 這個算法的過程大體以下:
以上迭代過程能夠這麼理解:整個尋優的過程就是個小步快跑的過程,每跑一小步,都往函數當前降低最快的那個方向走一點。
這樣尋優獲得的結果能夠表示成加和形式,即:
這個形式和以上Fm(x)是否是很是類似? Gradient Boosting 正是由此啓發而來。 構造Fm(x)自己也是一個尋優的過程,只不過咱們尋找的不是一個最優勢,而是一個最優的函數。優化的目標一般都是經過一個損失函數來定義,即:
其中Loss(F(xi), yi)表示損失函數Loss在第i個樣本上的損失值,xi和yi分別表示第 i 個樣本的特徵和目標值。常見的損失函數如平方差函數:
相似最深梯度降低法,咱們能夠經過梯度降低法來構造弱分類器f1, f2, ... , fm,只不過每次迭代時,令
即對損失函數L,以 F 爲參考求取梯度。
這裏有個小問題,一個函數對函數的求導很差理解,並且一般都沒法經過上述公式直接求解 到梯度函數gi。爲此,採起一個近似的方法,把函數Fi−1理解成在全部樣本上的離散的函數值,即:
不難理解,這是一個 N 維向量,而後計算
這是一個函數對向量的求導,獲得的也是一個梯度向量。注意,這裏求導時的變量仍是函數F,不是樣本xk。
嚴格來講 ĝi(xk) for k = 1,2, ... , N 只是描述了gi在某些個別點上的值,並不足以表達gi,但咱們能夠經過函數擬合的方法從ĝi(xk) for k = 1,2, ... , N 構造gi,這樣咱們就經過近似的方法獲得了函數對函數的梯度求導。
所以 GBM 的過程能夠總結爲以下:
常量函數f0一般取樣本目標值的均值,即
以上 Gradient Boosting Modeling 的過程當中,尚未說清楚如何經過離散值 ĝi−1(xj) for j = 1,2,3,...N 構造擬合函數gi−1。函數擬合是個比較熟知的概念,有不少現成的方法,不過有一種擬合方法廣爲應用,那就是決策樹 Decision Tree,有關決策樹的概念,理解GBDT重點首先是Gradient Boosting,其次纔是 Decision Tree。GBDT 是 Gradient Boosting 的一種具體實例,只不過這裏的弱分類器是決策樹。若是你改用其餘弱分類器 XYZ,你也能夠稱之爲 Gradient Boosting XYZ。只不過 Decision Tree 很好用,GBDT 才如此引人注目。
談到 GBDT,常聽到一種簡單的描述方式:「先構造一個(決策)樹,而後不斷在已有模型和實際樣本輸出的殘差上再構造一顆樹,依次迭代」。其實這個說法不全面,它只是 GBDT 的一種特殊狀況,爲了看清這個問題,須要對損失函數的選擇作一些解釋。
從對GBM的描述裏能夠看到Gradient Boosting過程和具體用什麼樣的弱分類器是徹底獨立的,能夠任意組合,所以這裏再也不刻意強調用決策樹來構造弱分類器,轉而咱們來仔細看看弱分類器擬合的目標值,即梯度ĝi−1(xj ),以前咱們已經提到過
Boosting 是一類機器學習算法,在這個家族中還有一種很是著名的算法叫 AdaBoost,是 Adaptive Boosting 的簡稱,AdaBoost 在人臉檢測問題上尤爲出名。既然也是 Boosting,能夠想象它的構造過程也是經過多個弱分類器來構造一個強分類器。那 AdaBoost 和 GBDT 有什麼區別呢?
二者最大的區別在於,AdaBoost 不屬於 Gradient Boosting,即它在構造弱分類器時並無利用到梯度降低法的思想,而是用的Forward Stagewise Additive Modeling (FSAM)。爲了理解 FSAM,在回過頭來看看以前的優化問題。
嚴格來講以前描述的優化問題要求咱們同時找出α1, α2, ... , αm和f1, f2, f3 ... , fm,這個問題很 難。爲此咱們把問題簡化爲分階段優化,每一個階段找出一個合適的α 和f 。假設咱們已經 獲得前 m-1 個弱分類器,即Fm−1(x),下一步在保證Fm−1(x)不變的前提下,尋找合適的 αmfm(x)。按照損失函數的定義,咱們能夠獲得
若是 Loss 是平方差函數,則咱們有
這裏yi − Fm−1(xi)就是當前模型在數據上的殘差,能夠看出,求解合適的αmfm(x)就是在這 當前的殘差上擬合一個弱分類器,且損失函數仍是平方差函數。這和 GBDT 選擇平方差損失 函數時構造弱分類器的方法剛好一致。
(1)擬合的是「殘差」,對應於GBDT中的梯度方向。
(2)損失函數是平方差函數,對應於GBDT中用Decision Tree來擬合「殘差」。
其中 wim−1= exp(−yi(Fm−1(xi))和要求解的αmfm(x)無關,能夠當成樣本的權重,所以在這種狀況下,構造弱分類器就是在對樣本設置權重後的數據上擬合,且損失函數仍是指數形式。 這個就是 AdaBoost,不過 AdaBoost 最先並非按這個思路推出來的,相反,是在 AdaBoost 提出 5 年後,人們纔開始用 Forward Stagewise Additive Modeling 來解釋 AdaBoost 背後的原理。
爲何要把平方差和指數形式 Loss 函數單獨拿出來講呢?這是由於對這兩個損失函數來講, 按照 Forward Stagewise Additive Modeling 的思路構造弱分類器時比較方便。若是是平方差損 失函數,就在殘差上作平方差擬合構造弱分類器; 若是是指數形式的損失函數,就在帶權 重的樣本上構造弱分類器。但損失函數若是不是這兩種,問題就沒那麼簡單,好比絕對差值 函數,雖然構造弱分類器也能夠表示成在殘差上作絕對差值擬合,但這個子問題自己也不容 易解,由於咱們是要構造多個弱分類器的,因此咱們固然但願構造弱分類器這個子問題比較 好解。所以 FSAM 思路沒法推廣到其餘一些實用的損失函數上。相比而言,Gradient Boosting Modeling (GBM) 有什麼優點呢?GBM 每次迭代時,只須要計算當前的梯度,並在平方差損 失函數的基礎上擬合梯度。雖然梯度的計算依賴原始問題的損失函數形式,但這不是問題, 只要損失函數是連續可微的,梯度就能夠計算。至於擬合梯度這個子問題,咱們老是能夠選 擇平方差函數做爲這個子問題的損失函數,由於這個子問題是一個獨立的迴歸問題。
所以 FSAM 和 GBM 獲得的模型雖然從形式上是同樣的,都是若干弱模型相加,可是他們求 解弱分類器的思路和方法有很大的差異。只有當選擇平方差函數爲損失函數時,這兩種方法 等同。
以上比較了 GBM 和 FSAM,能夠看到 GBM 在損失函數的選擇上有更大的靈活性,但這不足以解釋GBDT的所有優點。GBDT是拿Decision Tree做爲GBM裏的弱分類器,GBDT的優點 首先得益於 Decision Tree 自己的一些良好特性,具體能夠列舉以下:
Decision Tree 能夠很好的處理 missing feature,這是他的自然特性,由於決策樹的每一個節點只依賴一個 feature,若是某個 feature 不存在,這顆樹依然能夠拿來作決策,只是少一些路徑。像邏輯迴歸,SVM 就沒這個好處。
Decision Tree 能夠很好的處理各類類型的 feature,也是自然特性,很好理解,一樣邏輯迴歸和 SVM 沒這樣的自然特性。
對特徵空間的 outlier 有魯棒性,由於每一個節點都是 x < 𝑇 的形式,至於大多少,小多少沒有區別,outlier 不會有什麼大的影響,一樣邏輯迴歸和 SVM 沒有這樣的自然特性。
若是有不相關的 feature,沒什麼干擾,若是數據中有不相關的 feature,頂多這個 feature 不出如今樹的節點裏。邏輯迴歸和 SVM 沒有這樣的自然特性(可是有相應的補救措施,好比邏輯迴歸裏的 L1 正則化)。
數據規模影響不大,由於咱們對弱分類器的要求不高,做爲弱分類器的決策樹的深 度通常設的比較小,即便是大數據量,也能夠方便處理。像 SVM 這種數據規模大的時候訓練會比較麻煩。
固然 Decision Tree 也不是毫完好陷,一般在給定的不帶噪音的問題上,他能達到的最佳分類效果仍是不如 SVM,邏輯迴歸之類的。可是,咱們實際面對的問題中,每每有很大的噪音,使得 Decision Tree 這個弱勢就不那麼明顯了。並且,GBDT 經過不斷的疊加組合多個小的 Decision Tree,他在不帶噪音的問題上也能達到很好的分類效果。換句話說,經過GBDT訓練組合多個小的 Decision Tree 每每要比一次性訓練一個很大的 Decision Tree 的效果好不少。所以不能把 GBDT 理解爲一顆大的決策樹,幾顆小樹通過疊加後就再也不是顆大樹了,它比一顆大樹更強。