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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

sklearn综合示例5:多分类分类器

發(fā)布時間:2024/1/23 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 sklearn综合示例5:多分类分类器 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

二元分類器在兩個類中區(qū)分,而多類分類器(也稱為多項分類器)可以區(qū)分兩個以上的類。有一些算法(如隨機森林分類器或樸素貝葉斯分類器)可以直接處理多個類。也有一些嚴格的二元分類器(如支持向量機分類器或線性分類器)。但是,有多種策略可以讓你用幾個二元分類器實現(xiàn)多類分類的目的。

我們這里使用的是mnist數(shù)據(jù)集。

OVR
要創(chuàng)建一個系統(tǒng)將數(shù)字圖片分為10類(從0到9),一種方法是訓練10個二元分類器,每個數(shù)字一個(0檢測器、1檢測器、2檢測器,以此類推)。然后,當你需要對一張圖片進行檢測分類時,獲取每個分類器的決策分數(shù),哪個分類器給分最高,就將其分為哪個類。這稱為一對剩余(OvR)策略,也稱為一對多(oneversusall)。

OVO
另一種方法是為每一對數(shù)字訓練一個二元分類器:一個用于區(qū)分0和1,一個區(qū)分0和2,一個區(qū)分1和2,以此類推。這稱為一對一(OvO)策略。如果存在N個類別,那么這需要訓練N×(N1)/2個分類器。對于MNIST問題,這意味著要訓練45個二元分類器!當需要對一張圖片進行分類時,你需要運行45個分類器來對圖片進行分類,最后看哪個類獲勝最多。OvO的主要優(yōu)點在于,每個分類器只需要用到部分訓練集對其必須區(qū)分的兩個類進行訓練。

有些算法(例如支持向量機分類器)在數(shù)據(jù)規(guī)模擴大時表現(xiàn)糟糕。對于這類算法,OvO是一個優(yōu)先的選擇,因為在較小訓練集上分別訓練多個分類器比在大型數(shù)據(jù)集上訓練少數(shù)分類器要快得多。但是對大多數(shù)二元分類器來說,OvR策略還是更好的選擇。ScikitLearn可以檢測到你嘗試使用二元分類算法進行多類分類任務(wù),它會根據(jù)情況自動運行OvR或者OvO。我們用sklearn.svm.SVC類來試試SVM分類器:

import numpy as np import pandas as pd import matplotlib.pyplot as plt

二分類模型

我們先準備好數(shù)據(jù):

from sklearn.datasets import fetch_openml mnist = fetch_openml('mnist_784', version=1) X,y = mnist['data'], mnist['target']X_train, X_test = X[:6000], X[6000:] y_train, y_test = y[:6000].astype(np.uint8), y[6000:].astype(np.uint8)

數(shù)據(jù)準備好了,我們開始訓練模型:

from sklearn.svm import SVC svm_clf = SVC() svm_clf.fit(X_train, y_train) SVC()

OK,模型訓練好了,我們預測幾個數(shù)據(jù):

svm_clf.predict([X[0], X[1]]) array([5, 0], dtype=uint8) print(y[0], y[1]) 5 0

完美,預測正確。

這段代碼使用原始目標類0到9(y_train)在訓練集上對SVC進行訓練,而不是以“5”和“剩余”作為目標類(y_train_5),然后做出預測(在本例中預測正確)。而在內(nèi)部,ScikitLearn實際上訓練了45個二元分類器,獲得它們對圖片的決策分數(shù),然后選擇了分數(shù)最高的類。

要想知道是不是這樣,可以調(diào)用decision_function()方法。它會返回10個分數(shù),每個類1個,而不再是每個實例返回1個分數(shù)

some_scores = svm_clf.decision_function([X[1]]) print(some_scores) [[ 9.31124939 0.70612005 6.21459611 4.98107511 -0.29750684 8.277479743.82932284 1.74975607 3.81848706 6.05566815]]

我們可以看出,第0個結(jié)果的分數(shù)最高,所以分類結(jié)果為0。

如果想要強制ScikitLearn使用一對一或者一對剩余策略,可以使用OneVsOneClassifier或OneVsRestClassifier類。只需要創(chuàng)建一個實例,然后將分類器傳給其構(gòu)造函數(shù)(它甚至不必是二元分類器)。

from sklearn.multiclass import OneVsRestClassifier ovr_clf = OneVsRestClassifier(SVC()) ovr_clf.fit(X_train, y_train) ovr_clf.predict([X[0]]) array([5], dtype=uint8)

多分類模型

上述方式使用的是一個二分類模型來計算多分類問題,我們也可以直接使用SGDClassifier, RandomForestClassifer等可用于多分類的模型:

from sklearn.linear_model import SGDClassifier sgd_clf = SGDClassifier() sgd_clf.fit(X_train, y_train) sgd_clf.predict([X[0]]) array([5], dtype=uint8)

我們看一下分數(shù):

sgd_clf.decision_function([X[0]]) array([[-562212.94461254, -707645.64712029, -293553.98530211,-55603.9170907 , -842804.94696506, 41561.46574389,-642257.63484493, -793582.58056233, -381185.27236082,-359218.48451935]])

模型好像相當自信,除了5以為,其它score都是負數(shù)。

我們再看一下準確率:

from sklearn.model_selection import cross_val_score cross_val_score(sgd_clf, X_train, y_train, cv=3, scoring='accuracy') array([0.8595, 0.868 , 0.8625])

所有的測試折疊上都超過了85%。如果是一個純隨機分類器,準確率大概是10%,所以這個結(jié)果不是太糟,但是依然有提升的空間。例如,將輸入進行簡單縮放可以將準確率稍為提高:

from sklearn.preprocessing import StandardScaler scaler = StandardScaler() X_train_scaler = scaler.fit_transform(X_train.astype(np.float64)) cross_val_score(sgd_clf, X_train_scaler, y_train, cv=3, scoring='accuracy') array([0.867, 0.898, 0.889])

多分類問題的誤差分析

首先看看混淆矩陣。就像之前做的,使用cross_val_predict()函數(shù)進行預測,然后調(diào)用confusion_matrix()函數(shù):

from sklearn.model_selection import cross_val_predict from sklearn.metrics import confusion_matrix y_train_pred = cross_val_predict(sgd_clf, X_train_scaler, y_train, cv=3) confusion_matrix = confusion_matrix(y_train, y_train_pred) print(confusion_matrix) [[570 0 3 2 1 11 3 0 2 0][ 0 633 8 2 1 6 0 1 18 2][ 10 8 499 10 9 4 11 9 18 3][ 3 5 21 512 1 36 1 8 11 10][ 4 2 8 0 557 2 9 7 10 24][ 5 6 5 25 14 411 10 1 24 13][ 4 4 6 0 5 7 578 1 3 0][ 3 5 9 3 10 0 1 575 2 43][ 3 18 14 17 4 10 8 3 461 13][ 7 4 6 8 17 3 0 29 8 519]]

我們可以看到數(shù)字主要集中在對角線,說明效果還是比較理想的。

我們使用更直觀的圖線方式來看一下混淆矩陣:

plt.matshow(confusion_matrix, cmap=plt.cm.gray) plt.show <function matplotlib.pyplot.show(close=None, block=None)>

數(shù)字5看起來暗一點,這以為著數(shù)據(jù)集中被判斷為5的照片比較少,有可能是5真的少,也有可能我們把5分到了其它類。所以我們看一下錯誤率:

row_sums = confusion_matrix.sum(axis=1, keepdims=True) nor_conf_mx = confusion_matrix / row_sums

用0填充對角線,只保留錯誤:

np.fill_diagonal(nor_conf_mx, 0) plt.matshow(nor_conf_mx, cmap=plt.cm.gray) plt.show()

現(xiàn)在可以清晰地看到分類器產(chǎn)生的錯誤種類了。記住,每行代表實際類,而表示預測類。第5列看起來非常亮,說明有許多圖片被錯誤地分類為數(shù)字5了。

分析混淆矩陣通常可以幫助你深入了解如何改進分類器。通過上圖來看,你的精力可以花在改進數(shù)字5的分類錯誤上。例如,可以試著收集更多看起來像數(shù)字8的訓練數(shù)據(jù),以便分類器能夠?qū)W會將它們與真實的數(shù)字區(qū)分開來。

反正,發(fā)現(xiàn)問題后,你可以通過各種方式來解決這個問題,比如檢查樣本,把樣本一個一個打印出來。你可能發(fā)現(xiàn)樣本中的3和5非常類型。畢竟我們這里使用的是線性分類器,一些寫的不規(guī)范的3和5很容易被混淆。

總結(jié)

以上是生活随笔為你收集整理的sklearn综合示例5:多分类分类器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。