日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

Python实现Adaboost

發(fā)布時間:2023/12/18 python 54 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python实现Adaboost 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1.Adaboost概念

提升方法的思路是綜合多個分類器,得到更準(zhǔn)確的分類結(jié)果。 即“三個臭皮匠頂個諸葛亮”。《統(tǒng)計學(xué)習(xí)方法》稱AdaBoost是提升算法的代表,所謂提升算法,指的是一種常用的統(tǒng)計學(xué)習(xí)方法,應(yīng)用廣泛且有效。在分類問題中,它通過改變訓(xùn)練樣本的權(quán)重,學(xué)習(xí)多個分類器,并將這些分類器進(jìn)行線性組合,提髙分類的性能。
AdaBoost算法的基本思想:
1)多輪訓(xùn)練,多個分類器
2)每輪訓(xùn)練增加錯誤分類樣本的權(quán)值,降低正確分類樣本的權(quán)值
3)降低錯誤率高的分類器的權(quán)值,增加正確率高的分類器的權(quán)值

2.Adaboost算法流程

給定一個二類分類的訓(xùn)練數(shù)據(jù)集,T={(x1,y1),(x2,y2),…(xn,yn)}T=\{({x_1},y_1),({x_2},y_2),\dots({x_n},y_n)\}T={(x1?,y1?),(x2?,y2?),(xn?,yn?)},其中χi∈X?Rnχ_i∈X? R^nχi?X?Rn表示實例的特征向量,yi∈Y∈{+1,?1}y_i∈Y\in\{+1,-1\}yi?Y{+1,?1},XXX是實例空間,YYY是標(biāo)記集合。AdaBoost利用以下算法,從訓(xùn)練數(shù)據(jù)中學(xué)習(xí)一系列弱分類器或基本分類器,并將這些弱分類器線性組合成為一個強(qiáng)分類器。
AdaBoost算法
輸入:訓(xùn)練數(shù)據(jù)集T={(x1,y1),(x2,y2),…(xn,yn)}T=\{({x_1},y_1),({x_2},y_2),\dots({x_n},y_n)\}T={(x1?,y1?),(x2?,y2?),(xn?,yn?)},其中χi∈X?Rnχ_i∈X? R^nχi?X?Rn,yi∈Y∈{+1,?1}y_i∈Y\in\{+1,-1\}yi?Y{+1,?1};弱學(xué)習(xí)算法;
輸出:最終分類器G(x)G(x)G(x)
(1)初始化訓(xùn)練數(shù)據(jù)的權(quán)值分布

D1=(W11,...,W1i,...,W1n)D_1=(W_{11},...,W_{1i},...,W_{1n})D1?=(W11?,...,W1i?,...,W1n?)

每個w的下標(biāo)由兩部分構(gòu)成,前一個數(shù)表示當(dāng)前迭代次數(shù),與D的下標(biāo)保持一致,后一個數(shù)表示第幾個權(quán)值,與位置保持一致。初始情況下,每個權(quán)值都是均等的。
(2)對m=1,2,...Mm=1,2,...Mm=1,2,...M
(這里的M表示訓(xùn)練的迭代次數(shù),是由用戶指定的。每輪迭代產(chǎn)生一個分類器,最終就有M個分類器,當(dāng)然我們也可以設(shè)置一些條件,滿足某些條件時跳出迭代,例如,所有樣本都分對了,誤差為0時,跳出迭代):
(a)使用具有權(quán)值分布的訓(xùn)練數(shù)據(jù)集學(xué)習(xí),得到基本分類器

Gm(x):X→{+1,?1}G_m(x):X{\rightarrow} \{+1,-1\}Gm?(x):X{+1,?1}

(b)在Gm(x)G_m(x)Gm?(x)訓(xùn)練數(shù)據(jù)集上的分類誤差率

em=∑iNP(Gm(xi)≠yi)=∑iNwmiI(Gm(xi)≠yi))e_m=\sum_i^NP(G_m(x_i){\neq}y_i)=\sum_i^Nw_{mi}I(G_m(x_i){\neq}y_i))em?=iN?P(Gm?(xi?)??=yi?)=iN?wmi?I(Gm?(xi?)??=yi?))

分類誤差率這個名字可能產(chǎn)生誤解,這里其實是個加權(quán)和。
(c)計算Gm(x)G_m(x)Gm?(x)的系數(shù)

αm=12log1?emem\alpha_m = \frac{1}{2}log{\frac{1-e_m}{e_m}}αm?=21?logem?1?em??

這里的對數(shù)是自然對數(shù)。ama_mam?表示Gm(x)G_m(x)Gm?(x)在最終分類器中的重要性。由式αm=12log1?emem\alpha_m = \frac{1}{2}log{\frac{1-e_m}{e_m}}αm?=21?logem?1?em??可知,當(dāng)em&lt;=1/2e_m&lt;=1/2em?<=1/2時,am&gt;=0a_m&gt;=0am?>=0,并且ama_mam?隨著eme_mem?的減小而增大,所以分類誤差率越小的基本分類器在最終分類器中的作用越大。

(d)更新訓(xùn)練數(shù)據(jù)集的權(quán)值分布

Dm+1=(Wm+1,1,...,Wm+1,i,...,Wm+1,n)D_{m+1}=(W_{m+1,1},...,W_{m+1,i},...,W_{m+1,n})Dm+1?=(Wm+1,1?,...,Wm+1,i?,...,Wm+1,n?)

wm+1,i=wm,iZme?αmyiGm(xi)w_{m+1, i}=\frac{w_{m, i}}{Z_m}e^{-\alpha_my_iG_m(x_i)}wm+1,i?=Zm?wm,i??e?αm?yi?Gm?(xi?)

y只有正負(fù)一兩種取值,所以上式可以寫作:

wm+1,i={wmiZme?am,Gm(xi)=yiwmiZmeam,Gm(xi)≠yiw_{m+1,i}=\begin{cases} \frac{w_{mi}}{Z_m}e^{-a_m},G_m(x_i)=y_i \\ \frac{w_{mi}}{Z_m}e^{a_m},G_m(x_i){\neq}y_i \end{cases}wm+1,i?={Zm?wmi??e?am?,Gm?(xi?)=yi?Zm?wmi??eam?,Gm?(xi?)??=yi??

這里,ZmZ_mZm?是規(guī)范化因子

Zm=∑i=1Nwmiexp(?αmyiGm(xi))Z_m=\sum_{i=1}^Nw_{m i}exp({-\alpha_my_iG_m(x_i)})Zm?=i=1N?wmi?exp(?αm?yi?Gm?(xi?))

它使Dm+1D_{m+1}Dm+1?成為一個概率分布。
由此可知,被基本分類器誤分類樣本的權(quán)值得以擴(kuò)大,而被正確分類樣本的權(quán)值卻得以縮小。兩相比較,誤分類樣本的權(quán)值被放大e2am=1?ememe^{2am} = {\frac{1-e_m}{e_m}}e2am=em?1?em??倍。因此,誤分類樣本在下一輪學(xué)習(xí)中起更大的作用。不改變所給的訓(xùn)練數(shù)據(jù),而不斷改變訓(xùn)練數(shù)據(jù)權(quán)值的分布,使得訓(xùn)練數(shù)據(jù)在基本分類器的學(xué)習(xí)中起不同的作用,這是AdaBoost的一個特點(diǎn)。

(3)構(gòu)建基本分類器的線性組合:

f(x)=∑m=1MamGm(x)f(x)=\sum_{m=1}^{M}a_mG_m(x)f(x)=m=1M?am?Gm?(x)

得到最終分類器:

G(x)=sign(f(x))=sign(∑m=1MamGm(x))G(x)=sign(f(x))=sign(\sum_{m=1}^{M}a_mG_m(x))G(x)=sign(f(x))=sign(m=1M?am?Gm?(x))
這里需要注意的是,我們得到的是M個f(x)方程,需要將每個方程的結(jié)果求和,最好只取結(jié)果的正負(fù)號,在Adaboost中我們的預(yù)測結(jié)果與數(shù)值是無關(guān)的。

3.完整代碼

代碼運(yùn)行結(jié)果:

# -*- coding: utf-8 -*- """@Time : 2018/12/04 13:58@Author : hanzi5@Email : hanzi5@yeah.net@File : Adaboost.py@Software: PyCharm """ import numpy as np #import pandas as pd import matplotlib import matplotlib.pyplot as pltmatplotlib.rcParams['font.family']='SimHei' # 用來正常顯示中文 plt.rcParams['axes.unicode_minus']=False # 用來正常顯示負(fù)號def splitDataSet(dataSet, i, value,types='lt'):""" #劃分?jǐn)?shù)據(jù)集,只進(jìn)行一次劃分的樹,將劃分后的結(jié)果返回:param dataSet: 數(shù)據(jù):param i: 特征的下標(biāo):param value: 閾值:param types: 大于或小于:return: 分類結(jié)果,注意返回的直接就是1,-1分類結(jié)果"""retArray = np.ones((np.shape(dataSet)[0],1)) # 默認(rèn)類型都為1if types=='lt': # 使用(小于等于value)劃分?jǐn)?shù)據(jù),滿足條件的將結(jié)果值改為-1retArray[dataSet[:,i]<=value]= -1.0 elif types=='gt': # 使用(大于value)劃分?jǐn)?shù)據(jù),滿足條件的將結(jié)果值改為-1retArray[dataSet[:,i]>value]= -1.0 return retArray def bulidSimpleTree(dataSet,y,D):""" 創(chuàng)建一個最簡單的樹,只進(jìn)行一次劃分,相當(dāng)于一個樹樁:param dataSet: 數(shù)據(jù)特征矩陣:param y: 標(biāo)簽向量:param D: 訓(xùn)練數(shù)據(jù)的權(quán)重向量:return: 最佳決策樹,最小的錯誤率加權(quán)和,最優(yōu)預(yù)測結(jié)果"""m,n=dataSet.shape # 樣本行數(shù)及列數(shù)numFeatures = len(dataSet[0]) - 1 # 最后一列為y,計算x特征列數(shù)numSteps=10 # 用于計算步長,進(jìn)行numSteps等分minError=np.inf # 初始化損失值bestTree={} # 使用dict存儲最優(yōu)的一系列樹for i in range(numFeatures): # 遍歷所有x特征列# i=0rangeMin = dataSet[:, i].min() # 該xi維的最小值rangeMax = dataSet[:, i].max() # 該xi維的最大值stepSize = (rangeMax - rangeMin) / numSteps # 步長for j in range(-1,int(numSteps) + 1): # 循環(huán)尋找最優(yōu)切分點(diǎn)# j=-1for inequal in ['lt', 'gt']: # 遍歷(lt小于等于)及(gt大于)# inequal=1value = (rangeMin + float(j) * stepSize) # 切分值predictedVals = splitDataSet(dataSet, i, value, inequal) # 獲取切分后的數(shù)據(jù)errArr = np.mat(np.ones((m, 1)))errArr[predictedVals == y] = 0 # 預(yù)測正確的樣本對應(yīng)的錯誤率為0,否則為1weightedError=D.T*errArr # 《統(tǒng)計學(xué)習(xí)方法》李航P138,8.1,計算訓(xùn)練數(shù)據(jù)上的分類誤差率if weightedError < minError: # 記錄最優(yōu)樹樁決策樹分類器minError = weightedError # 計算錯誤率加權(quán)和bestClasEst = predictedVals.copy() # 最好的預(yù)測結(jié)果bestTree['column'] = i # 維度xbestTree['splitValue'] = value # 切分值bestTree['ineq'] = inequal # 切分方法(lt小于等于)及(gt大于)return bestTree, minError, bestClasEst# 基于單層決策樹的adaboost分類器 def adaboost(dataSet,maxLoop=100):""" 基于單層決策樹的ada訓(xùn)練:param dataSet: 樣本x及y:param maxLoop: 迭代次數(shù):return: 一系列弱分類器及其權(quán)重,樣本分類結(jié)果"""adaboostTree=[]m,n=dataSet.shape # 樣本行數(shù)及列數(shù)y=dataSet[:,-1].reshape((-1,1)) # 將y提取出來,方便進(jìn)行計算D = np.array(np.ones((m,1))/m) # 將每個樣本的權(quán)重初始化為均等,有多少條數(shù)據(jù)就有多少個daggClassEst = np.mat(np.zeros((m,1))) # 每個數(shù)據(jù)點(diǎn)的類別估計累計值for i in range(maxLoop): # maxLoop超參數(shù),總迭代次數(shù)bestTree, minError, bestClasEst=bulidSimpleTree(dataSet,y,D)alpha=0.5*np.log((1-minError)/(minError+0.00001)) # 《統(tǒng)計學(xué)習(xí)方法》李航P139,8.2,計算Gm的系數(shù),分母加一個小數(shù)避免除數(shù)為0bestTree['alpha'] = alpha.getA()[0][0] # 將matrix中的值提取出來,并加入到bestTree中adaboostTree.append(bestTree) # 將樹存入list中存儲D=D*np.exp(-alpha.getA()[0][0]*y*bestClasEst) # 更新權(quán)重D,《統(tǒng)計學(xué)習(xí)方法》李航P139,8.3-8.5,計算Gm(x)的系數(shù)D=D/D.sum() # 歸一化權(quán)重值,統(tǒng)計學(xué)習(xí)方法》李航P139,8.5,計算Zm# 計算所有分類器的誤差,如果為0則終止訓(xùn)練aggClassEst += alpha.getA()[0][0]*bestClasEst # 分類估計累計值,adaboost是線性運(yùn)行的,需要將每次的樹預(yù)測結(jié)果相加aggErrors = np.multiply(np.sign(aggClassEst) != np.mat(y),np.ones((m,1))) # aggClassEst每個元素的符號代表分類結(jié)果,如果與y不等則表示錯誤,統(tǒng)計學(xué)習(xí)方法》李航P138,8.8errorRate = aggErrors.sum()/m # 平均分類誤差print( "total error: ",errorRate)if errorRate == 0.0: # 平均分類誤差等于0的,說明數(shù)據(jù)已經(jīng)全部分類正確,跳出循環(huán)breakreturn adaboostTree,aggClassEstdef adaClassify(data, adaboostTree):""" 對預(yù)測數(shù)據(jù)進(jìn)行分類:param data: 預(yù)測樣本x及y:param adaboostTree: 使用訓(xùn)練數(shù)據(jù),訓(xùn)練好的決策樹:return: 預(yù)測樣本分類結(jié)果"""dataMatrix = np.mat(data) m = np.shape(dataMatrix)[0]aggClassEst = np.mat(np.zeros((m, 1)))for i in range(len(adaboostTree)): # 遍歷所有adaboostTree,將估計值累加classEst = splitDataSet(dataMatrix, adaboostTree[i]['column'], adaboostTree[i]['splitValue'], adaboostTree[i]['ineq']) aggClassEst += adaboostTree[i]['alpha'] * classEst # 分類估計累計值,adaboost是線性運(yùn)行的,需要將每次的樹預(yù)測結(jié)果相加result = np.sign(aggClassEst) # 只取正負(fù)號,《統(tǒng)計學(xué)習(xí)方法》李航P139,8.8return resultdef plotData(dataSet):""" 數(shù)據(jù)畫圖"""type1_x1 = []type1_x2 = []type2_x1 = []type2_x2 = []# 取兩類x1及x2值畫圖type1_x1 = dataSet[dataSet[:,-1] == -1][:,:-1][:,0].tolist()type1_x2 = dataSet[dataSet[:,-1] == -1][:,:-1][:,1].tolist()type2_x1 = dataSet[dataSet[:,-1] == 1][:,:-1][:,0].tolist()type2_x2 = dataSet[dataSet[:,-1] == 1][:,:-1][:,1].tolist()# 畫點(diǎn)fig = plt.figure()ax = fig.add_subplot(111)ax.scatter(type1_x1,type1_x2, marker='s', s=90)ax.scatter(type2_x1,type2_x2, marker='o', s=50, c='red')plt.title('Adaboost訓(xùn)練數(shù)據(jù)')if __name__ == '__main__':print('\n1、Adaboost,開始')dataSet = np.array([[ 1. , 2.1, 1 ],[ 2. , 1.1, 1 ],[ 1.3, 1. , -1],[ 1. , 1. , -1],[ 2. , 1. , 1 ]])#classLabels = [1.0, 1.0, -1.0, -1.0, 1.0]# 畫圖print('\n2、Adaboost數(shù)據(jù)畫圖')plotData(dataSet)print('\n3、計算Adaboost樹')adaboostTree,aggClassEst=adaboost(dataSet)# 對數(shù)據(jù)進(jìn)行分類print('\n4、對[5,5],[0, 0]點(diǎn),使用Adaboost進(jìn)行分類:')print( adaClassify([[5,5],[0, 0]], adaboostTree))

參考資料:
1、《機(jī)器學(xué)習(xí)實戰(zhàn)》Peter Harrington著
2、《機(jī)器學(xué)習(xí)》西瓜書,周志華著
3、 斯坦福大學(xué)公開課 :機(jī)器學(xué)習(xí)課程
4、機(jī)器學(xué)習(xí)視頻,鄒博
5、《統(tǒng)計學(xué)習(xí)方法》李航
6、提升方法
7、分類——組合算法之提升1:AdaBoost提升算法以及Python實現(xiàn)

轉(zhuǎn)載于:https://www.cnblogs.com/hanzi5/p/10105613.html

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎

總結(jié)

以上是生活随笔為你收集整理的Python实现Adaboost的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。