【轉(zhuǎn)載】機(jī)器學(xué)習(xí)實(shí)戰(zhàn)之AdaBoost算法

https://www.cnblogs.com/zy230530/p/6909288.html

一蝌矛,引言

  前面幾章的介紹了幾種分類(lèi)算法,當(dāng)然各有優(yōu)缺谈喳。如果將這些不同的分類(lèi)器組合起來(lái),就構(gòu)成了我們今天要介紹的集成方法或者說(shuō)元算法。集成方法有多種形式:可以使多種算法的集成茬末,也可以是一種算法在不同設(shè)置下的集成,還可以將數(shù)據(jù)集的不同部分分配不同的分類(lèi)器,再將這些分類(lèi)器進(jìn)行集成丽惭。

  adaBoost分類(lèi)器就是一種元算法分類(lèi)器击奶,adaBoost分類(lèi)器利用同一種基分類(lèi)器(弱分類(lèi)器),基于分類(lèi)器的錯(cuò)誤率分配不同的權(quán)重參數(shù)责掏,最后累加加權(quán)的預(yù)測(cè)結(jié)果作為輸出柜砾。

1 bagging方法

  在介紹adaBoost之前,我們首先大致介紹一種基于數(shù)據(jù)隨機(jī)重抽樣的分類(lèi)器構(gòu)建方法换衬,即bagging(bootstrap aggregating)方法痰驱,其是從原始數(shù)據(jù)集選擇s次后得到s個(gè)新數(shù)據(jù)集的一種技術(shù)。需要說(shuō)明的是瞳浦,新數(shù)據(jù)集和原數(shù)據(jù)集的大小相等担映。每個(gè)數(shù)據(jù)集都是通過(guò)在原始數(shù)據(jù)集上先后隨機(jī)選擇一個(gè)樣本來(lái)進(jìn)行替換得到的新的數(shù)據(jù)集(即先隨機(jī)選擇一個(gè)樣本,然后隨機(jī)選擇另外一個(gè)樣本替換之前的樣本)叫潦,并且這里的替換可以多次選擇同一樣本蝇完,也就是說(shuō)某些樣本可能多次出現(xiàn),而另外有一些樣本在新集合中不再出現(xiàn)矗蕊。

  s個(gè)數(shù)據(jù)集準(zhǔn)備好之后短蜕,將某個(gè)學(xué)習(xí)算法分別作用于每個(gè)數(shù)據(jù)集就得到s個(gè)分類(lèi)器。當(dāng)要對(duì)新的數(shù)據(jù)進(jìn)行分類(lèi)時(shí)拔妥,就應(yīng)用這s個(gè)分類(lèi)器進(jìn)行分類(lèi)忿危,最后根據(jù)多數(shù)表決的原則確定出最后的分類(lèi)結(jié)果。

2 boosting方法

  boosting方法就是我們本文要講到的分類(lèi)算法没龙,其與上面提到的bagging很類(lèi)似铺厨,都是采用同一種基分類(lèi)器的組合方法。而與bagging不同的是硬纤,boosting是集中關(guān)注分類(lèi)器錯(cuò)分的那些數(shù)據(jù)來(lái)獲得新的分類(lèi)器

  此外解滓,bagging中分類(lèi)器權(quán)重相等,而boosting中分類(lèi)器的權(quán)值并不相等筝家,分類(lèi)器的錯(cuò)誤率越低洼裤,那么其對(duì)應(yīng)的權(quán)重也就越大,越容易對(duì)預(yù)測(cè)結(jié)果產(chǎn)生影響溪王。boosting有許多版本腮鞍,而今天要介紹的是比較流行的AdaBoost。

二莹菱,AdaBoost

  AdaBoost的一般流程如下所示:

(1)收集數(shù)據(jù)

(2)準(zhǔn)備數(shù)據(jù):依賴(lài)于所用的基分類(lèi)器的類(lèi)型移国,這里的是單層決策樹(shù),即樹(shù)樁道伟,該類(lèi)型決策樹(shù)可以處理任何類(lèi)型的數(shù)據(jù)迹缀。

(3)分析數(shù)據(jù)

(4)訓(xùn)練算法:利用提供的數(shù)據(jù)集訓(xùn)練分類(lèi)器

(5)測(cè)試算法:利用提供的測(cè)試數(shù)據(jù)集計(jì)算分類(lèi)的錯(cuò)誤率

(6)使用算法:算法的相關(guān)推廣使碾,滿足實(shí)際的需要

  接下來(lái),具體闡述adaBoost分類(lèi)算法

1 訓(xùn)練算法:基于錯(cuò)誤提升分類(lèi)器的性能

  上面所述的基分類(lèi)器祝懂,或者說(shuō)弱分類(lèi)器票摇,意味著分類(lèi)器的性能不會(huì)太好,可能要比隨機(jī)猜測(cè)要好一些砚蓬,一般而言矢门,在二類(lèi)分類(lèi)情況下,弱分類(lèi)器的分類(lèi)錯(cuò)誤率達(dá)到甚至超過(guò)50%灰蛙,顯然也只是比隨機(jī)猜測(cè)略好颅和。但是,強(qiáng)分類(lèi)器的分類(lèi)錯(cuò)誤率相對(duì)而言就要小很多缕允,adaBoost算法就是易于這些弱分類(lèi)器的組合最終來(lái)完成分類(lèi)預(yù)測(cè)的。

  adaBoost的運(yùn)行過(guò)程:訓(xùn)練數(shù)據(jù)的每一個(gè)樣本蹭越,并賦予其一個(gè)權(quán)重障本,這些權(quán)值構(gòu)成權(quán)重向量D,維度等于數(shù)據(jù)集樣本個(gè)數(shù)响鹃。開(kāi)始時(shí)驾霜,這些權(quán)重都是相等的,首先在訓(xùn)練數(shù)據(jù)集上訓(xùn)練出一個(gè)弱分類(lèi)器并計(jì)算該分類(lèi)器的錯(cuò)誤率买置,然后在同一數(shù)據(jù)集上再次訓(xùn)練弱分類(lèi)器粪糙,但是在第二次訓(xùn)練時(shí),將會(huì)根據(jù)分類(lèi)器的錯(cuò)誤率忿项,對(duì)數(shù)據(jù)集中樣本的各個(gè)權(quán)重進(jìn)行調(diào)整蓉冈,分類(lèi)正確的樣本的權(quán)重降低,而分類(lèi)錯(cuò)的樣本權(quán)重則上升轩触,但這些權(quán)重的總和保持不變?yōu)?.

  并且寞酿,最終的分類(lèi)器會(huì)基于這些訓(xùn)練的弱分類(lèi)器的分類(lèi)錯(cuò)誤率,分配不同的決定系數(shù)alpha脱柱,錯(cuò)誤率低的分類(lèi)器獲得更高的決定系數(shù)伐弹,從而在對(duì)數(shù)據(jù)進(jìn)行預(yù)測(cè)時(shí)起關(guān)鍵作用。alpha的計(jì)算根據(jù)錯(cuò)誤率得來(lái):

  alpha=0.5*ln(1-ε/max(ε,1e-16))

其中榨为,ε=為正確分類(lèi)的樣本數(shù)目/樣本總數(shù)惨好,max(ε,1e-16)是為了防止錯(cuò)誤率為而造成分母為0的情況發(fā)生

  計(jì)算出alpha之后,就可以對(duì)權(quán)重向量進(jìn)行更新了随闺,使得分類(lèi)錯(cuò)誤的樣本獲得更高的權(quán)重日川,而分類(lèi)正確的樣本獲得更低的權(quán)重。D的計(jì)算公式如下:

如果某個(gè)樣本被正確分類(lèi)板壮,那么權(quán)重更新為:

D(m+1,i)=D(m,i)*exp(-alpha)/sum(D)

如果某個(gè)樣本被錯(cuò)誤分類(lèi)逗鸣,那么權(quán)重更新為:

D(m+1,i)=D(m,i)*exp(alpha)/sum(D)

其中,m為迭代的次數(shù),即訓(xùn)練的第m個(gè)分類(lèi)器撒璧,i為權(quán)重向量的第i個(gè)分量透葛,i<=數(shù)據(jù)集樣本數(shù)量

  當(dāng)我們更新完各個(gè)樣本的權(quán)重之后,就可以進(jìn)行下一次的迭代訓(xùn)練卿樱。adaBoost算法會(huì)不斷重復(fù)訓(xùn)練和調(diào)整權(quán)重僚害,直至達(dá)到迭代次數(shù),或者訓(xùn)練錯(cuò)誤率為0繁调。

2 基于單層決策樹(shù)構(gòu)建弱分類(lèi)器

  單層決策樹(shù)是一種簡(jiǎn)單的決策樹(shù)萨蚕,也稱(chēng)為決策樹(shù)樁。單層決策樹(shù)可以看做是由一個(gè)根節(jié)點(diǎn)直接連接兩個(gè)葉結(jié)點(diǎn)的簡(jiǎn)單決策樹(shù)蹄胰,比如x>v或x<v岳遥,就可以看做是一個(gè)簡(jiǎn)單決策樹(shù)。

  為了更好的演示adaBoost的訓(xùn)練過(guò)程裕寨,我們首先建立一個(gè)簡(jiǎn)單的數(shù)據(jù)集浩蓉,并將其轉(zhuǎn)為我們想要的數(shù)據(jù)格式,代碼如下:

#獲取數(shù)據(jù)集

def loadSimpData():

? ? dataMat=matrix([[1. ,2.1],

? ? ? ? [2. ,1.1],

? ? ? ? [1.3,1. ],

? ? ? ? [1. ,1. ],

? ? ? ? [2. ,1. ]])

? ? classLabels=[1.0,1.0,-1.0,-1.0,1.0]

return dataMat,classLabels



  接下來(lái)宾袜,我們就要通過(guò)上述數(shù)據(jù)集來(lái)尋找最佳的單層決策樹(shù)捻艳,最佳單層決策樹(shù)是具有最低分類(lèi)錯(cuò)誤率的單層決策樹(shù),偽代碼如下:

#構(gòu)建單層分類(lèi)器

#單層分類(lèi)器是基于最小加權(quán)分類(lèi)錯(cuò)誤率的樹(shù)樁

#偽代碼

#將最小錯(cuò)誤率minError設(shè)為+∞

#對(duì)數(shù)據(jù)集中的每個(gè)特征(第一層特征):

? ? #對(duì)每個(gè)步長(zhǎng)(第二層特征):

? ? ? ? #對(duì)每個(gè)不等號(hào)(第三層特征):

? ? ? ? ? ? #建立一顆單層決策樹(shù)并利用加權(quán)數(shù)據(jù)集對(duì)它進(jìn)行測(cè)試

? ? ? ? ? ? #如果錯(cuò)誤率低于minError庆猫,則將當(dāng)前單層決策樹(shù)設(shè)為最佳單層決策樹(shù)

#返回最佳單層決策樹(shù)



  接下來(lái)看單層決策樹(shù)的生成函數(shù)代碼:

#單層決策樹(shù)的閾值過(guò)濾函數(shù)

def stumpClassify(dataMatrix,dimen,threshVal,threshIneq):

? ? #對(duì)數(shù)據(jù)集每一列的各個(gè)特征進(jìn)行閾值過(guò)濾

? ? retArray=ones((shape(dataMatrix)[0],1))

? ? #閾值的模式认轨,將小于某一閾值的特征歸類(lèi)為-1

? ? if threshIneq=='lt':

? ? ? ? retArray[dataMatrix[:,dimen]<=threshVal]=-1.0

? ? #將大于某一閾值的特征歸類(lèi)為-1

? ? else:

? ? ? ? retArray[dataMatrix[:,dimen]>threshVal]=-1.0


def buildStump(dataArr,classLabels,D):

#將數(shù)據(jù)集和標(biāo)簽列表轉(zhuǎn)為矩陣形式

? ? dataMatrix=mat(dataArr);labelMat=mat(classLabels).T

? ? m,n=shape(dataMatrix)

? ? #步長(zhǎng)或區(qū)間總數(shù) 最優(yōu)決策樹(shù)信息 最優(yōu)單層決策樹(shù)預(yù)測(cè)結(jié)果

? ? numSteps=10.0;bestStump={};bestClasEst=mat(zeros((m,1)))

? ? #最小錯(cuò)誤率初始化為+∞

? ? minError=inf

? ? #遍歷每一列的特征值

? ? for i in range(n):

? ? ? ? #找出列中特征值的最小值和最大值

? ? ? ? rangeMin=dataMatrix[:,i].min();rangeMax=dataMatrix[:,i].max()

? ? ? ? #求取步長(zhǎng)大小或者說(shuō)區(qū)間間隔

? ? ? ? stepSize=(rangeMax-rangeMin)/numSteps

? ? ? ? #遍歷各個(gè)步長(zhǎng)區(qū)間

? ? ? ? for j in range(-1,int(numSteps)+1):

? ? ? ? ? ? #兩種閾值過(guò)濾模式

? ? ? ? ? ? for inequal in ['lt','gt']:

? ? ? ? ? ? #閾值計(jì)算公式:最小值+j(-1<=j<=numSteps+1)*步長(zhǎng)

? ? ? ? ? ? threshVal=(rangeMin+float(j)*stepSize)

? ? ? ? ? ? #選定閾值后,調(diào)用閾值過(guò)濾函數(shù)分類(lèi)預(yù)測(cè)

? ? ? ? ? ? predictedVals=\

? ? ? ? ? ? ? ? stumpClassify(dataMatrix,i,threshVal,'inequal')

? ? ? ? ? ? #初始化錯(cuò)誤向量

? ? ? ? ? ? errArr=mat(ones((m,1)))

? ? ? ? ? ? #將錯(cuò)誤向量中分類(lèi)正確項(xiàng)置0

? ? ? ? ? ? errArr[predictedVals==labelMat]=0

? ? ? ? ? ? #計(jì)算"加權(quán)"的錯(cuò)誤率

? ? ? ? ? ? weigthedError=D.T*errArr

? ? ? ? ? ? #打印相關(guān)信息月培,可省略

? ? ? ? ? ? #print("split: dim %d, thresh %.2f,thresh inequal:\

? ? ? ? ? ? #? ? %s, the weighted error is %.3f",

? ? ? ? ? ? #? ? %(i,threshVal,inequal,weigthedError))

? ? ? ? ? ? #如果當(dāng)前錯(cuò)誤率小于當(dāng)前最小錯(cuò)誤率嘁字,將當(dāng)前錯(cuò)誤率作為最小錯(cuò)誤率

? ? ? ? ? ? #存儲(chǔ)相關(guān)信息

? ? ? ? ? ? if weigthedError<minError:

? ? ? ? ? ? ? ? minError=weigthedError

? ? ? ? ? ? ? ? bestClasEst=predictedVals.copy()

? ? ? ? ? ? ? ? bestStump['dim']=i

? ? ? ? ? ? ? ? bestStump['thresh']='threshVal'

? ? ? ? ? ? ? ? bestStump['ineq']=inequal

? ? #返回最佳單層決策樹(shù)相關(guān)信息的字典,最小錯(cuò)誤率杉畜,決策樹(shù)預(yù)測(cè)輸出結(jié)果

? ? return bestStump,minError,bestClasEst


需要說(shuō)明的是拳锚,上面的代碼包含兩個(gè)函數(shù),第一個(gè)函數(shù)是分類(lèi)器的閾值過(guò)濾函數(shù)寻行,即設(shè)定某一閾值霍掺,凡是超過(guò)該閾值的結(jié)果被歸為一類(lèi),小于閾值的結(jié)果都被分為另外一類(lèi)拌蜘,這里的兩類(lèi)依然同SVM一樣杆烁,采用+1和-1作為類(lèi)別。

  第二個(gè)函數(shù)简卧,就是建立單層決策樹(shù)的具體代碼兔魂,基于樣本值的各個(gè)特征及特征值的大小,設(shè)定合適的步長(zhǎng)举娩,獲得不同的閾值析校,然后以此閾值作為根結(jié)點(diǎn)构罗,對(duì)數(shù)據(jù)集樣本進(jìn)行分類(lèi),并計(jì)算錯(cuò)誤率智玻,需要指出的是遂唧,這里的錯(cuò)誤率計(jì)算是基于樣本權(quán)重的,所有分錯(cuò)的樣本乘以其對(duì)應(yīng)的權(quán)重吊奢,然后進(jìn)行累加得到分類(lèi)器的錯(cuò)誤率盖彭。錯(cuò)誤率得到之后,根據(jù)錯(cuò)誤率的大小页滚,跟當(dāng)前存儲(chǔ)的最小錯(cuò)誤率的分類(lèi)器進(jìn)行比較召边,選擇出錯(cuò)誤率最小的特征訓(xùn)練出來(lái)的分類(lèi)器,作為最佳單層決策樹(shù)輸出裹驰,并通過(guò)字典類(lèi)型保存其相關(guān)重要的信息隧熙。

  迭代的過(guò)程如下所示:

  好了,弱分類(lèi)器有了幻林,那么我們接下來(lái)就可以來(lái)討論adaBoost的具體訓(xùn)練過(guò)程了

3 完整AdaBoost算法實(shí)現(xiàn)

  上面已經(jīng)構(gòu)建好了基于加權(quán)輸入值進(jìn)行決策的單層分類(lèi)器贱鼻,那么就已經(jīng)有了實(shí)現(xiàn)一個(gè)完整AdaBoost算法所需要的所有信息了。下面先看一下整個(gè)AdaBoost的偽代碼實(shí)現(xiàn):

#完整AdaBoost算法實(shí)現(xiàn)

#算法實(shí)現(xiàn)偽代碼

#對(duì)每次迭代:

? ? #利用buildStump()函數(shù)找到最佳的單層決策樹(shù)

? ? #將最佳單層決策樹(shù)加入到單層決策樹(shù)數(shù)組

? ? #計(jì)算alpha

? ? #計(jì)算新的權(quán)重向量D

? ? #更新累計(jì)類(lèi)別估計(jì)值

? ? #如果錯(cuò)誤率為等于0.0滋将,退出循環(huán)


  再來(lái)看看具體的實(shí)現(xiàn)代碼吧:#adaBoost算法

#@dataArr:數(shù)據(jù)矩陣

#@classLabels:標(biāo)簽向量

#@numIt:迭代次數(shù)? ?

def adaBoostTrainDS(dataArr,classLabels,numIt=40):

? ? #弱分類(lèi)器相關(guān)信息列表

? ? weakClassArr=[]

? ? #獲取數(shù)據(jù)集行數(shù)

? ? m=shape(dataArr)[0]

? ? #初始化權(quán)重向量的每一項(xiàng)值相等

? ? D=mat(ones((m,1))/m)

? ? #累計(jì)估計(jì)值向量

? ? aggClassEst=mat((m,1))

? ? #循環(huán)迭代次數(shù)

? ? for i in range(numIt):

? ? ? ? #根據(jù)當(dāng)前數(shù)據(jù)集,標(biāo)簽及權(quán)重建立最佳單層決策樹(shù)

? ? ? ? bestStump,error,classEst=buildStump(dataArr,classLabels,D)

? ? ? ? #打印權(quán)重向量

? ? ? ? print("D:",D.T)

? ? ? ? #求單層決策樹(shù)的系數(shù)alpha

? ? ? ? alpha=float(0.5*log((1.0-error)/(max(error,1e-16))))

? ? ? ? #存儲(chǔ)決策樹(shù)的系數(shù)alpha到字典

? ? ? ? bestStump['alpha']=alpha

? ? ? ? #將該決策樹(shù)存入列表

? ? ? ? weakClassArr.append(bestStump)

? ? ? ? #打印決策樹(shù)的預(yù)測(cè)結(jié)果

? ? ? ? print("classEst:",classEst.T)

? ? ? ? #預(yù)測(cè)正確為exp(-alpha),預(yù)測(cè)錯(cuò)誤為exp(alpha)

? ? ? ? #即增大分類(lèi)錯(cuò)誤樣本的權(quán)重症昏,減少分類(lèi)正確的數(shù)據(jù)點(diǎn)權(quán)重

? ? ? ? expon=multiply(-1*alpha*mat(classLabels).T,classEst)

? ? ? ? #更新權(quán)值向量

? ? ? ? D=multiply(D,exp(expon))

? ? ? ? D=D/D.sum()

? ? ? ? #累加當(dāng)前單層決策樹(shù)的加權(quán)預(yù)測(cè)值

? ? ? ? aggClassEst+=alpha*classEst

? ? ? ? print("aggClassEst",aggClassEst.T)

? ? ? ? #求出分類(lèi)錯(cuò)的樣本個(gè)數(shù)

? ? ? ? aggErrors=multiply(sign(aggClassEst)!=\

? ? ? ? ? ? ? ? ? ? mat(classLabels).T,ones((m,1)))

? ? ? ? #計(jì)算錯(cuò)誤率

? ? ? ? errorRate=aggErrors.sum()/m

? ? ? ? print("total error:",errorRate,"\n")

? ? ? ? #錯(cuò)誤率為0.0退出循環(huán)

? ? ? ? if errorRate==0.0:break

? ? #返回弱分類(lèi)器的組合列表

? ? return weakClassArr

對(duì)于上面的代碼随闽,需要說(shuō)明的有一下幾點(diǎn):

(1)上面的輸入除了數(shù)據(jù)集和標(biāo)簽之外,還有用戶(hù)自己指定的迭代次數(shù)肝谭,用戶(hù)可以根據(jù)自己的成本需要和實(shí)際情況掘宪,設(shè)定合適的迭代次數(shù),構(gòu)建出需要的弱分類(lèi)器數(shù)量攘烛。

(2)權(quán)重向量D包含了當(dāng)前單層決策樹(shù)分類(lèi)器下魏滚,各個(gè)數(shù)據(jù)集樣本的權(quán)重,一開(kāi)始它們的值都相等坟漱。但是鼠次,經(jīng)過(guò)分類(lèi)器分類(lèi)之后,會(huì)根據(jù)分類(lèi)的權(quán)重加權(quán)錯(cuò)誤率對(duì)這些權(quán)重進(jìn)行修改芋齿,修改的方向?yàn)樾瓤埽岣叻诸?lèi)錯(cuò)誤樣本的權(quán)重,減少分類(lèi)正確的樣本的權(quán)重觅捆。

(3)分類(lèi)器系數(shù)alpha赦役,是另外一個(gè)非常重要的參數(shù),它在最終的分類(lèi)器組合決策分類(lèi)結(jié)果的過(guò)程中栅炒,起到了非常重要的作用掂摔,如果某個(gè)弱分類(lèi)器的分類(lèi)錯(cuò)誤率更低术羔,那么根據(jù)錯(cuò)誤率計(jì)算出來(lái)的分類(lèi)器系數(shù)將更高,這樣乙漓,這些分類(lèi)錯(cuò)誤率更低的分類(lèi)器在最終的分類(lèi)決策中级历,會(huì)起到更加重要的作用。

(4)上述代碼的訓(xùn)練過(guò)程是以達(dá)到迭代的用戶(hù)指定的迭代次數(shù)或者訓(xùn)練錯(cuò)誤率達(dá)到要求而跳出循環(huán)簇秒。而最終的分類(lèi)器決策結(jié)果鱼喉,會(huì)通過(guò)sign函數(shù),將結(jié)果指定為+1或者-1

下面是訓(xùn)練的過(guò)程:


4 測(cè)試算法

  那么有了訓(xùn)練好的分類(lèi)器趋观,是不是要測(cè)試一下呢扛禽,畢竟訓(xùn)練錯(cuò)誤率針對(duì)的是已知的數(shù)據(jù),我們需要在分類(lèi)器未知的數(shù)據(jù)上進(jìn)行測(cè)試皱坛,看看分類(lèi)效果编曼。上面的訓(xùn)練代碼會(huì)幫我們保存每個(gè)弱分類(lèi)器的重要信息,比如分類(lèi)器系數(shù)剩辟,分類(lèi)器的最優(yōu)特征掐场,特征閾值等。有了這些重要的信息贩猎,我們拿到之后熊户,就可以對(duì)測(cè)試數(shù)據(jù)進(jìn)行預(yù)測(cè)分類(lèi)了

#測(cè)試adaBoost,adaBoost分類(lèi)函數(shù)

#@datToClass:測(cè)試數(shù)據(jù)點(diǎn)

#@classifierArr:構(gòu)建好的最終分類(lèi)器

def adaClassify(datToClass,classifierArr):

? ? #構(gòu)建數(shù)據(jù)向量或矩陣

? ? dataMatrix=mat(datToClass)

? ? #獲取矩陣行數(shù)

? ? m=shape(dataMatrix)[0]

? ? #初始化最終分類(lèi)器

? ? aggClassEst=mat(zeros((m,1)))

? ? #遍歷分類(lèi)器列表中的每一個(gè)弱分類(lèi)器

? ? for i in range(len(classifierArr)):

? ? ? ? #每一個(gè)弱分類(lèi)器對(duì)測(cè)試數(shù)據(jù)進(jìn)行預(yù)測(cè)分類(lèi)

? ? ? ? classEst=stumpClassify(dataMat,classifierArr[i]['dim'],\

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? classifierArr[i]['thresh'],

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? classifierArr[i]['ineq'])

? ? ? ? #對(duì)各個(gè)分類(lèi)器的預(yù)測(cè)結(jié)果進(jìn)行加權(quán)累加

? ? ? ? aggClassEst+=classifierArr[i]['alpha']*classEst

? ? ? ? print('aggClassEst',aggClassEst)

? ? #通過(guò)sign函數(shù)根據(jù)結(jié)果大于或小于0預(yù)測(cè)出+1或-1

? ? return sign(aggClassEst)


 看一個(gè)測(cè)試樣例

  從結(jié)果看來(lái)吭服,不拿發(fā)現(xiàn)嚷堡,隨著迭代次數(shù)的增加,分類(lèi)結(jié)果是逐漸越強(qiáng)的艇棕。

三蝌戒,實(shí)例:難數(shù)據(jù)集上應(yīng)用adaBoost

  第四章的logistic回歸時(shí)用到了預(yù)測(cè)馬疝病是否死亡的數(shù)據(jù)集。這里沼琉,我們?cè)俅卫迷摯嬖?0%數(shù)據(jù)缺失的數(shù)據(jù)集來(lái)進(jìn)行adaBoost算法測(cè)試北苟,比較其與logistic回歸分類(lèi)器的分類(lèi)錯(cuò)誤率。

  首先打瘪,從文件中加載數(shù)據(jù)集友鼻,轉(zhuǎn)變成我們想要的數(shù)據(jù)格式,先看下面自適應(yīng)數(shù)據(jù)加載函數(shù)代碼:

#自適應(yīng)加載數(shù)據(jù)

def loadDataSet(filename):

? ? #創(chuàng)建數(shù)據(jù)集矩陣闺骚,標(biāo)簽向量

? ? dataMat=[];labelMat=[]

? ? #獲取特征數(shù)目(包括最后一類(lèi)標(biāo)簽)

? ? #readline():讀取文件的一行

? ? #readlines:讀取整個(gè)文件所有行

? ? numFeat=len(open(filename).readline().split('\t'))

? ? #打開(kāi)文件

? ? fr=open(filename)

? ? #遍歷文本每一行

? ? for line in fr.readlines():

? ? ? ? lineArr=[]

? ? ? ? curLine=line.strip().split('\t')

? ? ? ? for i in range(numFeat-1):

? ? ? ? ? ? lineArr.append(float(curLine[i]))

? ? ? ? #數(shù)據(jù)矩陣

? ? ? ? dataMat.append(lineArr)

? ? ? ? #標(biāo)簽向量

? ? ? ? labelMat.append(float(curLine[-1]))

? ? return dataMat,labelMat


  與之前的加載數(shù)據(jù)代碼不同的是桃移,該函數(shù)可以自動(dòng)檢測(cè)出數(shù)據(jù)樣本的特征數(shù)目。好了葛碧,來(lái)看最終的測(cè)試代碼函數(shù):

#訓(xùn)練和測(cè)試分類(lèi)器

def classify():

? ? #利用訓(xùn)練集訓(xùn)練分類(lèi)器

? ? datArr,labelArr=loadDataSet('horseColicTraining2.txt')

? ? #得到訓(xùn)練好的分類(lèi)器

? ? classifierArray=adaBoostTrainDS(datArr,labelArr,10)

? ? #利用測(cè)試集測(cè)試分類(lèi)器的分類(lèi)效果

? ? testArr,testLabelArr=loadDataSet('horseClicTest2.txt')

? ? prediction=adaClassify(testArr,classifierArray)

? ? #輸出錯(cuò)誤率

? ? num=shape(mat(labelArr))[1]

? ? errArr=mat(ones((num,1)))

? ? error=errArr[prediction!=mat(testLabelArr).T].sum()

? ? print("the errorRate is: %.2f",errorRate=float(error)/float((num)))


基于上面的adaBoost分類(lèi)器訓(xùn)練和測(cè)試代碼借杰,得到了下面的不同弱分類(lèi)器數(shù)目情況下的AdaBoost測(cè)試和分類(lèi)錯(cuò)誤率。

分類(lèi)器數(shù)目訓(xùn)練錯(cuò)誤率(%)測(cè)試錯(cuò)誤率(%)

1????0.28????0.27

10????0.23????0.24

50????0.19????0.21

100????0.19????0.22

500????0.16????0.25

1000????0.14????0.31

10000????0.11????0.33

觀察商標(biāo)的數(shù)據(jù)我們發(fā)現(xiàn):

(1)隨著分類(lèi)器數(shù)目的增加进泼,adaBoost分類(lèi)器的訓(xùn)練錯(cuò)誤率不斷的減少蔗衡,而測(cè)試錯(cuò)誤率則是經(jīng)歷先減少到最小值纤虽,再逐漸增大的過(guò)程。顯然绞惦,這就是所說(shuō)的過(guò)擬合逼纸。因此,對(duì)于這種情況济蝉,我們應(yīng)該采取相應(yīng)的措施杰刽,比如采取交叉驗(yàn)證的方法,在訓(xùn)練分類(lèi)器時(shí)王滤,設(shè)定一個(gè)驗(yàn)證集合贺嫂,不斷測(cè)試驗(yàn)證集的分類(lèi)錯(cuò)誤率,當(dāng)發(fā)現(xiàn)訓(xùn)練集錯(cuò)誤率減少的同時(shí)雁乡,驗(yàn)證集的錯(cuò)誤率較之上一次結(jié)果上升了第喳,就停止訓(xùn)練□馍裕或者其他比較實(shí)用的模擬退火方法曲饱,基因遺傳方法等。

(2)前面的第四章的logistic回歸分類(lèi)器對(duì)該數(shù)據(jù)集的分類(lèi)錯(cuò)誤率是35%珠月,顯然adaBoost分類(lèi)器取得了更好的分類(lèi)效果扩淀。

(3)有文獻(xiàn)表明,對(duì)于表現(xiàn)好的數(shù)據(jù)集啤挎,AdaBoost的測(cè)試誤差率會(huì)隨著迭代次數(shù)的增加而逐漸穩(wěn)定在某一個(gè)值附近驻谆,而不會(huì)出現(xiàn)上表中的先減小后上升的情況。顯然侵浸,這里用到的數(shù)據(jù)集不能稱(chēng)為"表現(xiàn)好"的數(shù)據(jù)集,比較該數(shù)據(jù)集存在30%的數(shù)據(jù)缺失氛谜。在第四章的logistic回歸中掏觉,我們講這些確實(shí)的數(shù)據(jù)設(shè)置為0,顯然這在logistic回歸算法中是合適值漫,這樣不會(huì)對(duì)分類(lèi)結(jié)果造成影響澳腹。但是,在adaBoost算法中依然這樣設(shè)置杨何,其合理性還有待證明酱塔,所以,有必要可以將這些缺失的數(shù)據(jù)值由0變成該特征相類(lèi)似的數(shù)據(jù)危虱,或者該特征數(shù)據(jù)的平均值羊娃,再來(lái)進(jìn)行adaBoost算法訓(xùn)練,看看得到的結(jié)果會(huì)不會(huì)有所提升埃跷?

四蕊玷,總結(jié)

  adaBoost是boosting方法中最流行的一種算法邮利。它是以弱分類(lèi)器作為基礎(chǔ)分類(lèi)器,輸入數(shù)據(jù)之后垃帅,通過(guò)加權(quán)向量進(jìn)行加權(quán)延届,;在每一輪的迭代過(guò)程中都會(huì)基于弱分類(lèi)器的加權(quán)錯(cuò)誤率贸诚,更新權(quán)重向量方庭,從而進(jìn)行下一次迭代。并且會(huì)在每一輪迭代中計(jì)算出該弱分類(lèi)器的系數(shù)酱固,該系數(shù)的大小將決定該弱分類(lèi)器在最終預(yù)測(cè)分類(lèi)中的重要程度械念。顯然,這兩點(diǎn)的結(jié)合是adaBoost算法的優(yōu)勢(shì)所在媒怯。

  優(yōu)點(diǎn):泛化錯(cuò)誤率低订讼,容易實(shí)現(xiàn),可以應(yīng)用在大部分分類(lèi)器上扇苞,無(wú)參數(shù)調(diào)整

  缺點(diǎn):對(duì)離散數(shù)據(jù)點(diǎn)敏感

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末欺殿,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子鳖敷,更是在濱河造成了極大的恐慌脖苏,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,744評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件定踱,死亡現(xiàn)場(chǎng)離奇詭異棍潘,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)崖媚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)亦歉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人畅哑,你說(shuō)我怎么就攤上這事肴楷。” “怎么了荠呐?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,105評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵赛蔫,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我泥张,道長(zhǎng)呵恢,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,242評(píng)論 1 292
  • 正文 為了忘掉前任媚创,我火速辦了婚禮渗钉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘钞钙。我一直安慰自己晌姚,他們只是感情好粤剧,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,269評(píng)論 6 389
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著挥唠,像睡著了一般抵恋。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上宝磨,一...
    開(kāi)封第一講書(shū)人閱讀 51,215評(píng)論 1 299
  • 那天弧关,我揣著相機(jī)與錄音,去河邊找鬼唤锉。 笑死世囊,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的窿祥。 我是一名探鬼主播株憾,決...
    沈念sama閱讀 40,096評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼晒衩!你這毒婦竟也來(lái)了嗤瞎?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,939評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤听系,失蹤者是張志新(化名)和其女友劉穎贝奇,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體靠胜,經(jīng)...
    沈念sama閱讀 45,354評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡掉瞳,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,573評(píng)論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了浪漠。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片陕习。...
    茶點(diǎn)故事閱讀 39,745評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖址愿,靈堂內(nèi)的尸體忽然破棺而出该镣,到底是詐尸還是另有隱情,我是刑警寧澤必盖,帶...
    沈念sama閱讀 35,448評(píng)論 5 344
  • 正文 年R本政府宣布拌牲,位于F島的核電站俱饿,受9級(jí)特大地震影響歌粥,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜拍埠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,048評(píng)論 3 327
  • 文/蒙蒙 一失驶、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧枣购,春花似錦嬉探、人聲如沸擦耀。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,683評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)眷蜓。三九已至,卻和暖如春胎围,著一層夾襖步出監(jiān)牢的瞬間吁系,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,838評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工白魂, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留汽纤,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,776評(píng)論 2 369
  • 正文 我出身青樓福荸,卻偏偏與公主長(zhǎng)得像蕴坪,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子敬锐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,652評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容