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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

Adaboost

發(fā)布時間:2024/6/21 综合教程 49 生活家
生活随笔 收集整理的這篇文章主要介紹了 Adaboost 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Adaboost算法概述

Adaboost算法核心思想:“三個臭皮匠賽過一諸葛亮”。我們平常構(gòu)建的分類模型可以說是弱分類器,若將這些弱分類器組合起來可以成為一個強(qiáng)分類器。大多數(shù)的提升方法是該表訓(xùn)練數(shù)據(jù)的概率分布(訓(xùn)練數(shù)據(jù)的權(quán)值分布),針對不同的訓(xùn)練數(shù)據(jù)分布調(diào)用弱學(xué)習(xí)算法學(xué)習(xí)。

如何改變訓(xùn)練數(shù)據(jù)的權(quán)值分布:第一輪初始化均勻分布樣本權(quán)值,往后每一輪,提高那些被前一輪弱分期錯誤分類樣本的權(quán)值,而降低那些被正確分類樣本的權(quán)值。這樣錯誤分類的樣本權(quán)值加大會受到后一輪弱分類器的更大關(guān)注,于是分類問題被一系列的弱分類器分而治之

如何將弱分類器組合成強(qiáng)分類器:Adaboost采取多數(shù)表決的方法。即加大分類誤差率小的弱分類器的權(quán)值,減少分類誤差率大的弱分類器的權(quán)值。

adaBoost的運(yùn)行過程

訓(xùn)練數(shù)據(jù)的每一個樣本,并賦予其一個權(quán)重,這些權(quán)值構(gòu)成權(quán)重向量D,維度等于數(shù)據(jù)集樣本個數(shù)。開始時,這些權(quán)重都是相等的,首先在訓(xùn)練數(shù)據(jù)集上訓(xùn)練出一個弱分類器并計算該分類器的錯誤率,然后在同一數(shù)據(jù)集上再次訓(xùn)練弱分類器,但是在第二次訓(xùn)練時,將會根據(jù)分類器的錯誤率,對數(shù)據(jù)集中樣本的各個權(quán)重進(jìn)行調(diào)整,分類正確的樣本的權(quán)重降低,而分類錯的樣本權(quán)重則上升,但這些權(quán)重的總和保持不變?yōu)?.

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

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

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

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

  如果某個樣本被正確分類,那么權(quán)重更新為:
  D(m+1,i)=D(m,i)*exp(-alpha)/sum(D)

  如果某個樣本被錯誤分類,那么權(quán)重更新為:
  D(m+1,i)=D(m,i)*exp(alpha)/sum(D)

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

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

基于單層決策樹構(gòu)建弱分類器

  單層決策樹是一種簡單的決策樹,也稱為決策樹樁。單層決策樹可以看做是由一個根節(jié)點(diǎn)直接連接兩個葉結(jié)點(diǎn)的簡單決策樹,比如x>v或x<v,就可以看做是一個簡單決策樹。

  為了更好的演示adaBoost的訓(xù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

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

#構(gòu)建單層分類器
#單層分類器是基于最小加權(quán)分類錯誤率的樹樁
#偽代碼
#將最小錯誤率minError設(shè)為+∞
#對數(shù)據(jù)集中的每個特征(第一層特征):
    #對每個步長(第二層特征):
        #對每個不等號(第三層特征):
            #建立一顆單層決策樹并利用加權(quán)數(shù)據(jù)集對它進(jìn)行測試
            #如果錯誤率低于minError,則將當(dāng)前單層決策樹設(shè)為最佳單層決策樹
#返回最佳單層決策樹

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

#單層決策樹的閾值過濾函數(shù)
def stumpClassify(dataMatrix,dimen,threshVal,threshIneq):
    #對數(shù)據(jù)集每一列的各個特征進(jìn)行閾值過濾
    retArray=ones((shape(dataMatrix)[0],1))
    #閾值的模式,將小于某一閾值的特征歸類為-1
    if threshIneq=='lt':
        retArray[dataMatrix[:,dimen]<=threshVal]=-1.0
    #將大于某一閾值的特征歸類為-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)
    #步長或區(qū)間總數(shù) 最優(yōu)決策樹信息 最優(yōu)單層決策樹預(yù)測結(jié)果
    numSteps=10.0;bestStump={};bestClasEst=mat(zeros((m,1)))
    #最小錯誤率初始化為+∞
    minError=inf
    #遍歷每一列的特征值
    for i in range(n):
        #找出列中特征值的最小值和最大值
        rangeMin=dataMatrix[:,i].min();rangeMax=dataMatrix[:,i].max()
        #求取步長大小或者說區(qū)間間隔
        stepSize=(rangeMax-rangeMin)/numSteps
        #遍歷各個步長區(qū)間
        for j in range(-1,int(numSteps)+1):
            #兩種閾值過濾模式
            for inequal in ['lt','gt']:
            #閾值計算公式:最小值+j(-1<=j<=numSteps+1)*步長
            threshVal=(rangeMin+float(j)*stepSize)
            #選定閾值后,調(diào)用閾值過濾函數(shù)分類預(yù)測
            predictedVals=
                stumpClassify(dataMatrix,i,threshVal,'inequal')
            #初始化錯誤向量
            errArr=mat(ones((m,1)))
            #將錯誤向量中分類正確項(xiàng)置0
            errArr[predictedVals==labelMat]=0
            #計算"加權(quán)"的錯誤率
            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)前錯誤率小于當(dāng)前最小錯誤率,將當(dāng)前錯誤率作為最小錯誤率
            #存儲相關(guān)信息
            if weigthedError<minError:
                minError=weigthedError
                bestClasEst=predictedVals.copy()
                bestStump['dim']=i
                bestStump['thresh']='threshVal'
                bestStump['ineq']=inequal
    #返回最佳單層決策樹相關(guān)信息的字典,最小錯誤率,決策樹預(yù)測輸出結(jié)果
    return bestStump,minError,bestClasEst

  需要說明的是,上面的代碼包含兩個函數(shù),第一個函數(shù)是分類器的閾值過濾函數(shù),即設(shè)定某一閾值,凡是超過該閾值的結(jié)果被歸為一類,小于閾值的結(jié)果都被分為另外一類,這里的兩類依然同SVM一樣,采用+1和-1作為類別。

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

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

#完整AdaBoost算法實(shí)現(xiàn)
#算法實(shí)現(xiàn)偽代碼
#對每次迭代:
    #利用buildStump()函數(shù)找到最佳的單層決策樹
    #將最佳單層決策樹加入到單層決策樹數(shù)組
    #計算alpha
    #計算新的權(quán)重向量D
    #更新累計類別估計值
    #如果錯誤率為等于0.0,退出循環(huán)

  再來看看具體的實(shí)現(xiàn)代碼吧:

#adaBoost算法
#@dataArr:數(shù)據(jù)矩陣
#@classLabels:標(biāo)簽向量
#@numIt:迭代次數(shù)    
def adaBoostTrainDS(dataArr,classLabels,numIt=40):
    #弱分類器相關(guān)信息列表
    weakClassArr=[]
    #獲取數(shù)據(jù)集行數(shù)
    m=shape(dataArr)[0]
    #初始化權(quán)重向量的每一項(xiàng)值相等
    D=mat(ones((m,1))/m)
    #累計估計值向量
    aggClassEst=mat((m,1))
    #循環(huán)迭代次數(shù)
    for i in range(numIt):
        #根據(jù)當(dāng)前數(shù)據(jù)集,標(biāo)簽及權(quán)重建立最佳單層決策樹
        bestStump,error,classEst=buildStump(dataArr,classLabels,D)
        #打印權(quán)重向量
        print("D:",D.T)
        #求單層決策樹的系數(shù)alpha
        alpha=float(0.5*log((1.0-error)/(max(error,1e-16))))
        #存儲決策樹的系數(shù)alpha到字典
        bestStump['alpha']=alpha
        #將該決策樹存入列表
        weakClassArr.append(bestStump)
        #打印決策樹的預(yù)測結(jié)果
        print("classEst:",classEst.T)
        #預(yù)測正確為exp(-alpha),預(yù)測錯誤為exp(alpha)
        #即增大分類錯誤樣本的權(quán)重,減少分類正確的數(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)前單層決策樹的加權(quán)預(yù)測值
        aggClassEst+=alpha*classEst
        print("aggClassEst",aggClassEst.T)
        #求出分類錯的樣本個數(shù)
        aggErrors=multiply(sign(aggClassEst)!=
                    mat(classLabels).T,ones((m,1)))
        #計算錯誤率
        errorRate=aggErrors.sum()/m
        print("total error:",errorRate,"
")
        #錯誤率為0.0退出循環(huán)
        if errorRate==0.0:break
    #返回弱分類器的組合列表
    return weakClassArr

測試算法

  那么有了訓(xùn)練好的分類器,是不是要測試一下呢,畢竟訓(xùn)練錯誤率針對的是已知的數(shù)據(jù),我們需要在分類器未知的數(shù)據(jù)上進(jìn)行測試,看看分類效果。上面的訓(xùn)練代碼會幫我們保存每個弱分類器的重要信息,比如分類器系數(shù),分類器的最優(yōu)特征,特征閾值等。有了這些重要的信息,我們拿到之后,就可以對測試數(shù)據(jù)進(jìn)行預(yù)測分類了

#測試adaBoost,adaBoost分類函數(shù)
#@datToClass:測試數(shù)據(jù)點(diǎn)
#@classifierArr:構(gòu)建好的最終分類器
def adaClassify(datToClass,classifierArr):
    #構(gòu)建數(shù)據(jù)向量或矩陣
    dataMatrix=mat(datToClass)
    #獲取矩陣行數(shù)
    m=shape(dataMatrix)[0]
    #初始化最終分類器
    aggClassEst=mat(zeros((m,1)))
    #遍歷分類器列表中的每一個弱分類器
    for i in range(len(classifierArr)):
        #每一個弱分類器對測試數(shù)據(jù)進(jìn)行預(yù)測分類
        classEst=stumpClassify(dataMat,classifierArr[i]['dim'],
                                classifierArr[i]['thresh'],
                                classifierArr[i]['ineq'])
        #對各個分類器的預(yù)測結(jié)果進(jìn)行加權(quán)累加
        aggClassEst+=classifierArr[i]['alpha']*classEst
        print('aggClassEst',aggClassEst)
    #通過sign函數(shù)根據(jù)結(jié)果大于或小于0預(yù)測出+1或-1
    return sign(aggClassEst)

總結(jié)

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

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