1. 程式人生 > >py2.7 : 《機器學習實戰》 Adaboost 2.24號:ROC曲線的繪製和AUC計算函式

py2.7 : 《機器學習實戰》 Adaboost 2.24號:ROC曲線的繪製和AUC計算函式

前言:可以將不同的分類器組合,這種組合結果被稱為整合方法  、 元演算法

使用: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