1. 程式人生 > >使用sklearn做手寫數字識別 模型:AdaBoostClassifier

使用sklearn做手寫數字識別 模型:AdaBoostClassifier

1.載入資料集 導包

import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets,cross_validation,ensemble

def load_classification_data():
    '''
    載入分類模型使用的資料集
    return 一個元組,依次為:訓練樣本集 測試樣本集 測試樣本的標記 測試樣本的標記
    '''
    digits=datasets.load_digits()
    return cross_validation.train_test_split(digits.data,digits.target,test_size=0.25,random_state=0,stratify=digits.target)

AdaBoostClassifier這個模型中,幾個比較重要的引數:學習器的數量,學習率,選用何種分類器,選用哪種演算法。

2.測試AdaBoostClassifier的預測效能隨基礎分類器的數量的影響

def test_AdaBoostClassifier(*data):
    '''
    測試AdaBoostClassifier的用法 ,繪製測試AdaBoostClassifier的預測效能隨基礎分類器的數量的影響
    param data 可變引數 一個元組 訓練樣本集.測試樣本集,訓練樣本的標記.測試樣本的標記
    return None
    '''
    x_train,x_test,y_train,y_test=data
    clf = ensemble.AdaBoostClassifier(learning_rate=0.1)#引數 學習率
    clf.fit(x_train,y_train)
    #繪圖
    fig = plt.figure()
    ax=fig.add_subplot(111)
    estimators_nums=len(clf.estimators_)#學習器的數量
    x=range(1,estimators_nums+1)
    ax.plot(list(x),list(clf.staged_score(x_train,y_train)),label='train score')#返回X,y的分階段分數。
    ax.plot(list(x),list(clf.staged_score(x_test,y_test)),label='test score')
    ax.set_xlabel('estimators num')
    ax.set_ylabel('score')
    ax.legend(loc='best')
    ax.set_title('AdaBoostClassifier')
    plt.show()


X_train,X_test,y_train,y_test=load_classification_data()#獲取分類資料
test_AdaBoostClassifier(X_train,X_test,y_train,y_test)

總結:隨著演算法的推進,每一輪迭代都產生一個新的個體分類器被整合。此時整合分類器的訓練誤差和測試誤差都在下降。當個體分類,數量達到一定值時,整合分類器的預測準確率再一定範圍內波動比較穩定,這證明:整合學習能很好地抵抗過擬合 訓練集和測試集表現相似

3.考察不同型別的個體分類器的影響  策樹個體分類器以及高斯分佈貝葉斯分類器的差別

def test_AdaBoostClassifier_base_classifier(*data):
    '''
    測試AdaBoostClassifier的用法,繪製測試AdaBoostClassifier的預測效能隨基礎分類器數量的影響
    
    :param data:可變引數。它是一個元組,這裡要求其元素依次為:訓練樣本集.測試樣本集,訓練樣本的標記.測試樣本的標記
    return: None
    '''
    from sklearn.naive_bayes import GaussianNB  #樸素貝葉斯分類器
    X_train,X_test,y_train,y_test=data
    fig=plt.figure(figsize=(10,20))
    ax=fig.add_subplot(2,1,1)
    ###############預設的個體分類器################
    clf=ensemble.AdaBoostClassifier(learning_rate=0.1)
    clf.fit(X_train,y_train)
    #繪圖
    estimators_num=len(clf.estimators_)#學習器數量
    X=range(1,estimators_num+1)
    ax.plot(list(X),list(clf.staged_score(X_train,y_train)),label='Traing score')
    ax.plot(list(X),list(clf.staged_score(X_test,y_test)),label='Testing score')
    ax.set_xlabel('estimators num')
    ax.set_ylabel('score')
    ax.legend(loc='lower right')
    ax.set_ylim(0,1)
    ax.set_title('AdaBoostClassifier with Decision Tree')
    ###############Gaussian  Naive  Bayes  個體分類器  ######
    ax=fig.add_subplot(2,1,2)
    clf=ensemble.AdaBoostClassifier(learning_rate=0.1,base_estimator=GaussianNB())
    clf.fit(X_train,y_train)
    #繪圖
    estimators_num=len(clf.estimators_)#學習器數量
    X=range(1,estimators_num+1)
    ax.plot(list(X),list(clf.staged_score(X_train,y_train)),label='Traing score')
    ax.plot(list(X),list(clf.staged_score(X_test,y_test)),label='Testing score')
    ax.set_xlabel('estimators num')
    ax.set_ylabel('score')
    ax.legend(loc='lower right')
    ax.set_ylim(0,1)
    ax.set_title('AdaBoostClassifier with Decision Tree')
    plt.show()

test_AdaBoostClassifier_base_classifier(X_train,X_test,y_train,y_test)

總結:預設分類器是決策樹,後來使用高斯樸素貝葉斯,由於高斯分佈bayes個體分類器本身就是強分類器,所以它沒有一個明顯的預測準確率提升的過程,整體曲線都比較平緩

4.學習率 預設採用了SAMME.R演算法

def test_AdaBoostClassifier_learn_rate(*data):
    '''
    測試AdaBoostClassifier 分類器數量一定的情況下 不同的學習率的影響
    param data 可變引數。它是一個元組,這裡要求其元素依次為:訓練樣本集.測試樣本集,訓練樣本的標記.測試樣本的標記
    return None
    '''
    x_train,x_test,y_train,y_test = data
    learn_rates=np.linspace(0.01,1)
    fig=plt.figure()
    ax=fig.add_subplot(1,1,1)
    train_score = []
    test_score=[]
    for rate in learn_rates:
        clf = ensemble.AdaBoostClassifier(learning_rate=rate,n_estimators=500)
        clf.fit(x_train,y_train)
        train_score.append(clf.score(x_train,y_train))
        test_score.append(clf.score(x_test,y_test))
    ax.plot(learn_rates,train_score,label="train_score")
    ax.plot(learn_rates,test_score,label="test_score")
    ax.set_xlabel("learn_rate")
    ax.set_ylabel("score")
    ax.legend(loc="best")
    ax.set_title("AdaBoostClassifier")
    plt.show()
    
test_AdaBoostClassifier_learn_rate(X_train,X_test,y_train,y_test)

總結:當學習率較小時 測試準確率和訓練準確率隨著學習率的增大而緩慢上升,但超過0.7後迅速下降 通常較小的學習率會要求更多的弱學習器,比較小的學習率更能帶來更小的測試誤差 推薦<=1 同時選擇一個很大的學習器數量

5.SAMME演算法 

def test_AdaBoostClassifier_learn_rate(*data):
    '''
    測試AdaBoostClassifier 分類器數量一定的情況下 不同的學習率的影響
    param data 可變引數。它是一個元組,這裡要求其元素依次為:訓練樣本集.測試樣本集,訓練樣本的標記.測試樣本的標記
    return None
    '''
    x_train,x_test,y_train,y_test = data
    learn_rates=np.linspace(0.01,1)
    fig=plt.figure()
    ax=fig.add_subplot(1,1,1)
    train_score = []
    test_score=[]
    for rate in learn_rates:
        clf = ensemble.AdaBoostClassifier(learning_rate=rate,n_estimators=500,algorithm='SAMME')
        clf.fit(x_train,y_train)
        train_score.append(clf.score(x_train,y_train))
        test_score.append(clf.score(x_test,y_test))
    ax.plot(learn_rates,train_score,label="train_score")
    ax.plot(learn_rates,test_score,label="test_score")
    ax.set_xlabel("learn_rate")
    ax.set_ylabel("score")
    ax.legend(loc="best")
    ax.set_title("AdaBoostClassifier")
    plt.show()
    
test_AdaBoostClassifier_learn_rate(X_train,X_test,y_train,y_test)