那些年被绕糊涂的查全率与查准率-一次讲明白
NLP测试-性能(评价)指标
工业界评价NLP模型,更大的系统层级评价常常使用 准确率和误召回率
1 这里先谈谈召回率
召回率即查全率,记为R, 查准率即为P
记住三个层次
1 查全率 所有的西瓜中所有的好瓜中有多少被挑了出来。
查准率 跳出来的好瓜中有多少好瓜
2 混淆矩阵
绘制混淆矩阵 先搞清楚横纵坐标
横坐标,列名字 , 预测值
纵坐标,行名字,真实值
然后预测值对于真实值就有
预测值
正例 反例
正例 TP FN
反列 FP TN
则召回率为 关心的是 正例中多少被挑出,即第一行
R TP/TP+FN
查准率 关心的是在预测正例中多少是正确的
TP/TP+FP
由此绘制P-R曲线
*注意 p高R可能就会低。 只有较为简单的分类任务,P和R都会高
NLP测试的 指标
误召回率 = 负召回 + 召回错误+ slots错误/ 总数
即求得是 负样本的 召回率
负召回对应 领域错误
召回错误 对应 意图领域错误
slots错误 对应 词槽分类错误
查全率= 针对目标样本不可放过一个的情况,如web目标信息查询, 小区盗窃闯入情况识别,任何闯入情况都要被识别到,而不允许一起闯入被漏掉
总结:目标样本 没漏掉,对目标样本识别率高。
查准率=关心的是选中目标样本的准确率,垃圾邮件场景,需要除去大量垃圾邮件,但是不能漏掉一些看似垃圾邮件实则正常邮件。
总结:非目标样本 能识别,对非目标样本识别率高。
更现实例子,比如你是一个瓜农,需要给一个特别重要会议供货,要求全部是好瓜。
那么就需要关注的是查全率 即召回率。因为你判断为好瓜的瓜一定是好瓜就完成了任务。
如果你买进一批西瓜,让你挑,这个时候你需要派出你的徒弟,这个徒弟,只要能判断为坏瓜的瓜一定是坏瓜就基本完成了任务。
他挑好瓜的精确率一定是百分百。
总结当目标样本为好瓜时, 查全率关注 多少坏瓜被分作好瓜
查准率关注 多少好瓜被分作坏瓜里。
-------------------------------------------------------------------------------------------------
以下是PR曲线绘制方法-可分部分看
1 评价模型好坏
P-R曲线面积,然后再去调参
计算面积方法为:sklearn.metrics.average_precision_score(y_true, y_score, average='macro', pos_label=1, sample_weight=None)
P-R曲线绘制方法为
precision, recall, thresholds = precision_recall_curve(y_true, y_scores)
result = array([0.1, 0.35, 0.4, 0.8])
>>> import numpy as np >>> from sklearn.metrics import precision_recall_curve >>> y_true = np.array([0, 0, 1, 1]) >>> y_scores = np.array([0.1, 0.4, 0.35, 0.8]) >>> precision, recall, thresholds = precision_recall_curve( ... y_true, y_scores) >>> precision array([0.66666667, 0.5 , 1. , 1. ]) >>> recall array([1. , 0.5, 0.5, 0. ]) >>> thresholds array([0.35, 0.4 , 0.8 ])
绘制方法 自动设置thr
import numpy as np
from sklearn.metrics import precision_recall_curve
import matplotlib.pyplot as plt
y_true = np.array([0, 0, 1, 1,])
y_true2 = np.array([0, 0, 1, 1, 0, 1])
y_scores = np.array([0.1, 0.4, 0.35, 0.8])
precision, recall, thresholds = precision_recall_curve(y_true, y_scores)
print(precision)
# array([0.66666667, 0.5 , 1. , 1. ])
print(recall)
# array([1. , 0.5, 0.5, 0. ])
print(thresholds)
# array([0.35, 0.4 , 0.8 ])
# model2
y_scores2 = np.array([0.1, 0.4, 0.8, 0.9, 0.2, 0.3])
precision2, recall2, thresholds2 = precision_recall_curve(y_true2, y_scores2)
print("precision2=",precision2)
print("recall2=",recall2)
print("thresholds2=",thresholds2)
# 绘制曲线
plt.figure()
plt.xlabel("Recall")
plt.ylabel("Precison")
plt.plot(recall,precision)
plt.plot(recall2,precision2)
plt.show()

可以人工设置 thr 然后利用excel绘制
-
注意thresholds是需要后面加一维。precision,recall,当取一个thr就会重新判断一批pred,= 新的precison和recall这样每一个或若干个预测值作为thr,就可以绘制pre和recall曲线。
也可以绘制另外一种即,横坐标为thr,纵坐标为pre和recall,绘制两条线。
注意 p曲线与r曲线交点不是thr最优值,还是p与r计算F1score最大值最佳。 -
计算方法:
1 验证样本计算出置信度
2 置信度排序(即预测值)
3 每一个样本置信度结果作为thr阈值
注意最后一个时>=1,P=0/0算作1,R=0/N=0
注意 >=0 在第一位 P = 0 R = n/n = 1
sklearn包中也是thr缺少最后一位默认时>=1 但是precision和recall计算了出来。
4 计算对应precision和recall
5 绘制pr曲线
曲线意义,两个模型的pr曲线又包含关系说明外面的模型性能更好
若不包含比较p=r点的位置
调参:pr曲线积分更大的说明超参比较好
对于sigmod阈值
最初的想法是根据绘制出的thr 和 p曲线与r曲线的交点p=r处的thr值作为 sigmod阈值
以针对样本不均衡问题
但是实际样本不均衡问题这样解决会因为数据类别分布问题让模型训练效果偏向某一个类别
sigmod的阈值,定义的本身就是认为 输入的 样本集为 正太分布所以才可以以0.5作为阈值。
再损失函数中调节阈值,
对于样本不均匀问题,可以拆解为多个目标优化问题,即多目标凸优化问题
函数表示为w1f(x1)+w2 f(x2)=loss x1与x2样本不均衡,可以通过调节函数前面的系数
搜索google关键字 多目标优化
ROC曲线需要的横纵坐标数据为
![]()
当正负样本不均衡时 PR曲线效果更好
当正负样本均衡时 PR曲线与ROC曲线差不多
-


浙公网安备 33010602011771号