py2.7 : 《機器學習實戰》 Adaboost 2.24號:ROC曲線的繪製和AUC計算函式
阿新 • • 發佈:2019-01-10
前言:可以將不同的分類器組合,這種組合結果被稱為整合方法 、 元演算法
使用:1.不同演算法的整合 2.同一演算法下的不同設定整合 3.不同部分分配給不同分類器的整合
演算法介紹:AdaBoost
優點:泛華錯誤率低,易編碼,可以應用在大部分的分類器上,無引數調整
缺點:對離群點敏感(離群點是指一個時間序列中,遠離序列的一般水平的極端大值和極端小值)
運用資料型別:數值型或者標稱型資料
7-1 :單層決策樹生成函式
# -*- coding: utf-8 -*- from numpy import * def loadSimpData(): datMat = 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 datMat , classLabels #通過閾值比較對資料進行分類函式,在閾值一邊的會分到-1類別,另一邊的分到類別+1 #先全部初始化為1,然後進行過濾,不滿足不等式的變為-1 def stumpClassify(dataMatrix , dimen , threshVal , threshIneq) : retArray = ones((shape(dataMatrix)[0] , 1 )) if threshIneq == 'lt' : retArray[dataMatrix[:,dimen] <= threshVal] = -1.0 else: retArray[dataMatrix[:,dimen] > threshVal] = -1.0 return retArray #遍歷上述函式所有可能輸入,找到最佳單層決策樹 def buildStump(dataArr,classLabels,D): dataMatrix = mat(dataArr) ; labelMat = mat(classLabels).T m,n = shape(dataMatrix) numSetps = 10.0 #在特徵的所有可能值上進行遍歷 bestStump = {} #儲存給定權重D得到的最佳單層決策樹 bestClasEst = mat(zeros((m,1))) minError = inf #初始化為無窮大,找最小錯誤率 for i in range(n) :#在特徵上進行遍歷,計算最大最小值來求得合理步長 rangeMin = dataMatrix[:,i].min() ; rangeMax = dataMatrix[:,i].max(); stepSize = (rangeMax-rangeMin)/numSetps for j in range(-1,int(numSetps)+1): for inequal in ['lt' , 'gt'] :#大於小於切換不等式 threshVal = (rangeMin+float(j)*stepSize) predictedVals = stumpClassify(dataMatrix,i,threshVal,inequal) errArr = mat(ones((m,1))) #如果預測值≠真實值,為1 errArr[predictedVals==labelMat] = 0 weightedError = D.T * errArr #相乘求和得到錯誤權重數值 if weightedError < minError : minError = weightedError bestClasEst = predictedVals.copy() bestStump['dim'] = i bestStump['thresh'] = threshVal bestStump['ineq'] = inequal return bestStump , minError , bestClasEst
執行
# -*- coding: utf-8 -*-
import adaboost
from numpy import *
D = mat(ones((5,1))/5)
dataMat , classLabels = adaboost.loadSimpData()
print adaboost.buildStump(dataMat,classLabels,D)
效果:
({'dim': 0, 'ineq': 'lt', 'thresh': 1.3}, matrix([[ 0.2]]), array([[-1.], [ 1.], [-1.], [-1.], [ 1.]]))
7.4 完整AdaBoost訓練過程:
def adaBoostTrainDS(dataArr,classLabels,numIt = 40) : #=資料集,類別標籤,迭代次數numIt weakClassArr = [] m = shape(dataArr)[0] #m是資料的數目 D = mat(ones((m,1))/m) #每個資料點的權重 aggClassEst = mat(zeros((m,1))) #記錄每個資料點的類別估計累計值 for i in range(numIt): #如果在迭代次數內錯誤率為0則退出 bestStump , error , classEst = buildStump(dataArr,classLabels,D) #返回利用D得到的最小錯誤率單層決策樹,最小的錯誤率和估計的類別向量 print "D:" , D.T alpha = float(0.5*log((1.0-error)/max(error,1e-16))) #分類器分配的權重,這裡比較是為了防止0出現溢位 bestStump['alpha'] = alpha weakClassArr.append(bestStump) print "classEst : " , classEst.T expon = multiply(-1*alpha*mat(classLabels).T , classEst) D = multiply(D,exp(expon)) D = D/D.sum() aggClassEst += alpha*classEst print "aggClassEst : " , aggClassEst.T aggErrors = multiply(sign(aggClassEst)!=mat(classLabels).T , ones((m,1))) errorRate = aggErrors.sum() / m print "Total error : " , errorRate , "\n" if errorRate ==0.0 : break return weakClassArr
樣例輸入:
# -*- coding: utf-8 -*-
import adaboost
from numpy import *
D = mat(ones((5,1))/5)
dataMat , classLabels = adaboost.loadSimpData()
lassifierArray = adaboost.adaBoostTrainDS(dataMat,classLabels,9)
print lassifierArray
樣例輸出:
D: [[ 0.2 0.2 0.2 0.2 0.2]]
classEst : [[-1. 1. -1. -1. 1.]]
aggClassEst : [[-0.69314718 0.69314718 -0.69314718 -0.69314718 0.69314718]]
Total error : 0.2
D: [[ 0.5 0.125 0.125 0.125 0.125]]
classEst : [[ 1. 1. -1. -1. -1.]]
aggClassEst : [[ 0.27980789 1.66610226 -1.66610226 -1.66610226 -0.27980789]]
Total error : 0.2
D: [[ 0.28571429 0.07142857 0.07142857 0.07142857 0.5 ]]
classEst : [[ 1. 1. 1. 1. 1.]]
aggClassEst : [[ 1.17568763 2.56198199 -0.77022252 -0.77022252 0.61607184]]
Total error : 0.0
[{'dim': 0, 'ineq': 'lt', 'thresh': 1.3, 'alpha': 0.6931471805599453}, {'dim': 1, 'ineq': 'lt', 'thresh': 1.0, 'alpha': 0.9729550745276565}, {'dim': 0, 'ineq': 'lt', 'thresh': 0.90000000000000002, 'alpha': 0.8958797346140273}]
可以看到第一次的D是都初始化為了1/5 , 且第一個被錯分了,提高概率,正確的降低 , 以此類推
def adaClassify(datToClass,classifierArr):#基於adaboost的分類
dataMatrix = mat(datToClass)
m = shape(dataMatrix)[0]
aggClassEst = mat(zeros((m,1)))
for i in range(len(classifierArr)): #訓練多個弱分類器
classEst = stumpClassify(dataMatrix,classifierArr[i]['dim'],
classifierArr[i]['thresh'],
classifierArr[i]['ineq'])
aggClassEst += classifierArr[i]['alpha']*classEst
print aggClassEst
return sign(aggClassEst)
7-5 ROC曲線繪製和AUC計算函式
def plotROC(predStrengths, classLabels):
import matplotlib.pyplot as plt
cur = (1.0,1.0) #保留繪製游標的位置
ySum = 0.0 #計算AUC的值
numPosClas = sum(array(classLabels)==1.0)
yStep = 1/float(numPosClas);
xStep = 1/float(len(classLabels)-numPosClas)
sortedIndicies = predStrengths.argsort()#獲取排序索引
fig = plt.figure()
fig.clf()
ax = plt.subplot(111)
#畫圖
for index in sortedIndicies.tolist()[0]:
if classLabels[index] == 1.0:
delX = 0;
delY = yStep;
else:
delX = xStep;
delY = 0;
ySum += cur[1]
ax.plot([cur[0],cur[0]-delX],[cur[1],cur[1]-delY], c='b')
cur = (cur[0]-delX,cur[1]-delY)
ax.plot([0,1],[0,1],'b--')
plt.xlabel('False positive rate'); plt.ylabel('True positive rate')
plt.title('ROC curve for AdaBoost horse colic detection system')
ax.axis([0,1,0,1])
plt.show()
print "the Area Under the Curve is: ",ySum*xStep