评估模型的一个好方法是使用交叉验证,就像在第2章中所做的那样。
实现交叉验证
有时您需要对交叉验证过程进行更多的控制,而这些控制是超出cross_val_score()和类似函数提供控制。在这些情况下,您可以自己实现交叉验证;其实很简单。下面的代码与前面的cross_val_score()代码大致相同,并输出相同的结果:
from sklearn.model_selection import StratifiedKFold from sklearn.base import clone skfolds = StratifiedKFold(n_splits=3, random_state=42) for train_index, test_index in skfolds.split(X_train, y_train_5): clone_clf = clone(sgd_clf) X_train_folds = X_train[train_index] y_train_folds = (y_train_5[train_index]) X_test_fold = X_train[test_index] y_test_fold = (y_train_5[test_index]) clone_clf.fit(X_train_folds, y_train_folds) y_pred = clone_clf.predict(X_test_fold) n_correct = sum(y_pred == y_test_fold) print(n_correct / len(y_pred)) # prints 0.9502, 0.96565 and 0.96495
StratifiedKFold 类执行分层抽样,来生成包含每个类的代表性比率的折叠。在每次迭代中,代码创建创建分类器的克隆,训练在训练折叠上的克隆,并对测试折叠进行预测。然后计算正确预测的数量并输出正确预测的比率。
让我们使用cross_val_score()函数来使用K-折交叉验证来评估您的SGDClassifier模型,我们这里使用三个折叠。记住,K-折交叉验证意味着将训练集分成K-折叠(在本例中为3),然后作出预测,并在每一个折叠上,使用其余折叠上训练的模型来进行评估它们(见第2章):
>>> from sklearn.model_selection import cross_val_score
>>> cross_val_score(sgd_clf, X_train, y_train_5, cv=3, scoring="accuracy")
array([ 0.9502 , 0.96565, 0.96495])
哇!在所有交叉验证折叠上,准确度超过95%(正确预测的比率)?这看起来很神奇,不是吗?在你太兴奋之前,让我们看看一个非常愚蠢的分类器,只是对“非-5”类别的图片进行分类:
from sklearn.base import BaseEstimator
class Never5Classifier(BaseEstimator):
def fit(self, X, y=None):
pass
def predict(self, X):
return np.zeros((len(X), 1), dtype=bool)
你能猜到这个模型的准确性吗?让我们来看看:
>>> never_5_clf = Never5Classifier()
>>> cross_val_score(never_5_clf, X_train, y_train_5, cv=3, scoring="accuracy")
array([ 0.909 , 0.90715, 0.9128 ])
没错,它的准确率超过了90% !
这说明了为什么精度通常不是用于分类器的首选性能度量,特别是在处理倾斜的数据集时[skewed datasets](例如,当某些类比其他类更频繁时)。