集成算法——Adaboost代码
? ? ?集成算法是我們將不同的分類器組合起來,而這種組合結果就被稱為集成方法或者是元算法。使用集成方法時會有多種形式:可以是不同算法的集成,也可以是同意算法在不同設置下的集成,還可以是數據集不同部分分配給不同分類器之后的集成。
兩種形式:
bagging方法:從原始數據集選擇S次后得到S個新數據集,之后將某個學習算法分別作用于數據集,就得到了S個分類器,在對新的數據集進行分類時,使用這些分類器進行分類,同時,選擇分類器投票結果中最多的類別作為最后的分類結果。不同的分類器是通過串行訓練而獲得的,每個新分類器都根據已訓練出來的分類器的性能來進行訓練。分類器的權重是相等的。
例子:隨機森林
boosting方法:使用多個分類器,它是通過集中關注被已有分類器錯分的那些數據來獲得新的分類器,boosting分類的結果是基于所有分類器的加權求和結果的,權重不相等,每個權重代表的是其對應分類器在上一輪迭代中的成功度。
例子:Adaboost,GBDT
AdaBoost的思想:
? ? 1.訓練數據中的每一個樣本,并賦予一個權重,初始化為相等值,這些權重構成了向量D
? ? 2.首先在訓練數據上訓練出一個弱分類器并計算該分類器的錯誤率,然后在同一個數據集上再次訓練弱分類器。在分類器的第 ? ? 二次訓練中,將會重新調整每個樣本的權重。其中第一次分對的樣本的權重會降低,而第一次分錯的樣本的權重會提高。
? ? 3.為了從所有弱分類器中得到最終的分類結果,Adaboost為每個分類器分配了一個權重alpha,這些alpha值是基于每個弱分類器的錯誤率進行的
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
4.計算出alpha值后,可以對權重向量D進行更新,以使得那些正確分類的樣本的權重降低而錯分樣本的權重升高。
?正確分類:
錯誤分類:
計算出D之后,在進行下一輪的迭代,會不斷地重復訓練和調整權重的過程,直到訓練集錯誤率為0或者是弱分類器的數目達到用戶的指定值為止。
代碼實現:
import numpy as np import matplotlib.pyplot as plt def loadSimpData():dataMat=np.matrix([[1.,2.1],[1.5,1.6],[1.3,1.],[1.,1.],[2.,1.]])classLabels=[1.0 , 1.0 , -1.0 ,-1.0 ,1.0]return dataMat,classLabels #數組過濾 將數據分成正好相反的兩類 def stumpClassify(dataMatrix,dimen,threshVal,threshIneq): # dimen特征值 threshVal 閾值 threshIneq 代表是lt或者是gtretArray=np.ones((np.shape(dataMatrix)[0],1)) #數組元素全部設置為1if threshIneq=='lt':retArray[dataMatrix[:,dimen]<= threshVal]=-1.0else:retArray[dataMatrix[:,dimen]> threshVal]=-1.0return retArray構建單層決策樹,找到錯誤率最小的特征和索引
def buildStump(dataArr, classLabels,D): #最佳基于數據的權重向量D來定義的dataMatrix=np.mat(dataArr);labelMat=np.mat(classLabels).Tm,n=np.shape(dataMatrix)numSteps=10.0;bestStump={};bestClasEst= np.mat(np.zeros((m,1))) #bestStump空字典minError = float('inf');#初始化為無窮大,之后用于尋找可能的最小的錯誤率 for i in range(n):#所有的特征上進行遍歷# 計算出最大的步長rangeMin = dataMatrix[:,i].min();rangeMax = dataMatrix[:,i].max()stepSize = (rangeMax-rangeMin)/numSteps #最大的步長#for j in range(-1,int(numSteps)+1):#大于或小于閾值的for inequal in ['lt','gt']:threshVal=(rangeMin+float(j)*stepSize) #閾值的計算predictedVals = stumpClassify(dataMatrix,i,threshVal,inequal)#計算加權錯誤率errArr= np.mat(np.ones((m,1)))errArr[predictedVals== labelMat]=0weightedError=D.T*errArr print("split:dim %d, thresh %.2f ,thresh ineqal : %s, the weighted error is %.3f" % (i, threshVal,inequal,weightedError))# inequal 類型if weightedError<minError:minError = weightedErrorbestClasEat = predictedVals.copy()bestStump['dim']=ibestStump['thresh']=threshValbestStump['ineq']=inequalreturn bestStump,minError,bestClasEat首先第一次訓練計算出該分類器的錯誤率,然后繼續訓練,調整權重,def adaBoostTrains(dataArr,classLabels,numIt=40):weakClassArr = []m=np.shape(dataArr)[0]D=np.mat(np.ones((m,1))/m)aggClassEst=np.mat(np.zeros((m,1)))for i in range (numIt):#利用buildStump()找到最佳的單層決策樹bestStump,error,classEst = buildStump(dataArr,classLabels,D) #D 權重print("D: ",D.T)alpha=float(0.5*np.log((1.0-error)/max(error,1e-16))) #alpha公式 1e是科學計數法 max確保在沒有錯誤時除以0不會溢出bestStump['alpha']=alphaweakClassArr.append(bestStump)# 轉化為listprint("classEst:", classEst.T) #特征#權重的分布expon=np.multiply(-1*alpha*np.mat(classLabels).T,classEst)#如果分對了,則同號,分錯了異號,正好對應公式D=np.multiply(D,np.exp(expon))D=D/D.sum() # ai*yiaggClassEst += alpha*classEstprint("aggClassEst :" ,aggClassEst.T)# sign將aggClassEst轉化為[1,-1.....]的m*1的矩陣,再與特征矩陣對比,得出[1,0....],其中1為錯誤分類,轉置之后與ones相乘得到錯誤分類的個數aggErrors=np.multiply(np.sign(aggClassEst)!= np.mat(classLabels).T,np.ones((m,1)))#計算錯誤率errorRate = aggErrors.sum()/mprint("total error:",errorRate,"\n")if errorRate == 0.0 :breakreturn weakClassArr dataArr,classLabels=loadSimpData() weakClassArr,aggClassEst = adaBoostTrains(dataArr,classLabels) print(weakClassArr) print(aggClassEst)
輸出結果:
總結
以上是生活随笔為你收集整理的集成算法——Adaboost代码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 孪生网络 Siamese Network
- 下一篇: #【软件stm32cubeIDE下配置S