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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

《机器学习实战》chapter 07利用AdaBoosting元算法提高分类性能

發布時間:2025/3/16 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 《机器学习实战》chapter 07利用AdaBoosting元算法提高分类性能 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

第一部分:集成方法介紹

集成方法通過組合多個分類器的分類結果,獲得了比簡單分類器更好的分類結果

1、bagging,通過隨機抽樣的替換方式,得到了與原始數據集規模一樣的數據集。

? ? 在S個數據集建好以后,將某個學習算法分別作用于每個數據集就得到了S個分類器。當我們對新數據進行分類時,就可以應用這S個分類器進行分類。與此同時,選擇分類投票結果中最多的類別作為最后的分類結果。

2、boosting,在bagging的思路上更進一步,它在數據集上順序應用了多個不同的分類器

? ? boosting中,不同的分類器是通過穿行訓練而獲得的,每個新分類器都根據已訓練出的分類器的分類性能來進行訓練。boosting是通過集中關注被已有分類器錯分的那些數據來獲得新的分類器。

? ? 運行過程:訓練數據中的每個樣本,并賦予其一個權重,這些權重構成了向量D。一開始,這些權重都初始化成相等值。首先在訓練數據上訓練出一個弱分類器并計算該分類器的錯誤率,然后在同一數據集上再次訓練弱分類器。在分類器的第二次訓練當中,將會重新調整每個樣本的權重,其中第一次分類正確的樣本的權重會降低,而第一次分錯的樣本的權重將會提高。為了從所有弱分類器中得到最終的分類結果,AdaBoosting為每一個分類器都分配了一個權重值alpha,這些alpha值是基于每個弱分類器的錯誤率來計算的。錯誤率的計算方法如下:


計算出alpha值之后可以對權重向量D進行更新,以使得那些正確分類的樣本的權重降低而錯分樣本的權重升高。D的計算方法如下:

如果某個樣本被正確分類,那么該樣本的權重更改為:


而如果耨個樣本被錯分,那么該樣本的權重更改為:


3、隨機森林(后補。。。)

第二部分:基于單層決策樹的AdaBoost方法

1、基于單層決策樹構建弱分類器

# 加載一個簡單的數據集 def loadSimpleData():dataMat = matrix([[1.0, 2.1],[2.0, 1.1],[1.3, 1.0],[1.0, 1.0],[2.0, 1.0]])classLabels = [1.0, 1.0, -1.0, -1.0, 1.0]return dataMat, classLabels# 利用單層決策樹(樹樁)分類 def stumpClassify(dataMatrix, dimen, threshVal, threshIneq):# 創建一個與數據集樣本數量相同的列向量,初始化為1retArray = ones((shape(dataMatrix)[0], 1))if threshIneq == 'lt':# <= threshVal的歸為-1類, 其余為1類retArray[dataMatrix[:, dimen] <= threshVal] = -1.0else:# 》 threshVal的歸為-1類, 其余為1類retArray[dataMatrix[:, dimen] > threshVal] = -1.0return retArray# 構建單層決策樹(數據集,類別標簽,迭代次數) def buildStump(dataArr, classLabels, D):"""將最小錯誤率minError設為正無窮對數據集中的每一個特征(第一層循環):對每個步長(第二層循環):對每個不等號(第三層循環):建立一棵單層決策樹并加以利用加權數據集對他進行測試如果錯誤率低于minError,則將當前單層決策樹設為最佳單層決策返回最佳單層決策樹"""dataMat = mat(dataArr)labelMat = mat(classLabels).Tm, n = shape(dataMat)# 步數(所有可能值范圍)numSteps = 10.0# 保存給定權重向量D所得到的最佳單層決策樹bestStump = {}# 最佳分類獲得的類別向量(列向量)bestClassEst = mat(zeros((m, 1)))# 初始化最小錯誤率為正無窮minError = inf# 對數據集中的每一個特征,按列循環for i in range(n):rangeMin = dataMat[:, i].min()rangeMax = dataMat[:, i].max()# 步長stepSize = (rangeMax - rangeMin) / numSteps# 對每個步長for j in range(-1, int(numSteps) + 1):# 對每個不等號,lt: less than; gt: great thanfor inequal in ['lt', 'gt']:# 計算閾值,初值 + 步數 * 步長threshVal = (rangeMin + float(j) * stepSize)# 利用單層決策樹返回預測分類結果predictedVals = stumpClassify(dataMat, i, threshVal, inequal)# 分類結果的正誤,1分類錯誤,0正確,初始化為全1errArr = mat(ones((m, 1)))# 把正確分類的置為0errArr[predictedVals == labelMat] = 0# 計算加權錯誤率,錯誤向量 dot* 權重向量,weightedError是一個值:[[ 0.57142857]]weightedError = D.T * errArr# print("weightedError : ", weightedError)# 更新最小加權錯誤率if weightedError < minError:minError = weightedErrorbestClassEst = predictedVals.copy()bestStump['dim'] = ibestStump['thresh'] = threshValbestStump['ineq'] = inequalreturn bestStump, minError, bestClassEst

2、基于單層決策樹的AdaBoost訓練過程

# 基于單層決策樹的AdaBoost訓練過程 def adaBoostTrainDS(dataArr, classLabels, numIt=40):"""對每次迭代:利用buildStump()函數找到最佳的單層決策樹將最佳單層決策樹加入到單層決策樹組計算alpha計算新的權重向量D更新累計類別估計值如果錯誤率等于0.0,則退出循環"""# 聲明單層決策樹組保存每一次迭代的最佳DS(decision stump)weakClassArr = []m = shape(dataArr)[0]# 初始化權重向量(列),保存每個數據的權重,初始時每個數據點的權重相同D = mat(ones((m, 1)) / m)# 初始化aggClassEst(列向量),保存每個數據點的類別累計估計值aggClassEst = mat(zeros((m, 1)))# 訓練numIt次或者直到錯誤率為0for i in range(numIt):"""利用buildStump()函數找到最佳的單層決策樹"""# 用buildStump獲得最小錯誤率的單層決策樹,最小錯誤率以及估計的類別向量bestStump, error, classEst = buildStump(dataArr, classLabels, D)print("D : ", D.T)"""計算alpha,表示本次單層決策樹輸出結果的權重"""# max(error, 1e-16)確保在沒有錯誤時不會發生除零溢出alpha = float(0.5 * log((1.0 - error) / max(error, 1e-16)))# 把alpha值加入到bestStump字典中bestStump['alpha'] = alpha"""將最佳單層決策樹加入到單層決策樹組"""weakClassArr.append(bestStump)print("classEst : ", classEst.T)"""計算新的權重向量D"""# 如果當前樣本被正確分類((1 * 1)or(-1 * -1)) = 1,乘參數-1 = -alpha,權重下降# 如果當前樣本被錯分((1 * -1)or(-1 * 1)) = -1,乘以參數-1 = alpha,權重升高expon = multiply(-1 * mat(classLabels).T, classEst) * alpha# 其實是一個迭代的過程D_i+1 = D_i * exp(expon)D = multiply(D, exp(expon))D = D / D.sum()# 運行時類別估計值aggClassEst += alpha * classEstprint("aggClassEst : ", aggClassEst.T)# 使用sign進行二分類aggErrors = multiply(sign(aggClassEst) != mat(classLabels).T, ones((m, 1)))errorRate = aggErrors.sum() / mprint("total error : ", errorRate)"""在訓練錯誤率達到0,提前結束循環"""if errorRate == 0.0:breakreturn weakClassArr

3、測試算法:基于AdaBoost的分類

# adaBOost分類函數 def adaClassify(dataToClass, classifierArr):dataMat = mat(dataToClass)m = shape(dataMat)[0]aggClassEst = mat(zeros((m, 1)))for i in range(len(classifierArr)):classEst = stumpClassify(dataMat, classifierArr[i]['dim'], classifierArr[i]['thresh'], classifierArr[i]['ineq'])aggClassEst += classifierArr[i]['alpha'] * classEstprint(aggClassEst)return sign(aggClassEst)# test dataMat, classLabels = loadSimpleData() classifierArr = adaBoostTrainDS(dataMat, classLabels, 30) print(adaClassify([[5, 5], [0, 0]], classifierArr))

4、示例:在一個難數據集上應用AdaBoost,數據集采用第4章給出的馬疝病數據集。

  • 加載數據
# 加載數據 def loadDataSet(fileName):# 計算特征個數(如果用下面的fr來讀,那么訓練集和測試集中就少了一個樣本數據)numFeat = len(open(fileName).readline().split('\t'))dataMat = []labelMat = []fr = open(fileName)for line in fr.readlines():lineArr = []curLine = line.strip().split('\t')for i in range(numFeat - 1):# 不能split()后直接append,應該先用float格式化數據,統一數據類型lineArr.append(float(curLine[i]))dataMat.append(lineArr)labelMat.append(float(curLine[-1]))return dataMat, labelMat
  • 測試
# test dataMat, classLabels = loadDataSet("horseColicTraining2.txt") testMat, testLabels = loadDataSet('horseColicTest2.txt') classifierArr = adaBoostTrainDS(dataMat, classLabels, 50) predicted = adaClassify(testMat, classifierArr) errArr = mat(ones((67, 1))) errCount = errArr[predicted != mat(testLabels).T].sum() print("錯誤率: ", errCount / 67)


總結

以上是生活随笔為你收集整理的《机器学习实战》chapter 07利用AdaBoosting元算法提高分类性能的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。