前向分步算法 && AdaBoost算法 && 提高樹(GBDT)算法 && XGBoost算法

1. 提高方法

提高(boosting)方法是一種經常使用的統計學方法,在分類問題中,它經過逐輪不斷改變訓練樣本的權重,學習多個分類器,並將這些分類器進行線性組合,提升分類的性能html

0x1: 提高方法的基本思路

提高方法基於這樣一種思想:對於一個複雜任務來講,將多個專家的判斷進行適當(按照必定權重)綜合(例如線性組合加法模型)所得出的判斷,要比其中任何一個專家單獨的判斷好git

歷史上,Kearns和Valiant首先提出了「強可學習(strongly learnable)」和「弱可學習(weekly learnable)」的概念,指出在機率近似正確(probably approximately correct,PAC)學習的框架中github

1. 一個概念(機率規律)若是存在一個多項式的學習算法可以學習它(經過建模抽象擬合),而且正確率很高,那麼就稱這個概念是強可學習的;
2. 一個概念若是存在一個多項式的學習算法可以學習它,可是學習的正確率僅比隨機猜想略好,那麼就稱這個概念是弱可學習的

同時,後來Schapire證實強在PAC學習的框架下,一個概念是強可學習的充分必要條件是這個概念是弱可學習的。這樣一來,問題就轉化爲了,在算法訓練建模中,若是已經發現了「弱可學習算法」(即當前分類效果並不優秀,甚至僅僅比隨機預測效果要好),就有可能將其boosting(提高)爲強可學習算法,這其中最具表明性的方法就是AdaBoosting(AdaBoosting algorithm)web

提高方法就是從弱學習算法出發,反覆學習,獲得一系列弱分類器(基本分類器),而後組合這些弱分類器,構成一個強分類器。大多數的提高方法都是改變訓練數據的機率分佈(訓練數據的權重分佈)算法

0x2:提高方法的兩個關鍵要素

對於提高方法來講,有兩個很是重要的問題api

1. 在每一輪如何改變訓練數據的權值或機率分佈,修改的策略是什麼?
2. 如何將弱分類器組合成一個強分類器?

這2個問題是全部Boosting方法都要考慮和解決的問題,這裏以AdaBoost爲例,討論AdaBoost的策略數組

1. 提升那些被前一輪弱分類器錯誤分類的樣本的權值,而下降那些被正確分類樣本的權值。這樣一來,那些被分錯的數據,在下一輪就會獲得更大的關注。因此,分類問題被一系列的弱分類器「分而治之」
2. 對弱分類器的組合,AdaBoost採起加權多數表決的方法。即加大分類偏差率小的弱分類器的權值,使其在表決中起較大做用,減少分類偏差率大的弱分類器的權值,使其在表決中起較小的做用

Relevant Link:網絡

https://cseweb.ucsd.edu/~yfreund/papers/IntroToBoosting.pdf
http://blog.csdn.net/dark_scope/article/details/14103983

 

2. 前向分步算法

在開始學習AdaBoost算法以前,咱們須要先了解前向分步算法思想。實際上,AdaBoost算法是模型爲加法模型、損失函數爲指數函數、學習算法爲前向分步算法時的二類分類學習算法併發

0x1:加法模型(aditive model)

加法模型是一種線性模型,,其中,爲基函數,爲基函數的參數,爲基函數的係數(權重)app

在給定訓練數據及損失函數的條件下,學習加法模型成爲經驗風險極小化(即損失函數極小化)問題:

即同時考慮N個樣本在整個線性模型組中的損失函數的極小值,一般這是一個十分複雜的優化問題(求極值問題),想要一步到位求出最優解特別困難。前向分步算法(forward stagewise algorithm)求解這一優化問題的思想是:

由於學習的是加法模型(線性模型),若是可以從前向後,每一步只學習一個基函數及其係數,逐步逼近優化目標函數式,那麼就能夠極大簡化優化的複雜度

具體地,每步只須要優化以下損失函數:,即一次只要考慮一個基函數及其係數便可

有一點要注意,前向分步的思想和貝葉斯估計有相似的地方:

它們都假設每一步之間的基函數和係數是獨立不相關的(在貝葉斯估計中這叫獨立同分布),也由於這一假設才能夠把原始的全局最優解求解等價爲分步的子項求解過程。
可是這種假設會丟失一部分精確度,即每一步之間的依賴關聯會被丟棄

而前向分步算法的思想就是不求一步到位,而是逐步逼近最優解,經過分步求得每一步的最優解來逼近全局最優解。我我的以爲這和SGD梯度降低的求最優思想是同樣的

0x2:算法策略

和其餘統計機器學習模型同樣,前向分佈算法的策略也一樣是:經驗風險最小化。若是在模型中加入了penalty懲罰項,則能夠演進爲結構風險最小化

0x3: 前向分步算法

給定訓練數據集,損失函數和基函數的集合,學習加法模型的前向分步算法以下

(1)初始化

(2)對m = 1,2,3...,M(M表明基函數個數)

  (a)在上一步獲得的最優基函數的基礎上,極小化本次單個基函數的損失函數:,獲得本輪最優基函數參數

  (b)更新(線性累加基函數)

(3)獲得最終加法模型

這樣,前向分步算法將同時求解從m=1到M全部參數的全局最優解問題簡化爲逐次求解各個的局部最優化問題

Relevant Link:

https://en.wikipedia.org/wiki/Additive_model
https://en.wikipedia.org/wiki/Generalized_additive_model
http://www.stat.cmu.edu/~ryantibs/advmethods/notes/addmodels.pdf

 

3. AdaBoost算法

0x1:算法過程

假設給定一個二類分類的訓練數據集(adaboost不限於二類分類),其中,每一個樣本點由實例與標記組成。實例是實例空間,是標記集合。AdaBoost利用如下算法,從訓練數據集中學習一系列弱分類器或基本分類器,並將這些弱分類器線性組合成一個強分類器

  • (1)初始化訓練數據的權值分佈(N表明樣本數量):(初始等機率分佈體現了最大熵原理,在沒有任何先驗知識的前提下做等機率假設是最合理的)。這一步假設數據集具備均勻的權值分佈,即每一個訓練樣本在基本分類器的學習中做用相同,這一假設保證第一步可以在原始數據上學習基本分類器
  • (2)假設訓練輪次爲M(直到達到某個預約的足夠小的錯誤率或達到預先指定的最大迭代次數),則對m = 1,2,....,M

  (2.1)使用具備權值分佈的訓練數據集(對應本輪權值分佈的數據集)學習,獲得本輪次的基本分類器:

  (2.2)計算在本輪訓練數據集上的分類偏差率(權重偏差函數):在加權的訓練數據集上的分類偏差率是被誤分類樣本的權值之和,注意,權重偏差函數關注的是本輪數據集的權重(機率)分佈,而不關注弱分類器內部的參數。即咱們對本輪高几率分佈(重點關注的數據)的錯誤會給與更大的懲罰,這樣就體現了模型Adding組合過程當中根據權重偏差進行模型組合選擇的策略了

  (2.3)根據本輪的弱分類器對數據集的分類偏差計算的模型係數:,表明了本輪獲得的弱分類器的重要程度。由左式可知,當時,,而且隨着的減少而增大,因此在本輪分類偏差率越小的基本分類器在最終分類器中的做用越大

  (2.4)更新下一輪訓練數據集的權值分佈:是規範化因子:,它使得成爲一個機率分佈(每一輪的權值總和都爲1,)。由此可知,被基本分類器誤分類樣本的權值得以擴大,而被正確分類樣本的權值卻在下一輪得以縮小。兩相比較,誤分類樣本的權值被放大了倍,所以誤分類樣本在下一輪學習中起更大做用。不改變所給的訓練數據自己,而不斷改變訓練數據權值的分佈,使得訓練數據在基本分類器的學習中起不一樣的做用,一次優化一個弱分類模型,或者理解理解爲一次優化全局複雜問題中的一次子問題(分而治之)

從數學的角度看,這也是一個平滑單調遞增函數和 log 指數函數組合獲得的動態增減平衡獲得的神奇效果

  • (3)構建基本分類器的線性組合:,獲得最終分類器:。線性組合實現M個基本分類器的加權表決。係數表示了基本分類器的重要性
能夠看到,在每輪的訓練中,訓練樣本的權值分佈不斷在變更,同時
1. 權值分佈對本輪的弱分類器在最終線性分類器組合中重要程度起正比例做用;
2. 對下一輪的樣本權值調整起反比例做用

0x2:算法策略

毫無疑問是經驗風險最小化策略

0x3:AdaBoost的一個例子

分析一下書上給的例子的計算過程,體會adaboost的思想

初始化訓練數據的權值分佈:,在第一輪輸入原始數據自己

1. 迭代過程 m = 1

要肯定本輪的權重偏差率,首先要"肯定"出本輪的模型內部參數(可是最終偏差損失的評估同時也受本輪數據集的權重分佈影響,因此同一份數據每一輪的模型最優參數解都不同),題目所給的模型是一個離散而分類模型,離散表明着模型的最優解是有一個區間的,最優解並不惟一(例如v取1.5和v取1.2都是等價的)。咱們遍歷【-0.5,0.5,1.5,2.5,3.5,4.5,5.5,6.5,7.5,8.5,9.5,10.5】比較模型偏差率最小的模型內部參數,通過計算可得,對於m=1,在權值分佈爲D1(10個數據,每一個數據的權值皆初始化爲0.1)的訓練數據上

  1. 閾值v取2.5時偏差率爲0.3(x < 2.5時取1,x > 2.5時取-1,則6 7 8分錯,偏差率爲0.3),
  2. 閾值v取5.5時偏差率最低爲0.4(x < 5.5時取1,x > 5.5時取-1,則3 4 5 6 7 8皆分錯,偏差率0.6大於0.5,不可取。故令x > 5.5時取1,x < 5.5時取-1,則0 1 2 9分錯,偏差率爲0.4),
  3. 閾值v取8.5時偏差率爲0.3(x < 8.5時取1,x > 8.5時取-1,則3 4 5分錯,偏差率爲0.3)。
  4. ...其餘類推可本身計算

能夠看到,不管閾值v取2.5,仍是8.5,總得分錯3個樣本,故可任取其中任意一個如2.5,弄成第一個基本分類器爲:

從而獲得G1(x)在訓練數據集上的偏差率(被G1(x)誤分類樣本「6 7 8」的權值之和)e1=P(G1(xi)≠yi) = 3*0.1 = 0.3

而後根據偏差率e1計算G1的係數:

接着更新訓練數據的權值分佈,用於下一輪迭代:

第一輪迭代後,最後獲得各個數據的權值分佈D2 = (0.0715, 0.0715, 0.0715, 0.0715, 0.0715,  0.0715, 0.1666, 0.1666, 0.1666, 0.0715)。由此能夠看出

1. 由於樣本中是數據「6 7 8」被G1(x)分錯了,因此它們的權值由以前的0.1增大到0.1666
2. 反之,其它數據皆被分正確,因此它們的權值皆由以前的0.1減少到0.0715

分類函數f1(x)= a1*G1(x) = 0.4236G1(x)

從上述第一輪的整個迭代過程能夠看出:被誤分類樣本的權值之和影響偏差率,偏差率影響基本分類器在最終分類器中所佔的權重,每輪被誤分類的樣本的調整幅度是一致的。

2. 迭代過程 m = 2

對於m=2,在權值分佈爲D2 = (0.0715, 0.0715, 0.0715, 0.0715, 0.0715,  0.0715, 0.1666, 0.1666, 0.1666, 0.0715)的訓練數據上,通過計算可得:

  1. 閾值v取2.5時偏差率爲0.1666*3(x < 2.5時取1,x > 2.5時取-1,則6 7 8分錯,偏差率爲0.1666*3),
  2. 閾值v取5.5時偏差率最低爲0.0715*4(x > 5.5時取1,x < 5.5時取-1,則0 1 2 9分錯,偏差率爲0.0715*3 + 0.0715),
  3. 閾值v取8.5時偏差率爲0.0715*3(x < 8.5時取1,x > 8.5時取-1,則3 4 5分錯,偏差率爲0.0715*3)

因此,閾值v取8.5時偏差率最低,故第二個基本分類器爲:

G2(x)把樣本「3 4 5」分錯了,根據D2可知它們的權值爲0.0715, 0.0715,  0.0715,因此G2(x)在訓練數據集上的偏差率e2=P(G2(xi)≠yi) = 0.0715 * 3 = 0.2143。

計算G2的係數:

更新訓練數據的權值分佈:

D3 = (0.0455, 0.0455, 0.0455, 0.1667, 0.1667,  0.01667, 0.1060, 0.1060, 0.1060, 0.0455)。被分錯的樣本「3 4 5」的權值變大,其它被分對的樣本的權值變小

f2(x)=0.4236G1(x) + 0.6496G2(x)

3. 迭代過程 m = 3

對於m=3,在權值分佈爲D3 = (0.0455, 0.0455, 0.0455, 0.1667, 0.1667,  0.01667, 0.1060, 0.1060, 0.1060, 0.0455)的訓練數據上,通過計算可得:

  1. 閾值v取2.5時偏差率爲0.1060*3(x < 2.5時取1,x > 2.5時取-1,則6 7 8分錯,偏差率爲0.1060*3),
  2. 閾值v取5.5時偏差率最低爲0.0455*4(x > 5.5時取1,x < 5.5時取-1,則0 1 2 9分錯,偏差率爲0.0455*3 + 0.0715),
  3. 閾值v取8.5時偏差率爲0.1667*3(x < 8.5時取1,x > 8.5時取-1,則3 4 5分錯,偏差率爲0.1667*3)

因此閾值v取5.5時偏差率最低,故第三個基本分類器爲:

此時,被誤分類的樣本是:0 1 2 9,這4個樣本所對應的權值皆爲0.0455,因此G3(x)在訓練數據集上的權重偏差率e3 = P(G3(xi)≠yi) = 0.0455*4 = 0.1820

計算G3的係數:

更新訓練數據的權值分佈:D4 = (0.125, 0.125, 0.125, 0.102, 0.102,  0.102, 0.065, 0.065, 0.065, 0.125)。被分錯的樣本「0 1 2 9」的權值變大,其它被分對的樣本的權值變小

f3(x)=0.4236G1(x) + 0.6496G2(x)+0.7514G3(x)

此時,獲得的第三個基本分類器sign(f3(x))在訓練數據集上有0個誤分類點。至此,整個訓練過程結束

從上述過程當中能夠發現:若是某些個樣本被分錯,它們在下一輪迭代中的權值將被增大(讓模型傾向於在下一輪把這些樣本點分對),同時,其它被分對的樣本在下一輪迭代中的權值將被減少。就這樣,分錯樣本權值增大,分對樣本權值變小,而在下一輪迭代中,老是選取讓偏差率最低的閾值來設計基本分類器,因此每輪的偏差率e(全部被Gm(x)誤分類樣本的權值之和)不斷下降。看起來就是最終線性模型組合的整體偏差率在每一輪的訓練中不斷下降

綜上,將上面計算獲得的a一、a二、a3各值代入G(x)中,G(x) = sign[f3(x)] = sign[ a1 * G1(x) + a2 * G2(x) + a3 * G3(x) ],獲得最終的分類器爲:

G(x) = sign[f3(x)] = sign[ 0.4236G1(x) + 0.6496G2(x)+0.7514G3(x) ]

能夠看到,每一輪迭代中閾值的選擇是經過一個相似learning rate的學習率,能夠理解爲步長,去限制弱學習器的迭代次數

(scikitlearn的AdaBoostClassifier 中的learning_rate參數)

書中例子只有一個變量x,所以梯度爲1能夠忽略,可當作在原數據上學習率(步長)爲0.5,去進行弱分類器的迭代,一次單變量的梯度下learning rate看起來和for循環遍歷形式上是同樣的

....
n_step = 0.5
features_min = min(features)
features_max = max(features)
# 步長
n_step = (features_max - features_min + self.learning_rate) // self.learning_rate

for i in range(1, int(n_step)):
        v = features_min + self.learning_rate * i
        # 加入條件:閾值與數據點不重合   
        if v not in features:
            # 誤分類計算
            ....

0x4: 前向分佈算法與AdaBoost的關係

在前面的章節中,咱們討論了加法模型(aditive model)與它的一個最優解近似求解算法前向分步算法。其實本質上說,AdaBoost還有另一種解釋,便可以認爲:

AdaBoost是模型爲加法模型、損失函數爲指數函數、學習算法爲前向分步算法的二類分類學習方法,AdaBoost算法就是前向分步算法的一個特例

AdaBoost中,各個基本分類器就至關於加法模型中的基函數,且其損失函數爲指數函數

換句話說,當前向分步算法中的基函數爲Adaboost中的基本分類器時,加法模型等價於Adaboost的最終分類器

Relevant Link:

http://blog.csdn.net/v_july_v/article/details/40718799
http://blog.csdn.net/dark_scope/article/details/14103983 
https://www.zhihu.com/question/65357931
http://blog.csdn.net/v_july_v/article/details/40718799 

 

4. 提高樹(GBDT Gradient Boostring Decision Tree)

提高樹是一種以分類樹或迴歸樹爲基本分類器的提高方法

0x1: 提高樹模型

提高樹實際採用加法模型(基函數的線性組合)與前向分步算法。以決策樹爲基函數的提高方法稱爲提高樹(boosting tree),對二分類問題決策樹是二叉樹,對迴歸問題決策樹是二叉迴歸樹。提高樹模型能夠表示爲決策樹的加法模型,其中表示決策樹;表示決策樹內部參數(選哪一個特徵做爲切分點;閾值多少);M 爲整個模型的個數

0x2: 提高樹算法

提高樹算法採用前向分步算法,首先肯定初始提高樹,第m步的模型是:,其中爲上一輪訓練獲得的單個基本分類器,經過經驗風險極小化肯定下一棵決策樹的參數

若是抽象來看,把每一個基分類器的權重機率看做模型的參數,即每一輪的模型都接收上一步模型的參數做爲輸入,這一點很像深度神經網絡的層一層之間的關係。
區別在於Boosting方法每輪獲得的模型參數在輸入下一輪迭代時是固定不變的,在每輪跌倒之間變更的只有:1)數據的機率權重;及2)模型的決策權重,而DNN會在每輪迭代中不斷調整模型自身內部的全部神經元(對應基分類器)的內部參數。
打個不巧當的比喻:DNN堅信本身就是最棒的,不斷提高本身。而Boostring認爲衆人拾柴火焰高,一我的不行咱們就用祖父子->祖父子代代之間不斷去優化,而後你們一塊兒來參與決策

因爲樹的線性組合能夠很好地擬合訓練數據中存在的機率規則分佈(多是多峯的),即便數據中的輸入與輸出之間的關係很複雜也是如此,因此提高樹是一個高效地學習算法。

下面討論針對不一樣問題的提高樹學習算法,其主要區別在於使用的損失函數不一樣:

1)用平方偏差損失函數的迴歸問題:用平方偏差求導更平滑可微;

2)用指數損失函數的分類問題;

3)用通常損失函數的通常決策問題;

1. 二分類問題提高樹

對於二分類問題,提高樹算法只須要將AdaBoost算法中的基本分類器(階躍分類器)限制爲二類分類樹便可,能夠說這時的提高樹算法是AdaBoost算法的特殊狀況

這裏插一句:前面例子中看到的基本分類器 x < v 或 x > v,能夠看做是由一個根節點直接鏈接的兩個葉節點的簡單決策樹,即所謂的決策樹樁(decision stump)

2. 迴歸問題的提高樹

已知一個訓練數據集爲輸入空間,爲輸出空間。若是將輸入空間劃分爲 J 個互不相交的區域 R1,R2,...,Rj,而且在每一個區域上肯定輸出的常量Cj(連續區間的離散採樣值),那麼樹能夠表示爲:,其中,參數 表示樹的區域劃分和各區域上的常數。J 是迴歸樹的複雜度即葉節點個數(採樣粒度)

迴歸問題提高樹使用如下前向分步算法:

在前向分步算法的第 m 步,給定當前模型 (上一輪訓練獲得的模型),需求解,獲得,即第 m 棵樹的參數

當採用平方偏差損失函數時,,其損失變爲:

這裏,是當前模型擬合訓練數據的殘差(residual),因此,對迴歸問題的提高樹算法來講,只需簡單地擬合當前模型的殘差便可。算法流程以下

(1) 初始化

(2)對 m = 1,2,...,M,M表明該加法模型總共有M個基本模型進行線性組合,在每一輪的訓練中都進行以下步驟

  (a)計算殘差

  (b)擬合殘差(殘差最小化)學習一個迴歸樹,獲得

  (c)更新

(3)獲得迴歸問題提高樹:

0x3: 提高樹算法的一個例子

來一步步推導下書上的例子加深理解和印象

1. 第一次迭代 m = 1

對第一次迭代來講,提高樹輸入的是原始數據,殘差等於原始樣本輸入

即迴歸樹。首先經過如下優化問題:求解訓練數據的切分點s:

容易求得在R1,R2內部使平方偏差達到最小的C1,C2爲:(離散採樣點取子集的均值可使得平方偏差最小),這裏N1,N2是R1,R2的樣本個數

每一輪迭代訓練中要計算的就是訓練數據的切分點,這裏能夠採起遍歷全部可能值的策略求得最優切分點s,s及m(s)的計算結果以下

可知當s = 6.5時m(s)達到最小值,此時,全部迴歸樹爲:

擬合訓練數據的殘差用於輸入下一輪迭代訓練(從第二輪開始模型的輸入就是殘差了,這是GBDT區別於普通迴歸決策樹的一個區別)以下表所示

擬合訓練數據的平方損失偏差:

仔細看這個結果,咱們會發現:從第二輪開始,輸入下一輪的就再也不是原始數據,而是數據的「離心距離」,即距離最佳分類面的距離。

2. 第二次迭代 m = 2

提高樹和AdaBoost的核心思想是同樣的,即:分而治之,每一輪迭代的「誤報量」會被傳遞到下一輪,在下一輪的迭代中經過調整基本函數內部參數對那部分「誤報量「進行重點解決

在AdaBoost中,上一輪誤報的樣本點會在下一輪按照必定的比例被提升權重,而在提高樹中。這種思想經過殘差得以體現,上一輪分類錯誤的殘差被做爲樣本點傳入進行模型訓練,這一輪的目的就是盡力消弭這部分殘差

這一輪的訓練樣本是上一輪的殘差

經過遍歷全部可能分界點s,能夠獲得:,-0.5二、0.22分別是左右分類子集的均值(知足平方偏差最小)

至此,兩個不等式線性相加的結果

注意到這裏和普通迴歸決策樹的不一樣:GBDT每一輪獲得的基分類器線性組合都同時包括此前的基分類器結果以及本輪的訓練擬合結果,而普通迴歸決策樹每輪迭代獲得的區間基分類器都僅僅取決於原是樣本

擬合原始訓練數據的平方損失偏差是:(比第一輪的損失函數在降低)

# -*- coding:utf-8 -*-

import math

def f2_fuc(x):
    if x < 3.5:
        return 5.72
    elif x < 6.5:
        return 6.46
    else:
        return 9.13

if __name__ == "__main__":
    loss = 0
    train_data = {
        1: 5.56,
        2: 5.7,
        3: 5.91,
        4: 6.4,
        5: 6.8,
        6: 7.05,
        7: 8.9,
        8: 8.7,
        9: 9.0,
        10: 9.05
    }
    for i in train_data:
        loss += (train_data[i] - f2_fuc(i)) ** 2

    print loss

3. 繼續往下迭代

擬合原始訓練數據的平方損失偏差是:

假設此時已經知足中止條件,則即爲所求提高樹(它的區間離散採樣值是由多課決策樹線性組合而成決定的)

0x4: 更加general泛化的殘差求解方式 - 梯度提高

提高樹利用加法模型與前向分步算法實現學習的優化過程。當損失函數是平方損失和指數損失函數時,每一步優化是相對簡單的(咱們均可以經過求導獲得最佳離散化採樣值c1/c2),但對通常泛化的損失函數而言,每每每一步的優化並不容易(針對連續迴歸函數的複雜函數的擬合場景)。針對這一問題,Freidman提出了梯度提高(gradient boosting)算法,梯度提高的關鍵是利用損失函數的負梯度(負導數) 做爲迴歸問題提高樹算法中的殘差的近似值(負梯度一樣體現了該區間內樣本數據和最佳分界面的「離心程度」),擬合一個迴歸樹

(1)初始化:

(2)對 m = 1,2,...,M,M表明該加法模型總共有M個基本模型進行線性組合,在每一輪的訓練中都進行以下步驟

  (a)對 i = 1,2,...,N(N個樣本),計算:(計算損失函數的負梯度在當前模型的值,將它做爲殘差的估計,對於平方損失函數它就是殘差;對於通常的損失函數,它就是殘差的近似值)

  (b)對擬合一個迴歸樹,獲得第 m 棵樹的葉節點區域,j = 1,2,...,J(葉節點不必定等於2)

  (c)對 j = 1,2,...,J,計算(利用線性搜索估計葉節點區域的值,尋找使得偏差梯度最小的離散採樣值c)

  (d)更新 (每一個基本函數由該棵樹的全部葉節點的離散採樣值組成)

(3)獲得迴歸樹:

Relevant Link:

https://www.zhihu.com/question/60625492/answer/200165954
http://www.jianshu.com/p/005a4e6ac775

 

5. xgboost(Scalable and Flexible Gradient Boosting)

0x1:用一個圖例說明XGboost模型

咱們用一個簡單的例子來引入對Xgboost的討論,咱們的目標是根據一些屬性特性,判斷一個家庭裏的成員是否喜歡玩電腦遊戲

1. 單個CART樹的預測

能夠看到,CART樹和decision tree有一些不一樣,CART樹的葉節點對應的是一個分值,而不像分類決策樹是一個肯定的類別,CART樹的這個分值咱們能夠理解爲權重

2. 兩個CART樹的線性加和組合

簡單來講,xgboost對應的模型就是一堆CART樹的線性組合,和GBDT同樣,XGBoost將每棵樹的預測值加到一塊兒做爲最終的預測值

第二圖的底部說明了如何用一堆CART樹作預測,就是基於「addive model加法線性模型」的思想,將各個樹的預測分數相加 。經過這種多基分類器加和(相似DNND中的多神經元)綜合判斷的方式,各個基模型互相補充,實現對多峯機率分佈的擬合。這也體現了ensemble learning集成學習的思想

0x2:XGBoost數學模型

咱們用數學來準確地表示這個模型:

這裏的K就是樹的棵數,F表示全部可能的CART樹,f表示一棵具體的CART樹。這個模型由K棵CART樹組成。

模型的目標函數以下:

這個目標函數一樣包含兩部分

1. 第一部分就是損失函數:MSE或指數損失(例如交叉熵損失)
2. 第二部分就是正則項,這裏的正則化項由K棵樹的正則化項相加而來,體現了總體模型的複雜度

咱們但願XGBoost獲得的是一個: simple and predictive model

0x3:XGBoost模型訓練策略 - 前向分步策略(逐輪加法訓練)

幾乎對於全部的有監督機器學習模型來講,訓練過程就是找到一個目標函數,而後優化求導求極值。

可是XGBoost的模型:是由K棵樹以及每棵樹中的全部葉節點值組成的加法模型,要對其進行全局求導;或者是進行梯度降低都是很困難的,或者說在計算上很是複雜。

解決這個問題,咱們可使用「加法訓練」,即咱們一次只訓練一棵樹,同時把上一輪獲得的全部ensemble tree結果做爲本輪的輸入:

在第t步時,咱們添加了一棵最優的CART樹ft,這棵最優的CART樹ft是怎麼得來的呢?就是在現有的t-1棵樹的基礎上,使得目標函數最小的那棵CART樹,以下圖所示:

假如咱們使用的損失函數時MSE,那麼上述表達式會變成這個樣子:

這個式子很是漂亮,由於它含有ft(xi)的一次式和二次式,並且一次式項的係數是殘差。注意:這裏模型的參數 ft(xi) 就是CART樹葉子結點的值

可是對於其餘的損失函數(指數損失和通常損失),咱們未必能得出如此漂亮的式子,因此,對於通常的損失函數,咱們須要將其做泰勒二階展開,以下所示: 

其中:

在這個公式中,constant表明的 t -1 棵樹的正則化項;l(yi, yi^t-1)也是常數項;剩下的三個變量項分別是第t棵CART樹的一次式,二次式;和整棵樹的正則化項。

咱們的目標在在這輪迭代中,讓目標函數最小化,因此能夠把常數項去掉,公式整理後以下:

obj*表明了什麼呢?它表示了這棵樹的結構有多好,值越小,表明這樣結構越好!也就是說,它是衡量第t棵CART樹的結構好壞的標準。這個值僅僅是用來衡量結構的好壞的,與葉子節點的值但是無關的。以下圖所示:

有了評判樹的結構好壞的標準,咱們就能夠先求最佳的樹結構,這個定出來後,最佳的葉子結點的值實際上在上面已經求出來了(模型的參數也就獲得了)。

問題是:樹的結構近乎無限多,一個一個去測算它們的好壞程度,而後再取最好的顯然是不現實的。因此,咱們仍然須要採起 「逐輪迭代漸進逼近全局最優策略」,咱們 每次只優化一層的樹結點,獲得在這層裏最優的樹結構,即找到一個最優的切分點,使得切分後的Gain最大(和決策樹的基尼指數求解最優分界面的思想是一致的)。
掃描結束後,咱們就能夠肯定是否切分,若是切分,對切分出來的兩個節點,遞歸地調用這個切分過程,咱們就能得到一個相對較好的樹結構。

咱們以上文提到過的判斷一我的是否喜歡計算機遊戲爲例子。最簡單的樹結構就是一個節點的樹。咱們能夠算出這棵單節點的樹的好壞程度obj*。假設咱們如今想按照年齡將這棵單節點樹進行分叉,咱們須要知道:

1、按照年齡分是否有效,也就是是否減小了obj的值
2、若是可分,那麼以哪一個年齡值來分。

爲了回答上面兩個問題,咱們能夠將這一家五口人按照年齡作個排序。以下圖所示:

這個Gain實際上就是單節點的obj*減去切分後的兩個節點的樹obj*,Gain若是是正的,而且值越大,表示切分後obj*越小於單節點的obj*,就越值得切分。

同時,咱們還能夠觀察到,Gain的左半部分若是小於右側的,則Gain就是負的,代表切分後obj反而變大了。

在這裏其實是一個臨界值,它的值越大,表示咱們對切分後obj降低幅度要求越嚴。這個值也是能夠在xgboost中設定的。這個實際在本質上就起到了剪枝限制的做用,這也是XGboost和決策樹的一個不一樣點:普通的決策樹在切分的時候並不考慮樹的複雜度,而依賴後續的剪枝操做來控制。xgboost在切分的時候就已經考慮了樹的複雜度,就是那個參數。因此,它不須要進行單獨的剪枝操做

0x4:XGboost的優勢

從這個目標函數能夠看出XGBoost的優勢之處:

1. 目標函數中的一次式,二次式的係數是 gi 和 hi,而 gi 和 hi 是彼此獨立的,能夠並行的計算,這帶來了計算速度上的併發優點
2. 並且,gi 和 hi是不依賴於損失函數的形式,只要這個損失函數是二次可微便可,因此 XGBoost能夠自定義損失函數
Relevant Link:

https://www.jianshu.com/p/7467e616f227 
https://homes.cs.washington.edu/~tqchen/pdf/BoostedTree.pdf
https://xgboost.readthedocs.io/en/latest/model.html
https://www.cnblogs.com/csyuan/p/6537255.html 
http://blog.csdn.net/a819825294/article/details/51206410
http://blog.csdn.net/sb19931201/article/details/52557382
http://blog.csdn.net/github_38414650/article/details/76061893

Copyright (c) 2018 LittleHann All rights reserved

相關文章
相關標籤/搜索