1、多類分類
二分類器只能區分兩個類別,多分類器則可以區分多余兩個類別
一些算法(比如隨機森林分類器或者朴素貝葉斯分類器)可以直接處理多分類問題,而其他的一些算法(比如SVM分類器或者線性分類器)擇時嚴格的二分類器。當然也有許多策略讓二分類器去執行多分類問題
"一對所有"(OvA)策略:創建一個將圖片分為10類(0到9)的系統的一個方法:訓練10個二分類器,每一個對應一個數字(探測器0,探測器1,探測器2,以此類推),然后當你想對某張圖片進行分類的時候,讓每一個分類器對這張圖片進行分類,選出決策分數最高的那個分類器。
“一對一”(OvO)策略:對每一對數字都訓練一個二分類器,一個分類器用來處理數字0和數字1,一個用來處理數字0和數字2,以此類推,如果有N個類,那么就需要N*(N-1)/2個分類器。讓這張圖片在這些分類器上都跑一遍,看哪個類勝出。OvO策略的主要優點是:每個分類器都只需要在訓練集的部分數據上面進行訓練。這部分數據是它所需要區分的那兩個類對應的數據。
Sklearn可以探測出你想用一個二分類器去實現多分類的任務,他會自動執行OvA(除了SVM分類器,它使用OvO)。現在讓試下SGDCLassifier
sgd_clf.fit(X_train,y_train)
sgd_clf.predict([some_digit])
SGDClassifier分類器將對數字0~9產生10個探測器,在訓練集上訓練10個二分類器,每個分類器都產生這張圖片的決策數值,選擇數值最高的那個類。
為證明這一點,可以調用decision_function()方法,會返回10個數值,每個數值對一個一個類
some_digit_scores = sgd_clf.decision_function([some_digit])
some_digit_scores
最高值是對應類別5:
np.argmax(some_digit_scores)
一個分類器訓練好之后,它會保存目標類別列表到屬性classes_中去,按照值排序。在本例子當中,在 classes_ 數組當中的每個類的索引方便地匹配了類本身,比如,索引為 5 的類恰好是類別 5 本身。但通常不會這么幸運
sgd_clf.classes_
sgd_clf.classes_[5]
現在來看下如何強制Sklearn 使用OvO策略或者OvA策略。可以使用OneVsOneClassifier類或者OneVsRestClassifer類。創建一個樣例,傳遞一個二分類器給他的構造函數。
from sklearn.multiclass import OneVsOneClassifier ovo_clf = OneVsOneClassifier(SGDClassifier(random_state = 42)) ovo_clf.fit(X_train,y_train) ovo_clf.predict([some_digit])
len(ovo_clf.estimators_)
可以看到OvO策略下對數字0~9分類會產生10*(10 -1 )/2 = 45個檢測器
使用RandomForestClassifier分類器試試:
forest_clf.fit(X_train,y_train)
forest_clf.predict([some_digit])
由於RandomForestClassifier可以直接進行多分類,因此沒必要去執行OvO或者OvA。可以調用predict_proba()可以得到樣例對應的類別的概率值的列表
forest_clf.predict_proba([some_digit])
在數組的索引 5 上的 0.8,意味着這個模型以80% 的概率估算這張圖片代表數字 5。它也認為這個圖片可能是數字 0 或者數字 3,分別都是 10% 的幾率。
現在使用交叉驗證來對SGDCLassifier進行精度評估
cross_val_score(sgd_clf,X_train,y_train,cv = 3,scoring = 'accuracy')
在所有的測試者上,他有86%的精度。如何將精度提高到90%以上呢?
from sklearn.preprocessing import StandardScaler scaler = StandardScaler() X_train_scaled = scaler.fit_transform(X_train.astype(np.float64)) cross_val_score(sgd_clf,X_train_scaled,y_train,cv = 3,scoring = 'accuracy')
2、誤差分析
使用混淆矩陣,首先要使用cross_val_predict進行預測,然后調用confusion_matrix()函數
y_train_pred = cross_val_predict(sgd_clf,X_train_scaled,y_train,cv = 3) conf_mx = confusion_matrix(y_train,y_train_pred) conf_mx
plt.matshow(conf_mx,cmap = plt.cm.gray)
plt.show()
關注下包含錯誤數據的圖像呈現,首先需要將混淆矩陣的每一個值除以相應類別圖片的總數目,並用0來填充對角線,這樣就只保留了被錯誤分類的數據。
row_sums = conf_mx.sum(axis = 1,keepdims = True)
norm_conf_mx = conf_mx/row_sums
np.fill_diagonal(norm_conf_mx,0) plt.matshow(norm_conf_mx,cmap= plt.cm.gray) plt.show()