后记 6.1
关于目标检测的计算
https://stats.stackexchange.com/a/315216
训练Embedding的时候,程序里面发现了AUC,因此处正样本始终只有一个(参考上一篇)为了克服样本不平衡带来的metric指示出现不能反应模型真实能力的问题(比如acc中,模型很有可能偏向比重大的标签),需要AUC进行判别。以前试过几次,过段时间就忘了,希望这次理解深刻些。
关于理解
先附上链接:机器学习和统计里面的auc怎么理解? - 小小丘的回答 - 知乎
提炼一下顿悟的地方,关键句:AUC: 在二分类问题中,从正样本集和负样本集中各自随机抽样
一个样本\\(s^1、s^0\\),用模型得到两个分类结果\\(y^0=model(s^0), y^1=model(s^1)\\), AUC被定义为 \\(y^1> y^0\\)的概率。
听起来可能还是有些绕,具体考虑一下该怎么求这个值就会清楚些。
首先构建样本对集合,每个样本对:\\(ss_{i,j}=(s^1_i,s^0_j), i\\in [0,M-1], j\\in [0,N-1]\\),从这个集合里面抽样可以满足各自随机抽样的的要求。对样本对进行概率比较:\\(I_{i,j}=1~if~ y^1_i > y^0_j~else~ 0\\),这样可以得到一个二值矩阵\\(I\\)。求这个矩阵的平均数,就是AUC。
这样之后,还可以进一步考虑一个例子。比如,现在有一个真钞和一个伪钞(已知一定有真假之分),用模型进行鉴别,如果模型的AUC指标好,我选择模型鉴定为真的钞票时(输出值更大那个)更自信。考虑一下自信从哪儿来的?
重新考虑一下矩阵\\(I\\),已知每个样本对里面一定有一个正样本,所以最佳状态应该是每个元素都为1,即每个正样本的分数都排在负样本上方。如果分类的阈值能够自动调节到恰好包含所有正样本(区别于softmax里面的0.5固定值),那么AUC可以理解为当模型预测为正样本时的命中率,或者说被预测为正样本中正样本的纯度。(所以更自信...)
关于计算
上面矩阵的方法容易理解,但不易于计算\\(O(MN)\\)。实际计算时,通过排序可以降至\\(O((M+N)log(M+N))+O(M+N)\\)。参考上面知乎的解答。主要意思是排序后,每访问到一个正样本就可以确定有多少负样本位于下方。相当于,行遍历矩阵\\(I\\)时,每次都直接确定该行的元素和(\\(1\\)的数量)。附上一段计算程序
# mxnet/example/nce_loss/nce.py
# tmp:[(label, pred_score),...] 假定 [ (0,1), (1, 0.3), (0, 0.9), (1, 0.8),(0, 0.5) ]
tmp = sorted(tmp, key=itemgetter(1), reverse=True) # 排序后 [(0, 0.9), (1, 0.8), (0, .5), (1, 0.3), (0, 0.1)]
m = 0.0
n = 0.0
z = 0.0
k = 0
for a, _ in tmp:
if a > 0.5:
m += 1.0 # 全部过程中m的变化情况 [0, 1, 1, 2, 2] 最终值是正样本的个数
z += len(tmp) - k # 对正样本的位次累加 位次依次为 z_l=[4, 2] -> I.shape=(2,3), 每行的和:[4-m, 2-(m-1)] (m=2)
# 4-m: 后续样本(含改点)-其中正样本数量=该行1的数量
else:
n += 1.0
k += 1
z -= m * (m + 1.0) / 2.0 # [m, m-1, m-2, ... ] 求和
z /= m
z /= n
一句话总结,AUC
: 正样本的纯度。