# 多类分类器
from sklearn.datasets import fetch_openml
minst = fetch_openml('mnist_784',version=1)
X,y = minst["data"],minst["target"]
X_train,X_test,y_train,y_test = X[:60000],X[60000:],y[:60000],y[60000:]
some_digit = X[0]
多类分类器(也称为多项分类器)可以区分两个以上的类。有一些算法(如随机森林分类器或朴素贝叶斯分类器)可以直接处理多个类。也有一些严格的二元分类器(如支持向量机分类器或线性分类器)。
使用二元分类器实现多类分类的策略,比如要创建一个系统将数字图片分为10类(从0到9)
有些算法(例如支持向量机分类器)在数据规模扩大时表现糟糕。对于这类算法,OvO是一个优先的选择,因为在较小训练集上分别训练多个分类器比在大型数据集上训练少数分类器要快得多。但是对大多数二元分类器来说,OvR策略还是更好的选择。Scikit-Learn可以检测到你尝试使用二元分类算法进行多类分类任务,它会根据情况自动运行OvR或者OvO。现在用sklearn.svm.SVC类来试试SVM分类器:
from sklearn.svm import SVC
svm_clf = SVC()
svm_clf.fit(X_train,y_train)
svm_clf.predict([some_digit])
使用原始目标类0到9(y_train)在训练集上对SVC进行训练,然后做出预测。
在内部,Scikit-Learn实际上训练了45个二元分类器,获得它们对图片的决策分数,然后选择了分数最高的类。
可以通过调用decision_function()方法,查看返回的10个分数,每个类1个,而不再是每个实例返回1个分数:
import numpy as np
some_digit_scores = svm_clf.decision_function([some_digit])
print(some_digit_scores) # 查看10个分数
# [[ 1.72501977 2.72809088 7.2510018 8.3076379 -0.31087254 9.3132482 1.70975103 2.76765202 6.23049537 4.84771048]]
print(np.argmax(some_digit_scores)) # 查看最高分对应的索引,5
print(svm_clf.classes_) #查看所有类别.['0' '1' '2' '3' '4' '5' '6' '7' '8' '9'].当训练分类器时,目标类的列表会存储在classes_属性中,按值的大小排序.本例是刚好索引跟类别一样
强制Scikit-Learn使用一对一或者一对剩余策略,可以使用OneVsOneClassifier或OneVsRestClassifier类。
只需要创建一个实例,然后将分类器传给其构造函数(不必是二元分类器)。
例如,下面这段代码使用OvR策略,基于SVC创建了一个多类分类器:
from sklearn.multiclass import OneVsRestClassifier
ovr_clf = OneVsRestClassifier(SVC())
ovr_clf.fit(X_train,y_train)
ovr_clf.predict([some_digit]) # array(['5'], dtype='
训练SGDClassifier,Scikit-Learn不必运行OvR或者OvO了,因为SGD分类器直接就可以将实例分为多个类。
调用decision_function()可以获得分类器将每个实例分类为每个类的概率列表:让我们看一下SGD分类器分配到的每个类
from sklearn.linear_model import SGDClassifier
sgd_clf = SGDClassifier(random_state=42)
sgd_clf.fit(X_train,y_train)
sgd_clf.predict([some_digit]) # array(['3'], dtype='
对模型进行评估
from sklearn.model_selection import cross_val_score
cross_val_score(sgd_clf,X_train,y_train,cv=3,scoring='accuracy') # array([0.87365, 0.85835, 0.8689 ])
在所有的测试折叠上都超过了85%,这个结果不是太糟,但是依然有提升的空间。例如,将输入进行简单缩放(标准化处理)可以将准确率提到89%以上:
import numpy as np
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') # array([0.8983, 0.891 , 0.9018])