分类器的性能测试。

性能测量

评估分类器比评估回归器要困难得多,因此本章将用很多篇幅来讨论这个主题,同时会涉及许多性能考核的方法。

使用交叉验证测量准确率

交叉验证是一个评估模型的好办法。

相比于Scikit-Learn提供cross_val_score()这一类交叉验证的函数,有时你可能希望自己能控制得多一些。在这种情况下,你可以自行实现交叉验证,操作也简单明了。下面这段代码与前面的cross_val_score()大致相同,并打印出相同的结果:
代码实现交叉验证

from sklearn.model_selection import StratifiedKFold
from sklearn.base import clone

skfolds = stratifiedKFold(n_splits = 3,shuffle = True ,random_state =42)

for train_index ,test_index in skfolds.split(X_train , y_train_5):
	clone_clf = clone(sgd_clf) #这里的clone()函数可以理解为克隆的意思吧,复制
	x_train_folds = X_train.iloc[train_index]
	y_train_folds = y_train_5[train_index]

	x_test_fold = x_test.iloc[test_index]
	y_test_fold = y_test[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))

stratifiedKFold可以看作一个将原数集分为测试集,和训练集的函数。
n_splits:分成多少折。
这里我们可以看看train_index 处理后的训练集的索引

print(train_index)

结果如下:

[    2     3     5 ... 59992 59996 59997]
[    0     1     3 ... 59997 59998 59999]
[    0     1     2 ... 59995 59998 59999]

得到一个二维数组。这便是StratifiedKFold

让我们来看看交叉验证的结果:

0.9669
0.91625
0.96785

每个折叠由StratifiedKFold 执行分层抽样产生。其所包含的各个类的比例符合整体比例。每个迭代会创建一个分类器的副本。用训练集对这个副本进行训练,然后用测试集进行预测。最后计算正确预测的次数,输出正确预测与预测总数的比例。

现在用cross_val_score()函数来评估SGDClassfier 模型。采用K-折交叉验证法(三个折叠)。
K-折交叉验证的意思是将训练集分解成K个折叠,然后每次留其中1个折叠进行预测,剩余的折叠用来训练。

from sklearn.model_selection import cross_val_score
cross_val_score(sgd_clf,X_train,y_train_5 , cv = 3,scoring ="accuracy")

结果如下:

array([0.9456 , 0.95195, 0.9509 ])

混淆矩阵

评估分类器性能的更好方法是混淆矩阵,其总体思路就是统计A类别实例被分成为B类别的次数。例如,要想知道分类器将数字3和数字5混淆多少次,只需要通过混淆矩阵的第5行第3列来查看。

要计算混淆矩阵,需要先有一组预测才能将其与实际目标进行比较。当然,可以通过测试集来进行预测,但是现在先不要动它(测试集最好留到项目的最后,准备启动分类器时再使用)。作为替代,可以使用cross_val_predict()函数:

from sklearn.model_selection import cross_val_predict

y_train_pred = cross_val_predict(sgd_clf , x_train , t_train , cv = 3)

cross_val_score()函数一样,cross_val_predict()函数同样执行K-折交叉验证,但返回的不是评估分数,而是每个折叠的预测。这意味着对于每个实例都可以得到一个干净的预测(“干净”的意思是模型预测时使用的数据在其训练期间从未见过)。

现在可以使用confusion_matrix()函数来获取混淆矩阵了。只需要给出目标类别(y_train_5)和预测类别(y_train_pred)即可:

3折的结果是将每一折结果都组合到一起,并按照它们在原始训练集中的顺序重新排列,形成 y_train_pred 数组。最终得到的y_train_predx_train长度相同。

由上文的StratifiedKFold可知,每一次迭代运算只获得一折预测值,三次则可得到三折预测值。

现在可以使用confusion_matrix()函数来获取混淆矩阵了。只需要给出目标类别(y_train_5)和预测类别(y_train_pred)即可:

from sklearn.metrics import confusion_matrix

confusion_matrix(y_train_5 , y_train_pred) #实际值在前 预测值在后。

结果如下:

array([[53892,   687],  #实际负 即实际非5
       [ 1891,  3530]]) #实际正,即实际5
        #猜测负   #猜测正

左上表示两个负,右下表示两个正。687张被错误地分类成了“5”(假正类:错误的猜成正类);第二行表示所有“5”(正类)的图片中:1891张被错误地分为“非5”类别(假负类:错误的猜成负嘞),3530张被正确地分在了“5”这一类别(真正类)

一个完美的分类器只有真正类和真负类,所以它的混淆矩阵只会在其对角线(左上
到右下)上有非零值:

y_train_perfect_predictions = y_train_5 
confusion_matrix(y_train_5 , y_train_perfect_predictions)

结果如下:

array([[54579,     0],
       [    0,  5421]])

混淆矩阵能提供大量信息,但有时你可能希望指标更简洁一些。正类预测的准确率是一个有意思的指标,它也称为分类器的精度,即猜的正类里猜中的有多少占比。

精度 = T P T P + F P 精度 = \frac{TP}{TP+FP} 精度=TP+FPTP
TP是真正类的数量,FP是假正类的数量。

分类器会忽略这个正类实例之外的所有内容。因此,精度通常与另一个指标一起使用,这个指标就是召回率,即猜出的正类占总体正类的多少。

召回率 = T P T P + F N 召回率 = \frac{TP}{TP+FN} 召回率=TP+FNTP
FN是假负类的数量。

精确率是分类正确的正样本 / 判定为正样本的总数;召回率是分类正确的正样本 / 真正正样本的总数。

![[QQ_1724755975403.png]]

混淆矩阵显示了真负(左上)、假正(右上)、假负(左下)和真正(右下)的示例

精度和召回率

Scikit-Learn提供了计算多种分类器指标的函数,包括精度和召回率:

from sklearn.metrics import precision_score ,recall_score
precision_score(y_train_5 , y_train_pred) #3530 / (3530 + 687)
recall_score(y_train_5 , y_train_pred) #3530 / (3530+1891)

现在再看,这个5-检测器看起来并不像它的准确率那么光鲜亮眼了。当它说一张图片是5时,只有72.9%的概率是准确的,并且也只有75.6%的数字5被它检测出来了。

因此我们可以很方便地将精度和召回率组合成一个单一的指标,称为F1分数。当你需要一个简单的方法来比较两种分类器时,这是个非常不错的指标。F1分数是精度和召回率的谐波平均值。

F 1 = 2 1 精度 + 1 召回率 = 2 × 精度 × 召回率 精度 + 召回率 = T P T P + F P + F N 2 F_1 = \frac{2}{\frac{1}{精度}+\frac{1}{召回率}} = 2 \times \frac{精度\times 召回率}{精度+召回率} = \frac{TP}{TP+\frac{FP+FN}{2}} F1=精度1+召回率12=2×精度+召回率精度×召回率=TP+2FP+FNTP

要计算F1分数,只需要调用f1_score()即可

from sklearn.metrics import f1_score
f1_score(y_train_5,y_train_pred)
# 0.7325171197343847

F1分数对那些具有相近的精度和召回率的分类器更为有利。这不一定能一直符合你的期望:在某些情况下,你更关心的是精度,而另一些情况下,你可能真正关心的是召回率。
遗憾的是,鱼和熊掌不可兼得,你不能同时增加精度又减少召回率,反之亦然。这称为精度/召回率权衡。

  • 16
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值