本篇主要内容:F1 Score,Precision-Recall 的平衡,P-R 曲线
F1 Score
上篇我们提到,精准率和召回率这两个指标有时精准率低一些有时召回率低一些,有时可能都低。那么实际中用哪个指标比较好呢?这一般和应用场景有关,对于有些场景,我们更注重精准率,比如股票预测,假设预测的是一个二分类问题:股票会升还是降,显然为了利润我们关注的是升(即上升为类 1),为什么这种情况下精准率指标更好呢?因为精准率是所有分类为 1 的预测中有多少是正确的,对本例也就是预测未来股票上升有多少是对的,这更复合我们的利润最大决策。而召回率是实际上升的股票中我们预测对了多少,基于风险投资理念,有很多股票会上升的时刻,我们就算落掉一些也是没有关系的,没有投资进去也就没有损失,更重要的是我们的决策中有多少能赚钱,所以在这种场景下,精准率更好。
而如果在医疗领域,则是召回率更加重要,也就是要能在实际得病的人中尽量预测的更加准确,我们不想漏掉任何真正患病的人,这样才更有可能挽回一些人的生命,而精准率低些(没病的被预测为有病)并不会导致特别严重的后果,只是进行了一些过度医疗。
不过并非所有场景都如上面两个例子般极端,只关注精准率或只关注召回率。更多的我们希望得到它们之间的一种平衡,即同时关注精准率和召回率。这种情况下我们有一个新的指标:F1 Score,它的计算公式为:
如果两个都为 0,则定义 F1=0。本质上 F1 是精准率和召回率的调和平均,调和平均一个很重要的特性是如果两个数极度不平衡(一个很大一个很小),最终的的结果会很小,只有两个数都比较高时,调和平均才会比较高,这样便达到了平衡精准率和召回率的目的。下面编程实现一下 F1 Score:
1 | import numpy as np |
输入几组值进行测试:
下面在真实数据集上来使用 F1 Score,分类算法使用逻辑回归,数据集和上篇文章相同,是人工处理为 2 类的手写数字数据集:
1 | import numpy as np |
准确率:
精准率和召回率:
精准率和召回率
1 | from sklearn.metrics import f1_score |
F1 Score:
可以看到 F1 的值是综合了精准率和召回率的,用它来衡量模型性能是比准确率要好的。
Precision-Recall 的平衡
精准率和召回率是相互制约的,如果想要精准率提高,召回率则会下降,如果要召回率提高,精准率则会下降,我们需要找到二者之间的一个平衡。
下面通过调整决策边界导致的分类结果变化来观察一下这个现象,不过 Logistic 回归中并没有直接能调整决策边界的函数,可以通过 decision_score 来间接调节:
1 | log_reg.decision_function(X_test)[:10] |
decision_score 的前 10 个值展示:
其值就是样本特征带入决策边界函数得到的结果,对于其中小于 0 的就被判别为类别 0 了,大于 0 的则是类别 1。默认的决策边界函数是,此时如果需要调节边界比如要调节为,只需在计算时让再与 0 比较即可:
1 | '''如果阀值为5''' |
此时的混淆矩阵为:
精准率和召回率:
F1 Score:
再调节决策边界为:
1 | '''如果阀值为-5''' |
精准率、召回率和 F1 Score:
从上面的结果可以观察到当精准率升高时召回率相应下降,召回率升高时精准率相应下降,我们希望模型尽量有比较平横的精准率和召回率,为了更好地观察它们之间的关系,可以绘制精准率召回率曲线(P-R 曲线):
1 | import matplotlib.pyplot as plt |
从 P-R 曲线看出精准率和召回率是相互制约的,召回率的升高会带来精准率的下降。同样可以用 sklearn 中自带的 P-R 曲线绘制函数来绘制:
1 | from sklearn.metrics import precision_recall_curve |
1 | plt.plot(thresholds,precisions[:-1]) |
在 P-R 曲线中,突然下降的位置很可能就是二者平衡的一个位置。
整体的,如果将两个模型的 P-R 曲线绘制到一个图中,则靠外的那个模型显然更优,也就是与两个轴围成的面积大的那个模型更好。