内容概要
-
“回归问题监督式学习” 的性能量度指标为 “均方误差”,介绍了其数学公式,解释了公式中各部分的含义,给出了计算均方误差的自定义函数和使用 sklearn 库计算的示例代码。
-
“分类问题监督式学习” 的性能量度:
-
错误率和精度,说明了两者的定义和关系。
-
查准率、查全率(召回率)、F1,阐述了在特定场景中的应用和概念。
-
累积增益图,用于辅助解决查准率和查全率的两难选择问题。
-
ROC 曲线和 AUC 值,介绍了通过改变分类阈值计算真正例率和假正例率来绘制 ROC 曲线,AUC 值用于评估模型性能。
-
科恩 kappa 得分,作为评价判断一致性程度和分类精度的指标。
-
-
提供了使用 sklearn 库计算分类问题中错误率、精度、召回率、F1 值、混淆矩阵、AUC 值和科恩得分的综合示例代码。
一、“回归问题监督式学习”的性能量度
针对“回归问题监督式学习”,最常用的性能量度指标为“均方误差”。
假设示例集为D={(x1,y1),(x2,y2),…,(xk,yk)},其中(xi,yi)为各个示例,xi为属性值,yi为响应变量的真实值。“均方误差”的数学公式为:
针对该公式解释如下:E(f:D)即为“均方误差”,公式中f为机器学习算法函数,而f(xi)则为响应变量的预测值,进而f(xi)-yi为响应变量的预测值与真实值之差,因为差值可能有正负之分,为了反映绝对差距,采用平方变换得到(f(xi)-yi)2,也就是方差。然后将k个样本的方差进行简单算术平均,即得到均方误差。
实际操作中通过 scikit-learn
(sklearn
)库来计算均方误差(MSE)的示例代码:
from sklearn.metrics import mean_squared_error
import numpy as np
# 真实值
y_true = np.array([1, 2, 3, 4, 5])
# 预测值
y_pred = np.array([1.2, 2.1, 2.9, 4.2, 4.8])
# 计算并打印均方误差
mse = mean_squared_error(y_true, y_pred)
print("均方误差(MSE)为:", mse)
结果为:
二、“分类问题监督式学习”的性能量度
1.错误率和精度
针对“分类问题监督式学习”,最简单的性能量度就是观察其预测的错误率和正确率,用到的性能量度指标即为错误率和精度。
其中错误率即为预测错误的比率,也就是预测类别和实际类别不同的样本数在全部样本中的占比;精度即为预测正确的比率,也就是预测类别和实际类别相同的样本数在全部样本中的占比。基于上述定义,不难看出错误率和精度之和等于1,或者说错误率=1-精度。
错误率的数学公式为:
精度的数学公式为:
2.查准率、查全率(召回率)、F1
在分类问题监督式学习中,除了观察预测的正确率、错误率外,很多情形下我们还需要特别关心特定类别是否被准确查找,比如针对员工行为管理中的异常行为界定,可能需要特别慎重,非常忌讳以莫须有的定性伤害员工的工作积极性,分类为异常行为的准确性非常重要,这时候就需要用到“查准率”的概念;也有很多情形下,我们还需要特别关心特定类别被查找得是否完整,比如针对某种传染性极强的病毒,核酸检测密切接触者是否为阳性,对阳性病例的查找的完整性就显得尤为重要,这时候就需要用到“查全率”的概念。
如果“分类问题监督式学习”为二分类问题,我们会很容易得到如表所示的分类结果矩阵,该矩阵也被称为“混淆矩阵”(Confusion Matrix)。其中的“正例”通常表示研究者所关注的分类结果,比如授信业务发生违约,所以并不像字面意思那样必然代表正向分类结果;“反例”则是与“正例”所对应的分类,比如前述的授信业务不发生违约。
在混淆矩阵中:
当样本真实的分类为正例,且机器学习预测分类也为正例时,说明机器学习预测正确,分类结果即为TP(真正例)。
当样本真实的分类为反例,且机器学习预测分类也为反例时,说明机器学习预测正确,分类结果即为TN(真反例)。
当样本真实的分类为正例,且机器学习预测分类为反例时,说明机器学习预测错误,分类结果即为FN(假反例)。
当样本真实的分类为反例,且机器学习预测分类为正例时,说明机器学习预测错误,分类结果即为FP(假正例)。
查全率也被称为“召回率”“灵敏度”“敏感度”。
为了平衡查准率与查全率,使用了F1值。F1值为查准率和查全率的调和平均值。F1的取值范围为0~1,数值越大表示模型效果越好。
3.累积增益图
前面提到“分类问题监督式学习”中查准率、查全率存在两难选择的问题,对这一问题用户可以使用累积增益图进行辅助决策。在针对二分类问题的很多机器学习算法中,系统对每个样本都会预测1个针对目标类别的概率值p,如果p大于0.5,则判定为目标类别,如果p小于0.5,则判定为非目标类别。
根据概率值p,用户将所有样本进行降序排列,拥有大的p值的样本将会被排在前面。累积增益图会在给定的类别中,通过把个案总数的百分比作为目标而显示出“增益”的个案总数的百分比。
4. ROC 曲线(Receiver Operating Characteristic Curve)和 AUC 值(Area Under the Curve)
ROC 曲线是一种用于评估二分类模型性能的工具。它通过不断地改变分类阈值,计算出不同阈值下的真正例率(True Positive Rate,TPR)和假正例率(False Positive Rate,FPR)。
真正例率(TPR) = 真正例数量 / (真正例数量 + 假反例数量),也就是灵敏度,反映了模型正确识别正例的能力。
假正例率(FPR) = 假正例数量 / (假正例数量 + 真反例数量),反映了模型将负例误判为正例的比例。
通过绘制 FPR 为横轴,TPR 为纵轴的曲线,我们就得到了 ROC 曲线。
一个好的分类模型,其 ROC 曲线应该尽量靠近左上角,这意味着在较低的假正例率下能获得较高的真正例率。
ROC曲线下方的区域又被称为AUC值,取值范围一般为0.5~1。使用AUC值作为评价标准是因为很多时候ROC曲线并不能清晰地说明哪个模型的效果更好,而作为一个数值,对应AUC值更大的模型预测效果更好。当AUC=1时,是完美模型,采用这个预测模型时,存在至少一个阈值能得出完美预测。绝大多数预测的场合不存在完美模型。
当0.5<AUC<1时,优于随机猜测。这个模型妥善设置阈值的话能有预测价值。
当AUC=0.5时,跟随机猜测一样,模型没有预测价值。当AUC<0.5时,比随机猜测还差;但只要总是反预测而行,就会优于随机猜测。
5.科恩kappa得分
kappa值作为评价判断的一致性程度的指标。科恩kappa得分既可以用于统计中来检验一致性,也可以用于机器学习中来衡量分类精度。科恩kappa得分的基本思想:将样本的预测值和实际值视为两个不同的评分者,观察两个评分者之间的一致性。由于样本分类一致性的大小不完全取决于特定机器学习算法的性能,还可能由于随机因素的作用,致使随机猜测与特定机器学习算法得出相同的分类结论。或者说,没有采用特定机器学习算法的随机猜测对样本进行分类也可能会得出与特定机器学习算法一样的结论,而这种一致性结论完全是由于随机因素导致的。所以在评价机器学习的真正性能时,需要剔除掉随机因素这种虚高的水分。
kappa取值为[0,1],值越大代表一致性越强/分类精度越高。具体衡量标准如表所示。
三、使用 scikit-learn
(sklearn
)库来计算上述一些性能指标的示例代码:
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
from sklearn.metrics import confusion_matrix
from sklearn.metrics import roc_auc_score
from sklearn.metrics import cohen_kappa_score
import numpy as np
# 假设这是真实的标签
y_true = np.array([1, 0, 1, 1, 0, 1, 0, 0, 1, 0])
# 假设这是模型的预测结果
y_pred = np.array([1, 0, 1, 0, 0, 1, 1, 0, 1, 0])
# 假设这是模型的预测概率
y_pred_probs = np.array([0.8, 0.3, 0.7, 0.2, 0.4, 0.9, 0.6, 0.1, 0.85, 0.35])
# 计算错误率
error_rate = 1 - accuracy_score(y_true, y_pred)
print("错误率:", error_rate)
# 计算精度
precision = precision_score(y_true, y_pred)
print("精度:", precision)
# 计算召回率
recall = recall_score(y_true, y_pred)
print("召回率:", recall)
# 计算 F1 值
f1 = f1_score(y_true, y_pred)
print("F1 值:", f1)
# 计算混淆矩阵
cm = confusion_matrix(y_true, y_pred)
print("混淆矩阵:\n", cm)
# 计算 AUC 值
auc = roc_auc_score(y_true, y_pred_probs)
print("AUC 值:", auc)
# 假设这是另一组预测的类别
y_pred_classes = np.array([1, 0, 1, 0, 0, 1, 1, 0, 1, 0])
# 计算科恩得分
kappa = cohen_kappa_score(y_true, y_pred_classes)
print("科恩得分:", kappa)
结果: