NLP-基础任务-中文分词算法(4)-评价指标:精确率(“模型分词结果集”与“标准答案集”的交集/“模型分词结果集”)、召回率(“模型分词结果集”与“标准答案集”的交集/“标准答案集”)、F1

一、分类模型中的:精确率、召回率、F1-Measure

在这里插入图片描述

  • 准确率(Accuracy):对于给定的测试数据集,分类器正确分类的样本数与总样本数之比。
    A c c u r a c y = T P + T N T P + T N + F P + F N Accuracy=\cfrac{TP+TN}{TP+TN+FP+FN} Accuracy=TP+TN+FP+FNTP+TN
  • 精确率(Precision)**:精指分类正确的正样本个数(TP)占分类器判定为正样本的样本个数(TP+FP)的比例。
    P r e c i s i o n = T P T P + F P Precision=\cfrac{TP}{TP+FP} Precision=TP+FPTP
  • 召回率(Recall):召回率是指分类正确的正样本个数(TP)占真正的正样本个数(TP+FN)的比例。
    R e c a l l = T P T P + F N Recall=\cfrac{TP}{TP+FN} Recall=TP+FNTP
  • F1-Measure值:就是精确率和召回率的调和平均值
    F 1 − M e a s u r e = 2 1 P r e c i s i o n + 1 R e c a l l \begin{aligned}F1-Measure=\cfrac{2}{\cfrac{1}{Precision}+\cfrac{1}{Recall}}\end{aligned} F1Measure=Precision1+Recall12

每个评估指标都有其价值,但如果只从单一的评估指标出发去评估模型,往往会得出片面甚至错误的结论;只有通过一组互补的指标去评估模型,才能更好地发现并解决模型存在的问题,从而更好地解决实际业务场景中遇到的问题。

二、分词算法中的:精确率、召回率、F1-Measure

前面说到的分类中的评估标准,但是在分词中标准答案和分词结果数不一定相等,因此要做一个思维转换。对于长为 n n n 的字符串,分词结果是一系列单词。设每个单词按照其在文中的起止位置可记作区间 [ i , j ] [i,j] [i,j] ,其中 i ≤ i ≤ j ≤ n i\leq i \leq j\leq n iijn 。那么:

  • 标准答案所有区间构成集合 A A A 作为正类,其它情况作为负类。
  • 同时,即分词结果所有单词构成的区间集合为 B B B

那么:

T P ∪ F N = A T P ∪ F P = B A ∩ B = T P \begin{aligned} TP\cup FN &= A\\ TP\cup FP&=B\\ A\cap B&=TP \end{aligned} TPFNTPFPAB=A=B=TP

因此相应的计算公式如下:

P r e c i s i o n = ∣ A ∩ B ∣ ∣ B ∣ ,    R e c a l l = ∣ A ∩ B ∣ ∣ A ∣ Precision=\frac{|A\cap B|}{|B|},\;Recall=\frac{|A\cap B|}{|A|} Precision=BAB,Recall=AAB

这样说可能有点晦涩,如下图所示:
在这里插入图片描述
可以发现,重合部分就是正确部分;因此,对于分词结果1来说,精确率和召回率均为0,因为没有重合部分。而对于分词结果2来说都为1。下面再来看个例子:
在这里插入图片描述

此时的精确率为: 3 / 5 = 0.6 3/5=0.6 3/5=0.6 ,召回率为: 3 / 6 = 0.5 3/6=0.5 3/6=0.5

3、OOV Recall 与 IV Recall

OOV指的是“未登录词”(Out Of Vocabulary)的简称,也就是新词,已知词典中不存在的词。出现OOV的原因一方面可能确实是因为产生了有意义的新词而词典并没有收录;另一方面可能就是因为分词器产生的错误无意义的分词结果,这当然也不会出现在字典中。

IV指的是“登陆词”(In Vocabulary),也就是已经存在字典中的词。而OOV Recall和IV Recall 分别指的就是OOV的召回率和IV的召回率。为了说明这两个召回率的具体含义,请先耐心看下面的详细例子:

词典:[‘结婚’, ‘尚未’, ‘的’, ‘和’, ‘青年’, ‘都’, ‘应该’, ‘好好考虑’, ‘自己’, ‘人生’, ‘大事’]

标准分词 A:[‘结婚’,’ 的’,’ 和’,’ 尚未’,’ 结婚 ‘,‘的’,’ 都’,’ 应该’,’ 好好’,’ 考虑’,’ 一下’,’ 人生’,’ 大事’]
标准区间 A:[1,2],[3,3],[4,4],[5,6],[7,8],[9,9],[10,10],[11,12],[13,14],[15,16],[17,18],[19,20],[21,22]

分词结果 B:[‘结婚’,’ 的’,‘和尚’,‘未结婚 ‘,‘的 ‘,‘都’,’ 应该’,’ 好好考虑’,’ 一下’,’ 人生大事’]
分词区间 B:[1,2],[3,3],[4,5],[6,7,8],[9,9],[10,10],[11,12],[13,14,15,16],[17,18],[19,20,21,22]

重复词语 A∩B:[‘结婚’,’ 的’,’ 的’,’ 都’,’ 应该’,’ 一下’]
重复区间 A∩B:[1,2], [3,3], [9,9],[10,10],[11,12],[17,18]

R e c a l l = 6 10 = 0.6 P r e c i s i o n = 6 13 = 0.4615 F 1 = 2 × 0.6 × 0.4615 0.6 + 0.4615 = 0.5217 O O V R e c a l l = 重复词区间未在词典中出现的词 标准分词中未在词典中出现的词 = 1 3 = 0.3333 I V R e c a l l = 重复词区间在词典中出现的词 标准分词中在词典中出现的词 = 5 10 = 0.5 \begin{aligned} Recall & = \frac{6}{10} = 0.6\\[1ex] Precision & = \frac{6}{13}=0.4615\\[1ex] F1 & = \frac{2\times 0.6\times 0.4615}{0.6+0.4615} = 0.5217\\[2ex] OOV Recall & = \frac{\text{重复词区间未在词典中出现的词}}{\text{标准分词中未在词典中出现的词}}=\frac{1}{3}=0.3333\\[2ex] IV Recall &=\frac{\text{重复词区间在词典中出现的词}}{\text{标准分词中在词典中出现的词}}=\frac{5}{10}=0.5 \end{aligned} RecallPrecisionF1OOVRecallIVRecall=106=0.6=136=0.4615=0.6+0.46152×0.6×0.4615=0.5217=标准分词中未在词典中出现的词重复词区间未在词典中出现的词=31=0.3333=标准分词中在词典中出现的词重复词区间在词典中出现的词=105=0.5

前面三项指标同第3节中的一样,不在赘述。从上面的计算过程可以看到:

  • OOV召回率等于重复词区间未在词典中出现的词除以标准分词中未在词典中出现的词。需要注意的是重复词区间未在词典中出现的词就意味着未在字典中出现的新词是有意义的,只是字典没有收录而已;同理标准分词中未在词典中出现的词就更是如此。同时也可以将两者分别称为重复词区间有意义的新词所有有意义的新词。有意义的新词越多也就表示你用来分词的字典收录越不全(可能也会因为词语的颗粒度大小造成),而OOV recall越低也就意味着词典分词器对有意义新词的发现或者说查找能力越低。

O O V R e c a l l = 重复词区间未在词典中出现的词 标准分词中未在词典中出现的词 = 重复词区间有意义的新词 所有有意义的新词 \begin{aligned} OOV Recall & = \frac{\text{重复词区间未在词典中出现的词}}{\text{标准分词中未在词典中出现的词}}=\frac{\text{重复词区间有意义的新词}}{\text{所有有意义的新词}} \end{aligned} OOVRecall=标准分词中未在词典中出现的词重复词区间未在词典中出现的词=所有有意义的新词重复词区间有意义的新词

同理,从IV 召回率的计算公式可以发现重复词区间在词典中出现的词指的就是分词得到的正确部分(即正样本);标准分词中在词典中出现的词指的就是所有正样本。因此,IV 召回率就可以来衡量词典中的词被正确找回的概率。如果IV召回率低,就说明字典分词器连词典中的词汇都无法百分之百的发现或者找回,说明其消歧能力不好。例如“商品,和服,服务”三个词都在词典中,词典分词依然可能分布对句子”商品和服务“。

import re
 ​
 def to_region(segmentation: str) -> list:
     """
     将分词结果转换为区间
     :param segmentation: 商品 和 服务
     :return: [(0, 2), (2, 3), (3, 5)]
     """
     region = []
     start = 0
     for word in re.compile("\\s+").split(segmentation.strip()):
         end = start + len(word)
         region.append((start, end))
         start = end
     return region
 ​
 ​
 def prf(gold: str, pred: str, dic) -> tuple:
     """
     计算P、R、F1
     :param gold: 标准答案文件,比如“商品 和 服务”
     :param pred: 分词结果文件,比如“商品 和服 务”
     :param dic: 词典
     :return: (P, R, F1, OOV_R, IV_R)
     """
     A_size, B_size, A_cap_B_size, OOV, IV, OOV_R, IV_R = 0, 0, 0, 0, 0, 0, 0
     A, B = set(to_region(gold)), set(to_region(pred))
     A_size += len(A)
     B_size += len(B)
     A_cap_B_size += len(A & B)
     text = re.sub("\\s+", "", gold)for (start, end) in A:
         word = text[start: end]
         if word in dic:
             IV += 1
         else:
             OOV += 1for (start, end) in A & B:
         word = text[start: end]
         if word in dic:
             IV_R += 1
         else:
             OOV_R += 1
     p, r = A_cap_B_size / B_size * 100, A_cap_B_size / A_size * 100
     return p, r, 2 * p * r / (p + r), OOV_R / OOV * 100, IV_R / IV * 100
 ​
 ​
 if __name__ == '__main__':
     dic = ['结婚', '尚未', '的', '和', '青年', '都', '应该', '好好考虑', '自己',  '人生', '大事']
     gold = '结婚 的 和 尚未 结婚 的 都 应该 好好 考虑 一下 人生 大事'
     pred = '结婚 的 和尚 未结婚 的 都 应该 好好考虑 一下 人生大事'
     print("Precision:%.2f Recall:%.2f F1:%.2f OOV-R:%.2f IV-R:%.2f" % prf(gold, pred, dic))



参考资料:
NLP中文分词的评估指标

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值