機器學習--集成學習AdaBoost

Boosting概念

提升學習(Boosting)是一種機器學習技術,可以用於迴歸和分類的問題,它也是多個弱學習器組合而成,但是跟bagging不同的是,bagging的學習器是相互獨立的,但是boosting的每個學習器是基於前面的學習器生成的。

AdaBoost

它給樣本加了一個權重,如果前面的學習器已經能把樣本分對,那麼權重會降低,如果不能分對就會把權重升高,更着重的去考慮分錯的樣本,然後把多個弱學習器組合形成一個強學習器。

AdaBoost算法推導

最終的增強學習器是:

G(x)=sign(f(x))=sign[m=1MαmGm(x)]

其中sign是一個-1/1的函數,如果sign(x),x>0則sign(x)預測爲1(正樣本),x<0則預測爲-1(負樣本),αm 是每個分類器的權重值,一共有M個分類器。

損失函數:

loss=1ni=1nI(G(xi)yi)

I 函數是如果分對則爲0,如果分錯則爲1,損失函數可以直觀的理解成錯誤率,分錯的樣本佔總樣本的比例。

損失函數變換:

loss=1nni=1I(G(xi)yi) 不利於作數學運算,轉化成具有相同性質易於作數學運算的形式:

loss=1ni=1neyif(x)

yi 如果整理是1,負例是-1,可以看到如果分類正確,yif(x) 會是一個比較大的負數,則eyif(x) 比較接近於0,如果分類錯誤則是一個正數,與I函數的性質相似。

求每個分類器的權重αm

假設已經進行到k-1輪,這時候學習器是:

fk1(x)=j=1k1αjGj(x)

這時候第k輪的學習器應該是:
fk(x)=j=1k1αjGj(x)+αkGk(x)=fk1(x)+αkGk(x)

損失函數應該是:
loss=1ni=1neyi(fk1(x)+αkGk(x))

可以拆分爲:
loss=1ni=1neyifk1(x)eyiαkGk(x)

前面的部分是一個常數,前面的學習器組合而成,寫成E。後面的部分重新寫會成I 函數,然後可以變成:
loss=eαm(1ϵt)+eαmϵt

ϵt 是當前的錯誤率,對αm 求偏導,令偏導數它等於0可以得到:
αm=12ln(1ϵtϵt)

得到第m個學習器。

構建過程:

1、平均分配每個樣本的權重
2、構建當前的分類器,計算誤差,通過αm=12ln(1ϵtϵt) ,得到當前分類器的權重。
3、根據αm 去跟新權重,更多的考慮分錯的項。

wm+1,i=wm,iZmeαmyiGm(xi)

其中Zm 是歸一化因子。
4、重複執行過程直到錯誤率低於一定值或者跌代次數達到一定值。

樣例:

製作虛擬數據:

import pandas as pd
import numpy as np

x = np.arange(0,10).reshape(1,-1)
y = np.array([1,1,1,-1,-1,-1,1,1,1,-1]).reshape(1,-1)
z = np.array([1/10]*10).reshape(1,-1)
data = np.concatenate((x,y,z),axis=0)
df = pd.DataFrame(data,index=['data','label','weight'])
df

這裏寫圖片描述

# 假設用決策樹的方法,用信息熵的衡量標準去構建決策樹

# 計算信息熵的函數
def h(p_list):
    return np.sum([-p*np.log2(p) for p in p_list])

# 找到信息增益最大的點,也就是條件熵最小的點:

# 在2.5處的條件熵:
Ht2_5 = h([3/7,4/7]) * 7 / 10  # 0.68965969522397608
# 在5.5處的條件熵:
Ht5_5 = h([0.5,0.5]) * 6 / 10 + h([1/4, 3/4]) * 4 / 10 # 0.92451124978365318
# 所以在2.5處劃分。

# 計算誤差率:(有三個分錯,權重都是0.1) : 0.3

# 根據誤差率,計算alpha的值
def g(e):
    return 0.5 * np.log2((1-e)/e)

a1 = g(0.3) #0.61119621066822405

# 跟新權重 
def update_weight(w, result, alpha):
    z_m = 0
    for i in range(w.shape[1]):
        z_m += w[0][i] * np.exp(- alpha * result[0][i])
    w_new = w * np.exp(- result * alpha) / z_m
    return w_new

result = np.array([1,1,1,1,1,1,-1,-1,-1,1]).reshape(1,-1)
w = np.array(df.ix[[2]])
w_new = update_weight(w, result, a1)
print(w_new)

# [[ 0.05818722  0.05818722  0.05818722  0.05818722  0.05818722  0.05818722
# 0.19756314  0.19756314  0.19756314  0.05818722]]

# 可以看到,誤分類的點權重加大了,正確分類的點,權重減小了。更加着重的去考慮錯誤分類的點。

最後的結果:

f(x)=0.6112G1(x)+1.1205G2(x)+1.631G3(x)

這裏寫圖片描述
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章