分类模型的评价指标

在本篇文章中,我们使用著名的手写数字数据集mnist做为例子.使用sklearn.datasetsfetch_openml()方法可以下载该数据集:

from sklearn.datasets import fetch_openml

# 下载minst数据集,data_home属性指定存储数据集的路径
mnist = fetch_openml('MNIST original', data_home='dataset_home')
X, y = mnist['data'], mnist['target']	# X每一行存储一张28*28的点阵图,y为对应的数字

# 展示一张图片
some_digit_image = X[36000].reshape(28, 28)
plt.imshow(some_digit_image, cmap=matplotlib.cm.binary, interpolation='nearest')
plt.show()

在这里插入图片描述

交叉验证

在训练时,我们常使用k折交叉验证扩充数据集.

我们将给定样本分为 k k k份,每次拿出 k − 1 k-1 k1份进行训练,留下 1 1 1份用于测试,重复 k k k次.取每一次误差的平方和作为最终的误差.

在这里插入图片描述

使用sklearn.model_selection模块的cross_val_predict()方法可以使用k折交叉验证进行预测,cross_val_score()方法可以使用k折交叉验证对计算某指标.

函数各参数意义:

  • estimator: 待训练的模型.
  • Xy: 训练数据.
  • cv: 交叉验证的折数.
  • scoring: cross_val_score()方法计算的指标.
  • method: cross_val_predict()方法调用的模型的方法.
sgd_clf = SGDClassifier(loss='log')	# 创建一个逻辑回归分类器

# 进行3折交叉验证,评估其准确率
cross_val_score(sgd_clf, X_train, y_train, cv=3, scoring='accuracy')

# 进行3折交叉验证,调用分类器的predict方法进行预测
cross_val_predict(sgd_clf, X_train, y_train, cv=3, method='predict')

# 进行3折交叉验证,调用分类器的predict_proba方法得到概率值
cross_val_predict(sgd_clf, X_train, y_train, cv=3, method='predict_proba')

评估指标

混淆矩阵

混淆矩阵是一张分类模型预测结果的情形分析表,其行索引为列表为样本的真实类别,列索引为样本的预测结果,表格中每一项表示对应真实类别与预测结果的样本的数量.

在主对角线上的样本预测正确,非主对角线上的样本预测错误.
在这里插入图片描述
当我们进行二分类时,混淆矩阵退化成为一个2×2的表格.

预测值
负例(Negative)正例(Positive)


负例(Negative)真阴性(True Negative,TN)假阳性(False Positive,FP)
第一类错误
正例(Positive)假阴性(False Negative,FP)
第二类错误
真阳性(True Positive,TP)

调用sklearn.metrics模块的confusion_matrix(y_true, y_pred)方法可以计算混淆矩阵,其中y_true为真实值数组,y_pred为预测值数组.

print(y_true)	# array([False, False, False, ..., False, False, False])
print(y_pred)	# array([False, False, False, ..., False, False, False])

print(confusion_matrix(y_labeled, y_predict)) 
# 得到 array([[61413, 2274], [ 6093, 220]], dtype=int64)

准确率(Accuracy),精确率(Precision),召回率(Recall)

根据二分类的混淆矩阵,我们分别定义三个指标

预测值
负例(Negative)正例(Positive)


负例(Negative)真阴性(True Negative,TN)假阳性(False Positive,FP)
第一类错误
正例(Positive)假阴性(False Negative,FN)
第二类错误
真阳性(True Positive,TP)
  1. 准确率(Accuracy): 所有样本中被正确预测的比例.

    A c c u r a c y = T P + T N T P + F P + T N + F N Accuracy = \frac{TP + TN}{TP + FP + TN + FN} Accuracy=TP+FP+TN+FNTP+TN

准确率Accuracy关心的是整体的正确率,在样本正负例个数不平衡时不是一个好的评估指标.考虑如下情况: 当样本中绝大多数都是负例时,我们的分类器只要无脑判负即可使得准确率Accuracy很高,但这并不是一个好的模型.

下面例子判断minst数据集中手写图片的数字是否为5,我们创建一个无脑判负的分类器,并将其和逻辑回归模型相对比.

import numpy as np
from sklearn.base import BaseEstimator
from sklearn.datasets import fetch_openml
from sklearn.linear_model import SGDClassifier
from sklearn.model_selection import cross_val_score

# 获取数据集并打乱原始数据集
mnist = fetch_openml('MNIST original', data_home='dataset_home')
X, y = mnist['data'], mnist['target']
shuffle_index = np.random.permutation(X.shape[0])
X_train, y_train = X[shuffle_index], y[shuffle_index]
y_train_5 = (y_train == 5)


# 创建一个逻辑回归分类器并进行交叉验证
sgd_clf = SGDClassifier(loss='log', max_iter=1000, tol=1e-4)
cross_val_score(sgd_clf, X_train, y_train_5, cv=3, scoring='accuracy')
# 进行三折交叉验证得到的准确率为 array([0.96532956, 0.96897099, 0.96018515])
cross_val_score(sgd_clf, X_train, y_train_5, cv=3, scoring='precision')
# 进行三折交叉验证得到的精确率为 array([0.95501022, 0.67672576, 0.87068966])
cross_val_score(sgd_clf, X_train, y_train_5, cv=3, scoring='recall')
# 进行三折交叉验证得到的召回率为 array([0.89643705, 0.87262357, 0.70722433])


# 创建一个无脑判负的分类器并进行交叉验证
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.91188823, 0.90957014, 0.9079844 ])
cross_val_score(never_5_clf, X_train, y_train_5, cv=3, scoring='precision')
# 进行三折交叉验证得到的精确率为 array([0., 0., 0.])
cross_val_score(never_5_clf, X_train, y_train_5, cv=3, scoring='recall')
# 进行三折交叉验证得到的召回率为 array([0., 0., 0.])

可以看到,无脑判负的Never5Classifier虽然准确率很高,但是精确率和召回率都很低.

  1. 精确率(Precision): 所有预测为正例的样本中被正确预测的比例.

    P r e c i s i o n = T P T P + F P Precision = \frac{TP}{TP + FP} Precision=TP+FPTP

  2. 召回率(Recall): 所有真实值为正例的样本中被正确预测的比例.

    R e c a l l = T P T P + F N Recall = \frac{TP}{TP+FN} Recall=TP+FNTP

精确率Precision和召回率Recall只关心正例,它们两者是相互抑制(trade off)的关系,考虑如下情况:

对于一个分类系统,我们将用户喜欢视为正例,用户不喜欢视为负例,这时我们只关心推荐的商品中用户喜欢的有多少(TP),因此应考虑精确率Precision和召回率Recall作为评价指标.

  • 假设用户实际喜欢的所有商品(TP+FN)有10000个,推荐系统向他推荐(TP+FP)10个商品,用户最终下单(TP)了3个商品.则此时的精确率Precision为30%,召回率Recall为0.003%.
  • 为了让用户多下单(增加TP),我们降低阈值(threshold),向用户推荐(TP+FP)1000个商品,用户最终下单(TP)了30个商品.则此时的精确率Precision为3%,召回率Recall为0.03%.召回率Recall上升,而精确率Precision却下降了.(这有点类似于’言多必失’的道理).

在这里插入图片描述

调用sklearn.metrics模块的accuracy_score(y_true, y_pred),precision_score(y_true, y_pred)recall_score(y_true, y_pred)分别可以计算预测结果的准确率,精确率和召回率,其中y_true为真实值数组,y_pred为预测值数组.

使用[precisions, recalls, thresholds] = precision_recall_curve(y_true, probas_pred)方法可以生成精确率Precision和召回率Recall曲线数据,示例如下:

# 获取逻辑回归表达式计算正例的概率
y_scores = cross_val_predict(sgd_clf, X_train, y_train, cv=3, method='decision_function')

# 生成 precisions,recalls,thresholds曲线
precisions, recalls, thresholds = precision_recall_curve(y_train, y_scores)

# 绘制 precisions,recalls,thresholds曲线
plt.plot(thresholds, precisions[:-1], 'b--', label='Precision')
plt.plot(thresholds, recalls[:-1], 'r--', label='Recall')
plt.xlabel("Threshold")
plt.legend(loc='upper left')
plt.ylim([0, 1])
plt.show()

F1-score

因为精确率Precision和召回率Recall是一个此消彼长的关系,因此我们有必要将两者综合成一个指标.

F1-Score被定义为精确率Precision召回率Recall调和平均数:

F 1 = 2 1 P r e c i s i o n + 1 R e c a l l = 2 ⋅ P r e c i s i o n × R e c a l l P r e c i s i o n + R e c a l l F_1 = \frac{2}{\frac{1}{Precision}+\frac{1}{Recall}} = 2 \cdot \frac{Precision \times Recall}{Precision + Recall} F1=Precision1+Recall12=2Precision+RecallPrecision×Recall

更一般的,有Fβ-Score,β越大,召回率Recall所占权重越高.

F β = 1 + β 2 1 P r e c i s i o n + β 2 R e c a l l = ( 1 + β 2 ) ⋅ P r e c i s i o n × R e c a l l β 2   P r e c i s i o n + R e c a l l F_{\beta} = \frac{1+\beta^2}{\frac{1}{Precision} + \frac{\beta^2}{Recall}} = (1+\beta^2) \cdot \frac{Precision \times Recall}{\beta^2 \, Precision+Recall} Fβ=Precision1+Recallβ21+β2=(1+β2)β2Precision+RecallPrecision×Recall

调用sklearn.metrics模块的f1_score(y_true, y_pred)fbeta_score(y_true, y_pred, beta)方法分别可以计算预测结果的F1-Score和Fβ-Score,其中y_true为真实值数组,y_pred为预测值数组.

AUC

ROC(receiver operating characteristic)曲线.ROC曲线上每个点反映着对同一信号刺激的感受性,即在不同阈值(threshold)下的负正类率(False Positive Rate,FPR)和真正类率(True Positive Rate,TPR).

  • 真正类率TPR表示所有真实值为正例的样本中,被正确预测为正例的样本的比例.

    T P R = T P T P + F N TPR = \frac{TP}{TP+FN} TPR=TP+FNTP

  • 负正类率FPR表示所有真实值为负例的样本中,被错误预测为正例的样本的比例.

    F P R = F P F P + T N FPR = \frac{FP}{FP+TN} FPR=FP+TNFP

根据定义,易知ROC曲线为一个过 ( 0 , 0 ) (0,0) (0,0)点和 ( 1 , 1 ) (1,1) (1,1)点的曲线.
在这里插入图片描述

AUC(Area under Curve)为ROC曲线下方的面积,即TPR对FPR积分的结果.容易看出AUC更看重正例.

调用sklearn.metrics模块的roc_curve(y_true, y_score)方法可以生成ROC曲线数据,调用roc_auc_score(y_true, y_score)方法可以计算AUC值.

# 使用逻辑回归分类器计算正例的概率
sgd_clf = SGDClassifier(loss='log', max_iter=1000, tol=1e-4)
y_scores_sgd = cross_val_predict(sgd_clf, X_train, y_train, cv=3, method='decision_function')
fpr_sgd, tpr_sgd, thresholds_sgd = roc_curve(y_train, y_scores)

# 使用随机森林分类器计算正例的概率
forest_clf = RandomForestClassifier(random_state=42)
y_probas_forest = cross_val_predict(forest_clf, X_train, y_train, cv=3, method='predict_proba')
y_scores_forest = y_probas_forest[:, 1]
fpr_forest, tpr_forest, thresholds_forest = roc_curve(y_train, y_scores_forest)

# 绘制ROC曲线
plt.plot(fpr_sgd, tpr_sgd, 'b:', label='SGD(AUC=%.5f)' % roc_auc_score(y_train, y_scores_sgd))
plt.plot(fpr_forest, tpr_forest, label='Random Forest(AUC=%.5f)' % roc_auc_score(y_train, y_scores_forest))
plt.legend(loc='lower right')
plt.show()

在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在sklearn中,多分类模型评价指标包括准确率、混淆矩阵、精确率、召回率、F1-score、支持度等。 首先,准确率是评价多分类模型性能的常用指标之一。它表示模型预测正确的样本占总样本数量的比例。准确率越高,模型的性能越好。 其次,混淆矩阵是多分类模型评价的重要工具。它是一个正方形矩阵,行表示实际类别,列表示预测类别。矩阵的每个元素表示被分为某个类别的样本数量。通过分析混淆矩阵可以得到模型在不同类别上的预测情况。 除了准确率和混淆矩阵之外,精确率和召回率也是常用的多分类模型评价指标之一。精确率表示在所有被预测为某一类别的样本中,实际属于该类别的比例。召回率表示在所有实际属于某一类别的样本中,被正确预测为该类别的比例。 F1-score是综合衡量精确率和召回率的指标,它是二者的调和均值,可以更全面地评估模型的性能。F1-score越高,模型的性能越好。 最后,支持度指标表示每个类别在样本中的出现次数。该指标可以衡量模型对各个类别的预测能力。支持度越高,表示该类别在样本中的比例越大。 在sklearn中,我们可以使用相应的函数或方法计算这些多分类模型评价指标,如准确率可以使用accuracy_score函数,混淆矩阵可以使用confusion_matrix函数,精确率和召回率可以使用classification_report函数,F1-score可以使用f1_score函数,支持度可以使用value_counts方法等。通过这些评价指标,我们可以对多分类模型的性能进行全面的评估和比较。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值