鏈接:
1. 線性回歸總結
2. 正則化
3. 邏輯回歸
4. Boosting
5. Adaboost算法
模型來源
提升算法是常用的有效的統計學習算法,屬于迭代算法,它通過不斷地使用一個弱學習器彌補前一個弱學習器的“不足”的過程,來串行地構造一個較強的學習器,這個強學習器能夠使目標函數值足夠小。從優化的角度分析,與一般的在參數空間搜索最優解的學習算法(如神經網絡)類似,Boosting也是一個迭代搜索,且最優的算法,不同的是,它的搜索空間是學習器空間,或說函數空間(Function space),它的搜索方向是構造不斷完善的強學習器,以達到目標函數(或說誤差函數)足夠小的目的。 Bagging也是一種常用的統計學習方法,兩者經常放在一起對比,它們不同的是,Bagging將在Bootstrap采樣得到的不同訓練子集上的弱學習器的結果綜合考慮,各個弱學習器的構建過程是并行的。而Boosting是通過串行地不斷迭加弱學習器形成一個強學習器,是學習模型的提升過程。此外,Boosting迭代在降低訓練誤差的同時,使模型預測的確信度(margin)不斷提高,是它獲得較好泛化能力的主要原因,而Bagging主要是通過平均來降低模型的方差(variation).
example
為說明Boosting的主要過程,下面舉一個簡化的例子。 假設訓練數據集為(x1,y1),(x2,y2),...,(xn,yn)我們的任務是尋找使這個回歸問題的均方誤差最小的模型F(x). 如果已經有一個初始的模型f,且f(x1)=0.8,但y1=0.9 ,f(x2)=1.4,但y2=1.3 …顯然f是不完美的,我們可以采用不斷完善f的方式,如不斷在f的基礎上增加模型(如決策樹)h,即:f(x)←f(x)+h(x),使f 趨于F. 我們希望:
f(x1)+h(x1)=y1 ====> h(x1)=y1?f(x1)
f(x2)+h(x2)=y2 ====> h(x2)=y2?f(x2)
... ====> ...
f(xn)+h(xn)=yn ====> h(xn)=yn?f(xn)
然而恰好滿足上式的h可能不存在,但我們總可以找到使殘差yi?f(xi)變小的h. 上述過程等價于擬合如下數據集:
(x1,y1?f(x1))
(x2,y2?f(x2))
...
(xn,yn?f(xn))
上述一次疊加h的過程就是Boosting的一次迭代。要使f足夠接近F一般需要多次迭代。
依據損失函數的不同具體分類有:
鏈接:關于AdaBoost的算法推導
Gradient Boosting
和Adaboost不同,Gradient Boosting 在迭代的時候選擇梯度下降的方向來保證最后的結果最好。
損失函數用來描述模型的“靠譜”程度,假設模型沒有過擬合,損失函數越大,模型的錯誤率越高
如果我們的模型能夠讓損失函數持續的下降,則說明我們的模型在不停的改進,而最好的方式就是讓損失函數在其梯度方向上下降。
import numpy as np
import matplotlib.pyplot as plt
from sklearn import ensemble
from sklearn import datasets
from sklearn.utils import shuffle
from sklearn.metrics import mean_squared_error
#########################################
# Load data
boston = datasets.load_boston()
X, y = shuffle(boston.data, boston.target, random_state=13)
X = X.astype(np.float32)
offset = int(X.shape[0] * 0.9)
X_train, y_train = X[:offset], y[:offset]
X_test, y_test = X[offset:], y[offset:]
########################################
# Fit regression model
params = {'n_estimators': 500, 'max_depth': 4, 'min_samples_split': 1,
'learning_rate': 0.01, 'loss': 'ls'}
clf = ensemble.GradientBoostingRegressor(**params)
clf.fit(X_train, y_train)
mse = mean_squared_error(y_test, clf.predict(X_test))
print("MSE: %.4f" % mse)
Adaboost
Adaboost 迭代算法就3步:
- 初始化訓練數據的權值分布。如果有N個樣本,則每一個訓練樣本最開始時都被賦予相同的權值:1/N。
- 訓練弱分類器。具體訓練過程中,如果某個樣本點已經被準確地分類,那么在構造下一個訓練集中,它的權值就被降低;相反,如果某個樣本點沒有被準確地分類,那么它的權值就得到提高。然后,權值更新過的樣本集被用于訓練下一個分類器,整個訓練過程如此迭代地進行下去。
- 將各個訓練得到的弱分類器組合成強分類器。各個弱分類器的訓練過程結束后,加大分類誤差率小的弱分類器的權重,使其在最終的分類函數中起著較大的決定作用, 而降低分類誤差率大的弱分類器的權重,使其在最終的分類函數中起著較小的決定作用。換言之,誤差率低的弱分類器在最終分類器中占的權重較大,否則較小。
給定一個訓練數據集T={(x1,y1), (x2,y2)…(xN,yN)},yi屬于標記集合{-1,+1},Adaboost的目的就是從訓練數據中學習一系列弱分類器或基本分類器,然后將這些弱分類器組合成一個強分類器。
Adaboost的算法流程如下:
步驟1. 首先,初始化訓練數據的權值分布。每一個訓練樣本最開始時都被賦予相同的權值:1/N。
步驟2. 進行多輪迭代,用m = 1,2, ..., M表示迭代的第多少輪
a. 使用具有權值分布Dm的訓練數據集學習,得到基本分類器(選取讓誤差率最低的閾值來設計基本分類器):
b. 計算Gm(x)在訓練數據集上的分類誤差率
由上述式子可知,Gm(x)在訓練數據集上的誤差率em就是被Gm(x)誤分類樣本的權值之和。
c. 計算Gm(x)的系數,am表示Gm(x)在最終分類器中的重要程度(目的:得到基本分類器在最終分類器中所占的權重):
由上述式子可知,em <= 1/2時,am >= 0,且αm隨著em的減小而增大,意味著分類誤差率越小的基本分類器在最終分類器中的作用越大。
d. 更新訓練數據集的權值分布(目的:得到樣本的新的權值分布),用于下一輪迭代
使得被基本分類器Gm(x)誤分類樣本的權值增大,而被正確分類樣本的權值減小。就這樣,通過這樣的方式,AdaBoost方法能“重點關注”或“聚焦于”那些較難分的樣本上。
其中,Zm是規范化因子,使得Dm+1成為一個概率分布:
**步驟3. **組合各個弱分類器
從而得到最終分類器,如下:
#################################################
Adaboost的一個例子
下面,給定下列訓練樣本,請用AdaBoost算法學習一個強分類器。
求解過程:初始化訓練數據的權值分布,令每個權值W1i = 1/N = 0.1,其中,N = 10,i = 1,2, ..., 10,然后分別對于m = 1,2,3, ...等值進行迭代。
拿到這10個數據的訓練樣本后,根據 X 和 Y 的對應關系,要把這10個數據分為兩類,一類是“1”,一類是“-1”,根據數據的特點發現:“0 1 2”這3個數據對應的類是“1”,“3 4 5”這3個數據對應的類是“-1”,“6 7 8”這3個數據對應的類是“1”,9是比較孤獨的,對應類“-1”。拋開孤獨的9不講,“0 1 2”、“3 4 5”、“6 7 8”這是3類不同的數據,分別對應的類是1、-1、1,直觀上推測可知,可以找到對應的數據分界點,比如2.5、5.5、8.5 將那幾類數據分成兩類。當然,這只是主觀臆測,下面實際計算下這個具體過程。
迭代過程1
對于m=1,在權值分布為D1(10個數據,每個數據的權值皆初始化為0.1)的訓練數據上,經過計算可得:
閾值v取2.5時誤差率為0.3(x < 2.5時取1,x > 2.5時取-1,則6 7 8分錯,誤差率為0.3),
閾值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),
閾值v取8.5時誤差率為0.3(x < 8.5時取1,x > 8.5時取-1,則3 4 5分錯,誤差率為0.3)。
可以看到,無論閾值v取2.5,還是8.5,總得分錯3個樣本,故可任取其中任意一個如2.5,弄成第一個基本分類器為:
上面說閾值v取2.5時則6 7 8分錯,所以誤差率為0.3,更加詳細的解釋是:因為樣本集中
0 1 2對應的類(Y)是1,因它們本身都小于2.5,所以被G1(x)分在了相應的類“1”中,分對了。
3 4 5本身對應的類(Y)是-1,因它們本身都大于2.5,所以被G1(x)分在了相應的類“-1”中,分對了。
但6 7 8本身對應類(Y)是1,卻因它們本身大于2.5而被G1(x)分在了類"-1"中,所以這3個樣本被分錯了。
9本身對應的類(Y)是-1,因它本身大于2.5,所以被G1(x)分在了相應的類“-1”中,分對了。
從而得到G1(x)在訓練數據集上的誤差率(被G1(x)誤分類樣本“6 7 8”的權值之和)e1=P(G1(xi)≠yi) = 30.1 = 0.3*。
然后根據誤差率e1計算G1的系數:
值得一提的是,由權值更新的公式可知,每個樣本的新權值是變大還是變小,取決于它是被分錯還是被分正確。
即如果某個樣本被分錯了,則yi * Gm(xi)為負,負負得正,結果使得整個式子變大(樣本權值變大),否則變小。
第一輪迭代后,最后得到各個數據新的權值分布D2= (0.0715, 0.0715, 0.0715, 0.0715, 0.0715, 0.0715,0.1666, 0.1666, 0.1666, 0.0715)。由此可以看出,因為樣本中是數據“6 7 8”被G1(x)分錯了,所以它們的權值由之前的0.1增大到0.1666,反之,其它數據皆被分正確,所以它們的權值皆由之前的0.1減小到0.0715。
分類函數f1(x)= a1G1(x) = 0.4236G1(x)。
此時,得到的第一個基本分類器sign(f1(x))在訓練數據集上有3個誤分類點(即6 7 8)。
從上述第一輪的整個迭代過程可以看出:被誤分類樣本的權值之和影響誤差率,誤差率影響基本分類器在最終分類器中所占的權重。
迭代過程2
對于m=2,在權值分布為D2 = (0.0715, 0.0715, 0.0715, 0.0715, 0.0715, 0.0715, 0.1666, 0.1666, 0.1666, 0.0715)的訓練數據上,經過計算可得:
閾值v取2.5時誤差率為0.16663(x < 2.5時取1,x > 2.5時取-1,則6 7 8分錯,誤差率為0.16663),
閾值v取5.5時誤差率最低為0.07154(x > 5.5時取1,x < 5.5時取-1,則0 1 2 9分錯,誤差率為0.07153 + 0.0715),
閾值v取8.5時誤差率為0.07153(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)此時,得到的第二個基本分類器sign(f2(x))在訓練數據集上有3個誤分類點(即3 4 5)。
迭代過程3
對于m=3,在權值分布為D3 = (0.0455, 0.0455, 0.0455, 0.1667, 0.1667, 0.01667, 0.1060, 0.1060, 0.1060, 0.0455)的訓練數據上,經過計算可得:
閾值v取2.5時誤差率為0.10603(x < 2.5時取1,x > 2.5時取-1,則6 7 8分錯,誤差率為0.10603),
閾值v取5.5時誤差率最低為0.04554(x > 5.5時取1,x < 5.5時取-1,則0 1 2 9分錯,誤差率為0.04553 + 0.0715),
閾值v取8.5時誤差率為0.16673(x < 8.5時取1,x > 8.5時取-1,則3 4 5分錯,誤差率為0.16673)。
所以閾值v取5.5時誤差率最低,故第三個基本分類器為:
依然還是原樣本:
此時,被誤分類的樣本是:0 1 2 9,這4個樣本所對應的權值皆為0.0455,
所以G3(x)在訓練數據集上的誤差率e3= P(G3(xi)≠yi) = 0.04554* = 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個誤分類點。至此,整個訓練過程結束。
現在,咱們來總結下3輪迭代下來,各個樣本權值和誤差率的變化,如下所示(其中,樣本權值D中加了下劃線的表示在上一輪中被分錯的樣本的新權值):
訓練之前,各個樣本的權值被初始化為D1 = (0.1, 0.1,0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1);
第一輪迭代中,樣本“6 7 8”被分錯,對應的誤差率為e1=P(G1(xi)≠yi) = 3*0.1 = 0.3,此第一個基本分類器在最終的分類器中所占的權重為a1 = 0.4236。第一輪迭代過后,樣本新的權值為D2= (0.0715, 0.0715, 0.0715, 0.0715, 0.0715, 0.0715, 0.1666, 0.1666, 0.1666, 0.0715);
第二輪迭代中,樣本“3 4 5”被分錯,對應的誤差率為e2=P(G2(xi)≠yi) = 0.0715 * 3 = 0.2143,此第二個基本分類器在最終的分類器中所占的權重為a2 = 0.6496。第二輪迭代過后,樣本新的權值為D3 = (0.0455, 0.0455, 0.0455, 0.1667, 0.1667, 0.01667, 0.1060, 0.1060, 0.1060, 0.0455);
第三輪迭代中,樣本“0 1 2 9”被分錯,對應的誤差率為e3= P(G3(xi)≠yi) = 0.04554 = 0.1820,此第三個基本分類器在最終的分類器中所占的權重為a3* = 0.7514。第三輪迭代過后,樣本新的權值為**D4 **= (0.125, 0.125, 0.125, 0.102, 0.102, 0.102, 0.065, 0.065, 0.065, 0.125)。
從上述過程中可以發現,如果某些個樣本被分錯,它們在下一輪迭代中的權值將被增大,反之,其它被分對的樣本在下一輪迭代中的權值將被減小。就這樣,分錯樣本權值增大,分對樣本權值變小,而在下一輪迭代中,總是選取讓誤差率最低的閾值來設計基本分類器,所以誤差率e(所有被Gm(x)誤分類樣本的權值之和)不斷降低。
綜上,將上面計算得到的a1、a2、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) ]。
2 Adaboost的誤差界
通過上面的例子可知,Adaboost在學習的過程中不斷減少訓練誤差e,直到各個弱分類器組合成最終分類器,那這個最終分類器的誤差界到底是多少呢?
事實上,Adaboost 最終分類器的訓練誤差的上界為:
下面,咱們來通過推導來證明下上述式子。
當G(xi)≠yi時,yif(xi)<0,因而exp(-yif(xi))≥1,因此前半部分得證。
關于后半部分,別忘了:
整個的推導過程如下:
這個結果說明,可以在每一輪選取適當的Gm使得Zm最小,從而使訓練誤差下降最快。接著,咱們來繼續求上述結果的上界。
對于二分類而言,有如下結果:
。
繼續證明下這個結論。
由之前Zm的定義式跟本節最開始得到的結論可知:
可先由e^x和1-x的開根號,在點x的泰勒展開式推出。
值得一提的是,如果取γ1, γ2… 的最小值,記做γ(顯然,γ≥γi>0,i=1,2,...m),則對于所有m,有:
這個結論表明,AdaBoost的訓練誤差是以指數速率下降的。另外,AdaBoost算法不需要事先知道下界γ,AdaBoost具有自適應性,它能適應弱分類器各自的訓練誤差率 。
最后,Adaboost 還有另外一種理解,即可以認為其模型是加法模型、損失函數為指數函數、學習算法為前向分步算法的二類分類學習方法