二分类性能评估方法

在机器学习中,正确评估分类模型的性能至关重要。本课程将深入介绍各种评估指标和技术,帮助您更好地理解和评估模型的效果。

1. 准确率

对分类模型的性能评估时经常使用准确率(Accuracy)评估方法,准确率是指分类模型正确预测的样本数量与总样本数量之比。

例如:

假设:样本中有 6 个恶性肿瘤样本,4 个良性肿瘤样本。
模型 A:预测对了 5 个恶性肿瘤样本,4 个良性肿瘤样本,其准确率为:90%
模型 B:预测对了 6 个恶性肿瘤样本,3 个良性肿瘤样本,其准确率为:90%

from sklearn.metrics import accuracy_score
import pandas as pd


if __name__ == '__main__':
    # 样本集中共有6个恶性肿瘤样本, 4个良性肿瘤样本
    y_true = ['恶性', '恶性', '恶性', '恶性', '恶性', '恶性', '良性', '良性', '良性', '良性']

    # 1. 模型 A: 预测对了 5 个恶性肿瘤样本, 4个良性肿瘤样本
    y_pred = ['恶性', '恶性', '恶性', '恶性', '恶性', '良性', '良性', '良性', '良性', '良性']
    acc = accuracy_score(y_true, y_pred)
    print('acc:', acc)

    # 2. 模型 B: 预测对了 6 个恶性肿瘤样本, 3 个良性肿瘤样本
    y_pred = ['恶性', '恶性', '恶性', '恶性', '恶性', '恶性', '恶性', '良性', '良性', '良性']
    acc = accuracy_score(y_true, y_pred)
    print('acc:', acc)
acc: 0.9
acc: 0.9

2. 混淆矩阵

准确率是一个较为粗粒度的分类评估方法,它并不能进行更加细粒度的评估场景。例如:在一个肿瘤预测的二分类问题中,我们更加看重模型对恶性肿瘤的预测能力,而不仅仅是准确率。模型 B 把所有潜在的恶性肿瘤患者全部预测出来,模型 A 只能把 5/6 的恶性肿瘤患者预测出来,哪一个模型对于当前问题场景更好呢?显然是前者。

所以,所以,我们需要引入其他的模型评估方法。

想要获得更加精细的分类评估方法,得将预测结果进行更为精细的划分,这就是混淆矩阵(Confusion Matrix)。

正例(预测结果)负例(预测结果)
正例(真实结果)真正例(TP)假负例(FN)
负例(真实结果)假正例(FP)真负例(TN)

混淆矩阵作用就是统计下在测试集中:

  1. 真实值是 正例 的样本中,被预测为 正例 的样本数量有多少,这部分样本叫做 真正例(TP,True Positive)
  2. 真实值是 正例 的样本中,被预测为 负例 的样本数量有多少,这部分样本叫做 假负例(FN,False Negative)
  3. 真实值是 负例 的样本中,被预测为 正例 的样本数量有多少,这部分样本叫做 假正例(FP,False Positive)
  4. 真实值是 的样本中,被预测为 负例 的样本数量有多少,这部分样本叫做 真负例(TN,True Negative)

True Positive :整体表示样本真实的类别
Positive :第二个词表示样本被预测为的类别

例子:

样本集中有 6 个恶性肿瘤样本,4 个良性肿瘤样本,我们假设恶性肿瘤为正例,则:

  1. 模型 A:预测对了 3 个恶性肿瘤样本,4 个良性肿瘤样本
    1. 真正例 TP 为:3
    2. 假负例 FN 为:3
    3. 假正例 FP 为:0
    4. 真负例 TN:4
  2. 模型 B:预测对了 6 个恶性肿瘤样本,1个良性肿瘤样本
    1. 真正例 TP 为:6
    2. 假负例 FN 为:0
    3. 假正例 FP 为:3
    4. 真负例 TN:1

我们会发现:TP+FN+FP+TN = 总样本数量

通过上面四种情况,将预测后的结果划分为 4 部分,分别是:TP、FN、TN、FP。我们通过上述 4 种信息,构成了分类问题中的重要评估指标。

from sklearn.metrics import confusion_matrix
import pandas as pd


if __name__ == '__main__':
    # 样本集中共有6个恶性肿瘤样本, 4个良性肿瘤样本
    y_true = ['恶性', '恶性', '恶性', '恶性', '恶性', '恶性', '良性', '良性', '良性', '良性']

    labels = ['恶性', '良性']

    # 1. 模型 A: 预测对了3个恶性肿瘤样本, 4个良性肿瘤样本
    y_pred = ['恶性', '恶性', '恶性', '良性', '良性', '良性', '良性', '良性', '良性', '良性']
    matrix = confusion_matrix(y_true, y_pred, labels=labels)
    print(pd.DataFrame(matrix, columns=labels, index=labels))

    # 2. 模型 B: 预测对了6个恶性肿瘤样本, 1个良性肿瘤样本
    y_pred = ['恶性', '恶性', '恶性', '恶性', '恶性', '恶性', '恶性', '恶性', '恶性', '良性']
    matrix = confusion_matrix(y_true, y_pred, labels=labels)
    print(pd.DataFrame(matrix, columns=labels, index=labels))
    恶性  良性
恶性   3   3
良性   0   4

    恶性  良性
恶性   6   0
良性   3   1

3. 精确率(精度、查准率)

精确率(Precision)是指被分类器正确分类的正样本(True Positive)数目与所有被分类为正样本的样本数目的比率。

比如,我们把恶性肿瘤当做正例样本,我们希望知道在模型预测出的所有的恶性肿瘤样本中,真正的恶性肿瘤样本占比。即:模型对恶性肿瘤的预测精确率有多少?

如果预测出 10 个恶性肿瘤样本,并且这 10 个也是真正的恶性肿瘤,那么精度就是 100%。如果 10 个中,只有 3 个是真正的恶性肿瘤,那么精度就是 30%.

也就是说,我们关心模型预测的准不准,并不关心预测的全不全。

例子:

样本集中有 6 个恶性肿瘤样本,4 个良性肿瘤样本,我们假设恶性肿瘤为正例,则:

  1. 模型 A:预测对了 3 个恶性肿瘤样本,4 个良性肿瘤样本
    1. 真正例 TP 为:3
    2. 假负例 FN 为:3
    3. 假正例 FP 为:0
    4. 真负例 TN:4
    5. 精确率:3/(3+0) = 100%
  2. 模型 B:预测对了 6 个恶性肿瘤样本,1个良性肿瘤样本
    1. 真正例 TP 为:6
    2. 假负例 FN 为:0
    3. 假正例 FP 为:3
    4. 真负例 TN:1
    5. 精确率:6/(6+3) = 67%

from sklearn.metrics import precision_score


if __name__ == '__main__':
    # 样本集中共有6个恶性肿瘤样本, 4个良性肿瘤样本
    y_true = ['恶性', '恶性', '恶性', '恶性', '恶性', '恶性', '良性', '良性', '良性', '良性']

    # 1. 模型 A: 预测对了3个恶性肿瘤样本, 4个良性肿瘤样本
    y_pred = ['恶性', '恶性', '恶性', '良性', '良性', '良性', '良性', '良性', '良性', '良性']

    # pos_label 指定那个类别是正例
    result = precision_score(y_true, y_pred, pos_label='恶性')
    print('模型A精确率:', result)

    # 2. 模型 B: 预测对了6个恶性肿瘤样本, 1个良性肿瘤样本
    y_pred = ['恶性', '恶性', '恶性', '恶性', '恶性', '恶性', '恶性', '恶性', '恶性', '良性']

    result = precision_score(y_true, y_pred, pos_label='恶性')
    print('模型B精确率:', result)

输出结果:

模型A精确率: 1.0
模型B精确率: 0.67

4. 召回率(查全率)

召回率也叫做查全率,指的是预测为真正例样本所有真实正例样本的比重。例如:我们把恶性肿瘤当做正例样本,则我们想知道模型是否能把所有的恶性肿瘤患者都预测出来。

例子:

样本集中有 6 个恶性肿瘤样本,4 个良性肿瘤样本,我们假设恶性肿瘤为正例,则:

  1. 模型 A:预测对了 3 个恶性肿瘤样本,4 个良性肿瘤样本
    1. 真正例 TP 为:3
    2. 假负例 FN 为:3
    3. 假正例 FP 为:0
    4. 真负例 TN:4
    5. 精确率:3/(3+0) = 100%
    6. 召回率:3/(3+3)=50%
  2. 模型 B:预测对了 6 个恶性肿瘤样本,1个良性肿瘤样本
    1. 真正例 TP 为:6
    2. 假负例FN 为:0
    3. 假正例 FP 为:3
    4. 真负例 TN:1
    5. 精确率:6/(6+3) = 67%
    6. 召回率:6/(6+0)= 100%

from sklearn.metrics import recall_score


if __name__ == '__main__':

    # 样本集中共有6个恶性肿瘤样本, 4个良性肿瘤样本
    y_true = ['恶性', '恶性', '恶性', '恶性', '恶性','恶性', '良性', '良性', '良性', '良性']

    # 1. 模型 A: 预测对了3个恶性肿瘤样本, 4个良性肿瘤样本
    y_pred = ['恶性', '恶性', '恶性', '良性', '良性', '良性', '良性', '良性', '良性', '良性']

    result = recall_score(y_true, y_pred, pos_label='恶性')
    print('模型A召回率:', result)


    # 2. 模型 B: 预测对了6个恶性肿瘤样本, 1个良性肿瘤样本
    y_pred = ['恶性', '恶性', '恶性', '恶性', '恶性', '恶性', '恶性', '恶性', '恶性', '良性']

    result = recall_score(y_true, y_pred, pos_label='恶性')
    print('模型B召回率:', result)

输出结果:

模型A召回率: 0.5
模型B召回率: 1.0

5. F1-score(综合精度和召回率)

F1-score 是一种常用的性能度量指标,它综合考虑了模型的精确度召回率,是这两者的调和平均数,其计算公式如下:

调和平均数对数据集中的较小数值更敏感。如果数据集中有极小的值,它会显著降低调和平均数的值。

from scipy.stats import hmean


print(hmean([0.0, 1.0]))
print(hmean([1.0, 0.0]))
print(hmean([0.0, 0.0]))
print(hmean([1.0, 1.0]))
0.0
0.0
0.0
1.0

所以,当精度和召回率都高的时候,f1-score 才会高。

样本集中有 6 个恶性肿瘤样本,4 个良性肿瘤样本,我们假设恶性肿瘤为正例,则:

  1. 模型 A:预测对了 3 个恶性肿瘤样本,4 个良性肿瘤样本
    1. 真正例 TP 为:3
    2. 假负例 FN 为:3
    3. 假正例 FP 为:0
    4. 真负例 TN:4
    5. 精确率:3/(3+0) = 100%
    6. 召回率:3/(3+3)=50%
    7. F1-score:(2*3)/(2*3+3+0)=67%
  2. 模型 B:预测对了 6 个恶性肿瘤样本,1个良性肿瘤样本
    1. 真正例 TP 为:6
    2. 假负例 FN 为:0
    3. 假正例 FP 为:3
    4. 真负例 TN:1
    5. 精确率:6/(6+3) = 67%
    6. 召回率:6/(6+0)= 100%
    7. F1-score:(2*6)/(2*6+0+3)=80%
from sklearn.metrics import f1_score


if __name__ == '__main__':

    # 样本集中共有6个恶性肿瘤样本, 4个良性肿瘤样本
    y_true = ['恶性', '恶性', '恶性', '恶性', '恶性','恶性', '良性', '良性', '良性', '良性']

    # 1. 模型 A: 预测对了3个恶性肿瘤样本, 4个良性肿瘤样本
    y_pred = ['恶性', '恶性', '恶性', '良性', '良性', '良性', '良性', '良性', '良性', '良性']
    
    result = f1_score(y_true, y_pred, pos_label='恶性')
    print('模型A f1-score:', result)


    # 2. 模型 B: 预测对了6个恶性肿瘤样本, 1个良性肿瘤样本
    y_pred = ['恶性', '恶性', '恶性', '恶性', '恶性', '恶性', '恶性', '恶性', '恶性', '良性']

    result = f1_score(y_true, y_pred, pos_label='恶性')
    print('模型B f1-score:', result)

输出结果:

模型A f1-score: 0.67
模型B f1-score: 0.8

未经允许不得转载:一亩三分地 » 二分类性能评估方法
评论 (0)

7 + 4 =