自然语言处理学习笔记(八)———— 准确率

目录

1.准确率定义

2.混淆矩阵与TP/FN/FP/TN

[3. 精确率](#3. 精确率)

4.召回率

5.F1值

6.中文分词的P、R、F1计算

7.实现


1.准确率定义

准确率是用来衡量一个系统的准确程度的值,可以理解为一系列评测指标。当预测与答案的数量相等时,准确率指的是系统做出正确判断的次数除以总的测试次数。

在中文分词任务中,一般使用在标准数据集上词语级别的精确率、召回率与F1值来衡量分词器的准确程度。这三个术语借用自信息检索与分类问题,常用来衡量搜索引擎和分类器的准确程度。

2.混淆矩阵与TP/FN/FP/TN

搜索引擎、分类器、中文分词场景下的准确率本质上都是4个集合的并集运算。分类预测与答案的四种组合:

预测/答案 P N
P TP FP
N FN TN

(1) TP (true postive) :预测是P ,答案果然是真的P

(2) FP (false postive) : 预测是P ,答案是N ,因此是假的P

(3) TN (true postive) : 预测是N ,答案果然是真的N

(4) FN (false postive) : 预测是N ,答案是P,因此是假的P

上表在机器学习中被称为混淆矩阵,用来衡量分类结果的混淆程度。混淆矩阵有如下性质:

只要混淆矩阵确定了,三个准确指标就都确定了。

3. 精确率

精确率(precision ,简称P值) 指的是预测结果中正类数量占全部结果的比率。正类的选择非常重要。

4.召回率

召回率(Recall)指的是正类样本中能被找出来的比率。

区分P值和R值的时候,只需记住两者分子都是真阳的样本数,只不过P值的分母是预测阳性 的数量,而R值的分母是答案阳性的数量。

5.F1值

一般而言,精确率和召回率难以平衡,召回率高的系统往往精确率低,反之亦然。

精确率和召回率的调和平均F1的值来作为综合性指标:

6.中文分词的P、R、F1计算

在中文分词中,标准答案和分词结果的单词数不一定相等。而且混淆矩阵针对的是分类问题,而中文分词却是一个分块(chunking)问题。

将分块问题转换为分类问题。对于长为 n 的字符串,分词结果是一系列单词。每个单词按它在文本中的起止位置可记作区间【i,j】,其中。那么所有标准答案的所有区间构成一个集合 A ,称为正类。此集合之外的所有区间构成另一个集合(A的补集),作为负类。同理,记所有分词结果的区间构成集合B。则:

例如:

7.实现

python 复制代码
import re
from pyhanlp import *
from tests.test_utility import ensure_data


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
    with open(gold, encoding='utf-8') as gd, open(pred, encoding='utf-8') as pd:
        for g, p in zip(gd, pd):
            A, B = set(to_region(g)), set(to_region(p))
            A_size += len(A)
            B_size += len(B)
            A_cap_B_size += len(A & B)
            text = re.sub("\\s+", "", g)
            for (start, end) in A:
                word = text[start: end]
                if dic.containsKey(word):
                    IV += 1
                else:
                    OOV += 1

            for (start, end) in A & B:
                word = text[start: end]
                if dic.containsKey(word):
                    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__':
    print(to_region('商品 和 服务'))

    sighan05 = ensure_data('icwb2-data', 'http://sighan.cs.uchicago.edu/bakeoff2005/data/icwb2-data.zip')
    msr_dict = os.path.join(sighan05, 'gold', 'msr_training_words.utf8')
    msr_test = os.path.join(sighan05, 'testing', 'msr_test.utf8')
    msr_output = os.path.join(sighan05, 'testing', 'msr_output.txt')
    msr_gold = os.path.join(sighan05, 'gold', 'msr_test_gold.utf8')

    DoubleArrayTrieSegment = JClass('com.hankcs.hanlp.seg.Other.DoubleArrayTrieSegment')
    segment = DoubleArrayTrieSegment([msr_dict]).enablePartOfSpeechTagging(True)
    with open(msr_gold, encoding='utf-8') as test, open(msr_output, 'w', encoding='utf-8') as output:
        for line in test:
            output.write("  ".join(term.word for term in segment.seg(re.sub("\\s+", "", line))))
            output.write("\n")
    print("P:%.2f R:%.2f F1:%.2f OOV-R:%.2f IV-R:%.2f" % prf(msr_gold, msr_output, segment.trie))
相关推荐
知识分享小能手1 分钟前
Vue3 学习教程,从入门到精通,Vue 3 + Tailwind CSS 全面知识点与案例详解(31)
前端·javascript·css·vue.js·学习·typescript·vue3
茴香豆的茴132 分钟前
转码刷 LeetCode 笔记[2]:203. 移除链表元素(python)
笔记·leetcode·链表
wdfk_prog1 小时前
[Linux]学习笔记系列 -- [arm][lds]
linux·运维·arm开发·笔记·学习
晨非辰2 小时前
#C语言——刷题攻略:牛客编程入门训练(六):运算(三)-- 涉及 辗转相除法求最大公约数
c语言·开发语言·经验分享·学习·学习方法·visual studio
无名咸鱼2 小时前
CICD部署流程详解文档笔记
笔记·ci/cd
Gloria_niki3 小时前
爬虫与数据分析结合案例学习总结
爬虫·学习·数据分析
秋风战士3 小时前
通信算法之306:精通FPGA-笔记核心
笔记·fpga开发
一颗正在价投韭菜3 小时前
《范仲淹传》读书笔记与摘要
笔记·学习·范仲淹
遇见尚硅谷4 小时前
C语言:单链表学习
java·c语言·学习
teeeeeeemo5 小时前
js 实现 ajax 并发请求
开发语言·前端·javascript·笔记·ajax