通俗讲解P(查准率),R(查全率),F1值

通俗讲解P(查准率),R(查全率),F1值

作者zenRRan 来源:公众号深度学习自然语言处理

一、怎么来的?

我们平时用的精度accuracy,也就是整体的正确率

acc=predict_right_num/predict_num

这个虽然常用,但不能满足所有任务的需求。比如,因为香蕉太多了,也不能拨开人工的一个一个的看它的好坏(我爱吃啊,想想就心疼),此时我们就需要有一种方法,代替拨开香蕉这种粗鲁的手段。这时我们需要通过一些测试,看看哪种方法能更加准确的预测。我们可以通过

“准”:预测的准确度,就是我预测的结果中真正好的香蕉要越多越好;

“全”:就是所有的好的香蕉预测出来的越多越好,虽然把有些坏的也预测是好的了,那也不管,“全”就行。

其实这两者都想要达到就好了,但是不行的:

比如"准",我就预测一个算了,好的香蕉肯定比坏的比例高,也就是我只预测一个,100%比例几率最大了,这时就不“全”了,海域好多好的不能都当成坏的扔了吧。。

再比如"全",我去全部预测成好的这真正好的都在我的预测里,也就是100%。可是这时的"准"就贼不准了。。

所以就必须来平衡这俩同志的关系了,怎么平衡呢?肯定是通过权重来的呀,此时,F值登上历史舞台!

二、啥意思捏?

实例化讲解吧。比如我们的香蕉中 1 表示好的,0表示坏的,有10个香蕉:

gold : [ 1,1,1,1,1,0,0,0,0,0 ]

pred: [ 1,0,1,1,1,1,1,0,0,0 ]

注释:gold是现实的好坏;pred是预测的好坏。

P(Precision) 查准率:就是上面说的"准"。字面意思好理解呀,就是在预测当中查找准确个数的比例。公式为:

P=真正预测准确的数量/预测是准确的数量 = 4 / 6

R(Recall) 查全率:就是上面的"全"。根据字面理解,在预测中看看真正预测对的占全有对的比率。公式为:

R=真正预测准确的数量/所有真正好的数量 = 4 / 5

F值是:

F(k)=(1+k)*P*R/((k*k)*P+R)

注释:k>0 度量了 查全率 对 查准率 的相对重要性。k>1查全率有更大影响;k<1查准率有更大影响。

在这个实例中可以表示为:k>1就是查全率有更大影响,就是好的香蕉最好都预测出来,因为你觉得不想把好的当成坏的扔点( 真可惜,我爱吃啊 ) ;

k<1查准率有更大影响,就是一定要准确,省时间,省力更重要,不在乎好的香蕉当坏的扔点。

而我们常用的是F1,就是F(1)的意思,k=1,比如我们做一个分类任务,这几个类觉得都一样重要。此时:

F(1)=2*P*R/(P+R)=(2*4/6*5/6)/(4/6+5/6)=40/54

三、代码实现

这里用核心的代码帮助上述理解!

我还是用上面的例子:

gold : [ 1,1,1,1,1,0,0,0,0,0 ]

pred: [ 1,0,1,1,1,1,1,0,0,0 ]

我们以数组中为1的index下标作为标签,那么gold的是[0,1,2,3,4]里面的数值代表原始数据为1对应的下标值。

predict的是[0,2,3,4,5,6]

我们来编程求解它的F值!代码如下:

def cal_f(gold, predict):
    p_numerator, r_numerator = 0., 0.

    for entity in predict:
        if entity in gold:
            p_numerator += 1

    for entity in gold:
        if entity in predict:
            r_numerator += 1

    return p_numerator, r_numerator


gold = [0,1,2,3,4]
predict = [0,2,3,4,5,6]

p_denominator = len(predict)
r_denominator = len(gold)


p_numerator, r_numerator = cal_f(gold, predict)

precision = p_numerator / p_denominator
recall = r_numerator / r_denominator
f1 = 2 * precision * recall / (precision + recall)

print("f value:{0}".format(f1))

结果如下:

讲解到这,应该讲的很详细了!

编辑于 2018-04-26

文章被以下专栏收录