准确率、召回率、F1、ROC曲线、AUC曲线、PR曲线基本概念

查准率P、查全率R和F1概念:

混淆矩阵:

预测值为正例,记为P(Positive)
预测值为反例,记为N(Negative)
预测值与真实值相同,记为T(True)
预测值与真实值相反,记为F(False)
在这里插入图片描述
TP:预测类别是P(正例),真实类别也是P

FP:预测类别是P,真实类别是N(反例)
TN:预测类别是N,真实类别也是N
FN:预测类别是N,真实类别是P
样本中的真实正例类别总数即TP+FN。TPR即True Positive Rate,

              准确率(查准率):TPR = TP/(TP+FN)

样本中的真实反例类别总数为FP+TN。FPR即False Positive Rate

              召回率(查全率):FPR = FP/(TN+FP)

PR曲线:

在这里插入图片描述

F1 是精确率和召回率的调和平均。
frac{2}{F1}  = \frac{1}{P} + \frac{1}{R}
在这里插入图片描述

ROC曲线

对于0,1两类分类问题,一些分类器得到的结果往往不是0,1这样的标签,如神经网络,得到诸如0.5,0,8这样的分类结果。这时,我们人为取一个阈值,比如0.4,那么小于0.4的为0类,大于等于0.4的为1类,可以得到一个分类结果。同样,这个阈值我们可以取0.1,0.2等等。取不同的阈值,得到的最后的分类情况也就不同。

如下面这幅图:
在这里插入图片描述

蓝色表示原始为负类分类得到的统计图,红色为正类得到的统计图。那么我们取一条直线,直线左边分为负类,右边分为正,这条直线也就是我们所取的阈值。

阈值不同,可以得到不同的结果,但是由分类器决定的统计图始终是不变的。这时候就需要一个独立于阈值,只与分类器有关的评价指标,来衡量特定分类器的好坏。

还有在类不平衡的情况下,如正样本90个,负样本10个,直接把所有样本分类为正样本,得到识别率为90%。但这显然是没有意义的。

如上就是ROC曲线的动机。

放在具体领域来理解上述两个指标。
如在医学诊断中,判断有病的样本。
那么尽量把有病的揪出来是主要任务,也就是第一个指标TPR,要越高越好。
而把没病的样本误诊为有病的,也就是第二个指标FPR,要越低越好。

不难发现,这两个指标之间是相互制约的。如果某个医生对于有病的症状比较敏感,稍微的小症状都判断为有病,那么他的第一个指标应该会很高,但是第二个指标也就相应地变高。最极端的情况下,他把所有的样本都看做有病,那么第一个指标达到1,第二个指标也为1。

我们以FPR为横轴,TPR为纵轴,得到如下ROC空间。
在这里插入图片描述

我们可以看出,左上角的点(TPR=1,FPR=0),为完美分类,也就是这个医生医术高明,诊断全对。

点A(TPR>FPR),医生A的判断大体是正确的。中线上的点B(TPR=FPR),也就是医生B全都是蒙的,蒙对一半,蒙错一半;下半平面的点C(TPR<FPR),这个医生说你有病,那么你很可能没有病,医生C的话我们要反着听,为真庸医。

上图中一个阈值,得到一个点。现在我们需要一个独立于阈值的评价指标来衡量这个医生的医术如何,也就是遍历所有的阈值,得到ROC曲线。

还是一开始的那幅图,假设如下就是某个医生的诊断统计图,直线代表阈值。我们遍历所有的阈值,能够在ROC平面上得到如下的ROC曲线。

在这里插入图片描述

曲线距离左上角越近,证明分类器效果越好。

在这里插入图片描述

如上,是三条ROC曲线,在0.23处取一条直线。那么,在同样的低FPR=0.23的情况下,红色分类器得到更高的PTR。也就表明,ROC越往上,分类器效果越好。我们用一个标量值AUC来量化他。

ROC曲线:
ROC曲线

AUC

AUC值为ROC曲线所覆盖的区域面积,显然,AUC越大,分类器分类效果越好。

AUC = 1,是完美分类器,采用这个预测模型时,不管设定什么阈值都能得出完美预测。绝大多数预测的场合,不存在完美分类器。

0.5 < AUC < 1,优于随机猜测。这个分类器(模型)妥善设定阈值的话,能有预测价值。

AUC = 0.5,跟随机猜测一样(例:丢铜板),模型没有预测价值。

AUC < 0.5,比随机猜测还差;但只要总是反预测而行,就优于随机猜测。

AUC的物理意义
假设分类器的输出是样本属于正类的socre(置信度),则AUC的物理意义为,任取一对(正、负)样本,正样本的score大于负样本的score的概率。

计算AUC:
第一种方法:AUC为ROC曲线下的面积,那我们直接计算面积可得。面积为一个个小的梯形面积之和。计算的精度与阈值的精度有关。

第二种方法:根据AUC的物理意义,我们计算正样本score大于负样本的score的概率。取NM(N为正样本数,M为负样本数)个二元组,比较score,最后得到AUC。时间复杂度为O(NM)。

第三种方法:与第二种方法相似,直接计算正样本score大于负样本的概率。我们首先把所有样本按照score排序,依次用rank表示他们,如最大score的样本,rank=n(n=N+M),其次为n-1。那么对于正样本中rank最大的样本,rank_max,有M-1个其他正样本比他score小,那么就有(rank_max-1)-(M-1)个负样本比他score小。其次为(rank_second-1)-(M-2)。最后我们得到正样本大于负样本的概率为

在这里插入图片描述

时间复杂度为O(N+M)。

参考:
1.ROC曲线与AUC:https://blog.csdn.net/ice110956/article/details/20288239
2.ROC与AUC的定义与使用详解:https://blog.csdn.net/shenxiaoming77/article/details/72627882
3.周志华西瓜书第二章

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
下面是一个使用Python实现Accuracy类、F1度量类、P-R曲线类、ROC曲线类和AUC类的示例代码: ```python import matplotlib.pyplot as plt class Accuracy: def __init__(self, y_true, y_pred): self.y_true = y_true self.y_pred = y_pred def accuracy_score(self): correct = sum([1 for yt, yp in zip(self.y_true, self.y_pred) if yt == yp]) total = len(self.y_true) accuracy = correct / total return accuracy class F1Score: def __init__(self, y_true, y_pred): self.y_true = y_true self.y_pred = y_pred def precision_recall_f1(self): true_positives = sum([1 for yt, yp in zip(self.y_true, self.y_pred) if yt == 1 and yp == 1]) false_positives = sum([1 for yt, yp in zip(self.y_true, self.y_pred) if yt == 0 and yp == 1]) false_negatives = sum([1 for yt, yp in zip(self.y_true, self.y_pred) if yt == 1 and yp == 0]) precision = true_positives / (true_positives + false_positives) if (true_positives + false_positives) > 0 else 0 recall = true_positives / (true_positives + false_negatives) if (true_positives + false_negatives) > 0 else 0 f1_score = 2 * (precision * recall) / (precision + recall) if (precision + recall) > 0 else 0 return precision, recall, f1_score class PRCurve: def __init__(self, y_true, y_scores): self.y_true = y_true self.y_scores = y_scores def precision_recall_curve(self): thresholds = sorted(set(self.y_scores), reverse=True) precisions = [] recalls = [] for threshold in thresholds: y_pred = [1 if score >= threshold else 0 for score in self.y_scores] true_positives = sum([1 for yt, yp in zip(self.y_true, y_pred) if yt == 1 and yp == 1]) false_positives = sum([1 for yt, yp in zip(self.y_true, y_pred) if yt == 0 and yp == 1]) false_negatives = sum([1 for yt, yp in zip(self.y_true, y_pred) if yt == 1 and yp == 0]) precision = true_positives / (true_positives + false_positives) if (true_positives + false_positives) > 0 else 0 recall = true_positives / (true_positives + false_negatives) if (true_positives + false_negatives) > 0 else 0 precisions.append(precision) recalls.append(recall) return precisions, recalls class ROCCurve: def __init__(self, y_true, y_scores): self.y_true = y_true self.y_scores = y_scores def roc_curve(self): thresholds = sorted(set(self.y_scores), reverse=True) tpr_values = [] fpr_values = [] num_positive_cases = sum([1 for yt in self.y_true if yt == 1]) num_negative_cases = sum([1 for yt in self.y_true if yt == 0]) for threshold in thresholds: y_pred = [1 if score >= threshold else 0 for score in self.y_scores] true_positives = sum([1 for yt, yp in zip(self.y_true, y_pred) if yt == 1 and yp == 1]) false_positives = sum([1 for yt, yp in zip(self.y_true, y_pred) if yt == 0 and yp == 1]) tpr = true_positives / num_positive_cases if num_positive_cases > 0 else 0 fpr = false_positives / num_negative_cases if num_negative_cases > 0 else 0 tpr_values.append(tpr) fpr_values.append(fpr) return tpr_values, fpr_values class AUC: def __init__(self, tpr, fpr): self.tpr = tpr self.fpr = fpr def auc_score(self): auc = 0 for i in range(1, len(self.fpr)): auc += (self.fpr[i] - self.fpr[i-1]) * (self.tpr[i] + self.tpr[i-1]) / 2 return auc # 示例数据 y_true = [1, 0, 1, 1, 0, 0, 1] y_scores = [0.9, 0.6, 0.8, 0.7, 0.4, 0.3, 0.5] # 计算并输出准确率 accuracy = Accuracy(y_true, y_scores) acc = accuracy.accuracy_score() print("Accuracy:", acc) # 计算并输出精确率、召回率F1度量 f1_score = F1Score(y_true, y_scores) precision, recall, f1 = f1_score.precision_recall_f1() print("Precision:", precision) print("Recall:", recall) print("F1 Score:", f1) # 计算并绘制P-R曲线 pr_curve = PRCurve(y_true, y_scores) precisions, recalls = pr_curve.precision_recall_curve() plt.plot(recalls, precisions) plt.xlabel('Recall') plt.ylabel('Precision') plt.title('P-R Curve') plt.show() # 计算并绘制ROC曲线 roc_curve = ROCCurve(y_true, y_scores) tpr_values, fpr_values = roc_curve.roc_curve() plt.plot(fpr_values, tpr_values) plt.xlabel('False Positive Rate') plt.ylabel('True Positive Rate') plt.title('ROC Curve') plt.show() # 计算并输出AUC auc = AUC(tpr_values, fpr_values) auc_score = auc.auc_score() print("AUC Score:", auc_score) ``` 这段代码展示了如何实现Accuracy类、F1度量类、P-R曲线类、ROC曲线类和AUC类。你可以根据你的实际需求进行修改和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值