我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

从原理上分析模型预测结果得分的算法,这些预测模型的得分算法包括:查准率precision、召回率recall、以及整体的f1得分,文章的主要内容就是模拟这些得分是怎么计算的。

苏南大叔:sklearn的metrics,如何原理上理解预测结果的得分好坏? - 原理上理解预测结果
sklearn的metrics,如何原理上理解预测结果的得分好坏? (图4-1)

苏南大叔的“程序如此灵动”博客,记录苏南大叔的编程感想感悟。本文的模型得分算法分析实验的测试环境:win10python@3.11.0sklearn@1.2.2。本文的基本思路前提是:二分法(非此即彼),而不是多分类。

基本数据

这里还是以二分类数据为例子,非零即一。场景假设为某种进口海鱼的安全合格率,这里假设1为目标检查数据,即不合格的海鱼。海关要尽力把数据为1的海鱼,即受污染的海鱼给找出来。

某一批海洋鱼类产品,

  • 它的实际情况是:[0 0 0 1 1 1]
  • 大数据模型根据机器学习的结果预测的结果是:[1 1 1 0 0 1]

基础分类

专业术语里面使用"阳性/Positive"来表示有问题,"阴性/Negative"表示没有问题。使用"真实/True"来表示符合情况,"虚假/False"来表示不符合情况。所以,这里对数据分成了分类,即:

变量含义预测实际是否准确解释
tp正确的阳性结论11准确有问题,还被预测出来了
fp虚假的阳性结论10不准确没问题,却被错误的预测出来了
tn正确的阴性结论00准确没问题,同时也确实被预测出来
fn虚假的阴性结论01不准确有问题,但是没被预测出来

算法上实际计算的是上述分类的样本总数:

tp = sum( (y_pred == 1) & (y_true == 1) )
fp = sum( (y_pred == 1) & (y_true == 0) )
tn = sum( (y_pred == 0) & (y_true == 0) )
fn = sum( (y_pred == 0) & (y_true == 1) )

苏南大叔:sklearn的metrics,如何原理上理解预测结果的得分好坏? - 分类计数代码
sklearn的metrics,如何原理上理解预测结果的得分好坏? (图4-2)

查准率 precision_score

精准度可以有三种表述:

  • 阳性有关的样本中,预测准确的样本比率。【查准率】
  • 阴性有关的样本中,预测准确的样本比率。
  • 所有样本中,预测准确的样本比率。

精准度,实际上计算的是阳性精准度。并不是阴性精准度,也不是整体的精准度【重大误解】。

尽量不冤枉好人,也不放过每个坏人。

算法是:

p = tp / (tp + fp)
p_n = tn / (tn + fn)
p_all = (tp + tn) / (tp + fp + tn + fn)

苏南大叔:sklearn的metrics,如何原理上理解预测结果的得分好坏? - 准确度计算代码
sklearn的metrics,如何原理上理解预测结果的得分好坏? (图4-3)

本文的例子中:

官方查准率: 0.25
阳性查准率[tp / tp + fp]: 0.25
阴性查准率[tn / tn + fp]: 0.0
整体查准率[(tp + tn) / (tp + fp + tn + fn)]: 0.16666666666666666

对比代码:

p = precision_score(y_true, y_pred)
p_ = (tp / (tp + fp)) if (tp + fp > 0) else 0

召回率recall_score

召回率就是:有问题的样本被召回(预测)的比率,无论有多少被错误召回的样本,只计算被正确召回的比率。

宁可错杀一千,不可放过敌军一个。

涉及的就是阳性相关的预测值:

  • 预测为阳性,[==>]真实阳性,准确(tp)。真实阴性,不准确(fp)。
  • 预测为阴性,真实阴性,准确(tn)。[==>]真实阳性,不准确(fn)。

算法是:

r = tp / (tp + fn)

对比代码:

r = recall_score(y_true, y_pred)
r_ = (tp / (tp + fn)) if (tp + fn > 0) else 0

f1得分f1_score

f1得分是综合上述两者得分的,f1得分越低,证明模型选的越不好。计算方法是:

f1 = 2 * p * r / (p + r)

对比代码:

f1 = f1_score(y_true, y_pred)
f1_ = 2 * p_ * r_ / (p_ + r_) if (p_ + r_ > 0) else 0

测试代码

from sklearn.metrics import precision_score, recall_score, f1_score
import numpy as np


def analyze(y_true, y_pred):
    print("实际值", y_true)
    print("预测值", y_pred)
    print("对不对", y_true == y_pred)

    tp = sum((y_pred == 1) & (y_true == 1))
    fp = sum((y_pred == 1) & (y_true == 0))
    tn = sum((y_pred == 0) & (y_true == 0))
    fn = sum((y_pred == 0) & (y_true == 1))

    print("有问题被发现了(tp):%s" % tp)
    print("有问题没被发现(fn):%s" % fn)
    print("没有问题被误诊(fp):%s" % fp)
    print("放心啥事都没有(tn):%s" % tn)

    p = precision_score(y_true, y_pred)
    r = recall_score(y_true, y_pred)
    f1 = f1_score(y_true, y_pred)

    print("官方查准率:%s" % p)
    print("官方召回率:%s" % r)
    print("官方F1得分:%s" % f1)

    p_ = (tp / (tp + fp)) if (tp + fp > 0) else 0
    r_ = (tp / (tp + fn)) if (tp + fn > 0) else 0
    f1_ = 2 * p_ * r_ / (p_ + r_) if (p_ + r_ > 0) else 0

    print("查准率自定义:%s" % p_)
    print("召回率自定义:%s" % r_)
    print("F1得分自定义:%s" % f1_)

    p_2 = (tn / (tn + fn)) if (tn + fn > 0) else 0
    p_3 = ((tp + tn) / (tp + fp + tn + fn)) if (tp + fp + tn + fn > 0) else 0
    print("阳性查准率[tp / tp + fp]:%s" % p_)
    print("阴性查准率[tn / tn + fp]:%s" % p_2)
    print("整体查准率[(tp + tn) / (tp + fp + tn + fn)]:%s" % p_3)


def analyze2(y_test, predictions):
    y_true = np.array(y_test)       # 1 有问题的,应该被召回  0 没有问题的,不应该被召回
    y_pred = np.array(predictions)  # 1 预测为有问题,被召回  0 预测为没有问题,没有被召回
    analyze(y_true, y_pred)
    print("=" * 20)
analyze2([0, 0, 0, 1, 1, 1], [1, 1, 1, 0, 0, 1])

输出值为:

实际值 [0 0 0 1 1 1]
预测值 [1 1 1 0 0 1]
对不对 [False False False False False  True]
有问题被发现了(tp):1
有问题没被发现(fn):2
没有问题被误诊(fp):3
放心啥事都没有(tn):0
官方查准率:0.25
官方召回率:0.3333333333333333
官方F1得分:0.28571428571428575
查准率自定义:0.25
召回率自定义:0.3333333333333333
F1得分自定义:0.28571428571428575
阳性查准率[tp / tp + fp]:0.25
阴性查准率[tn / tn + fp]:0.0
整体查准率[(tp + tn) / (tp + fp + tn + fn)]:0.16666666666666666

从预测结果上来看,f1得分实在是低的可怜。“这个”模型很失败,不合适。

苏南大叔:sklearn的metrics,如何原理上理解预测结果的得分好坏? - 运算结果
sklearn的metrics,如何原理上理解预测结果的得分好坏? (图4-4)

结束语

查准率原来是阳性查准率,召回率居然可以容错,f1得分才是最终的模型评判标准。更多机器学习文章,可以参考:

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   python    sklearn