【问题标题】:How to calculate tag-wise precision and recall for POS tagger?如何计算 POS 标记器的标记精度和召回率?
【发布时间】:2011-07-12 23:28:37
【问题描述】:

我正在使用一些基于规则和统计的词性标注器来用词性 (POS) 标注一个语料库(大约 5000 个句子)。以下是我的测试语料库的 sn-p,其中每个单词都由其各自的 POS 标签用“/”分隔。

No/RB ,/, it/PRP was/VBD n't/RB Black/NNP Monday/NNP ./.
But/CC while/IN the/DT New/NNP York/NNP Stock/NNP Exchange/NNP did/VBD n't/RB fall/VB apart/RB Friday/NNP as/IN the/DT Dow/NNP Jones/NNP Industrial/NNP Average/NNP plunged/VBD 190.58/CD points/NNS --/: most/JJS of/IN it/PRP in/IN the/DT final/JJ hour/NN --/: it/PRP barely/RB managed/VBD *-2/-NONE- to/TO stay/VB this/DT side/NN of/IN chaos/NN ./.
Some/DT ``/`` circuit/NN breakers/NNS ''/'' installed/VBN */-NONE- after/IN the/DT October/NNP 1987/CD crash/NN failed/VBD their/PRP$ first/JJ test/NN ,/, traders/NNS say/VBP 0/-NONE- *T*-1/-NONE- ,/, *-2/-NONE- unable/JJ *-3/-NONE- to/TO cool/VB the/DT selling/NN panic/NN in/IN both/DT stocks/NNS and/CC futures/NNS ./.

标注语料后是这样的:

No/DT ,/, it/PRP was/VBD n't/RB Black/NNP Monday/NNP ./. 
But/CC while/IN the/DT New/NNP York/NNP Stock/NNP Exchange/NNP did/VBD n't/RB fall/VB apart/RB Friday/VB as/IN the/DT Dow/NNP Jones/NNP Industrial/NNP Average/JJ plunged/VBN 190.58/CD points/NNS --/: most/RBS of/IN it/PRP in/IN the/DT final/JJ hour/NN --/: it/PRP barely/RB managed/VBD *-2/-NONE- to/TO stay/VB this/DT side/NN of/IN chaos/NNS ./. 
Some/DT ``/`` circuit/NN breakers/NNS ''/'' installed/VBN */-NONE- after/IN the/DT October/NNP 1987/CD crash/NN failed/VBD their/PRP$ first/JJ test/NN ,/, traders/NNS say/VB 0/-NONE- *T*-1/-NONE- ,/, *-2/-NONE- unable/JJ *-3/-NONE- to/TO cool/VB the/DT selling/VBG panic/NN in/IN both/DT stocks/NNS and/CC futures/NNS ./. 

我需要计算标注准确度(Tag wise-Recall & Precision),因此需要在每个词-标签对的标注中找出错误(如果有的话)。

我正在考虑的方法是遍历这两个文本文件并将它们存储在一个列表中,然后逐个元素地比较“两个”列表。

这种方法对我来说似乎很粗糙,所以希望你们对上述问题提出一些更好的解决方案。

来自wikipedia 页面:

在分类任务中, 一个类的 precision 是 真阳性(即 正确标记为属于的物品 到正类)除以 标记为的元素总数 属于正类(即 真阳性和假阳性的总和 正面,这是不正确的项目 标记为属于该类)。 Recall 在这种情况下被定义为 真阳性数除以 由元素的总数 实际上属于正类 (即真阳性和 假阴性,这是哪些项目 未被标记为属于 正类,但应该是)。

【问题讨论】:

    标签: python shell nlp machine-learning text-processing


    【解决方案1】:

    请注意,由于每个单词都只有一个标签,因此总体召回率和准确率分数对于这项任务没有意义(它们都将等于准确度度量)。但是要求每个标签的召回率和精度度量是有意义的 - 例如,您可以找到 DT 标签的召回率和精度。

    一次对所有标签执行此操作的最有效方法与您建议的方法类似,但您可以通过跳过列表制作阶段来节省一次数据。读入每个文件的一行,逐字比较这两行,然后重复直到到达文件末尾。对于每个单词比较,您可能想要检查单词是否相等,而不是假设两个文件是同步的。对于每种类型的标签,您保留三个运行总计:真阳性、假阳性和假阴性。如果当前单词的两个标签匹配,则增加标签的真阳性总数。如果它们不匹配,您需要增加真实标签的误报总数和机器错误选择的标签的误报总数。最后,您可以按照维基百科摘录中的公式计算每个标签的召回率和准确率分数。

    我还没有测试过这段代码,我的 Python 有点生锈,但这应该会给你一些想法。我假设文件是​​打开的,totals 数据结构是一个字典字典:

    finished = false
    while not finished:
        trueLine = testFile.readline()
        if not trueLine: # end of file
            finished = true
        else:
            trueLine = trueLine.split() # tokenise by whitespace
            taggedLine = taggedFile.readline()
            if not taggedLine:
                print 'Error: files are out of sync.'
            taggedLine = taggedLine.split()
            if len(trueLine) != len(taggedLine):
                print 'Error: files are out of sync.'
            for i in range(len(trueLine)):
                truePair = trueLine[i].split('/')
                taggedPair = taggedLine[i].split('/')
                if truePair[0] != taggedPair[0]: # the words should match
                    print 'Error: files are out of sync.'
                trueTag = truePair[1]
                guessedTag = taggedPair[1]
                if trueTag == guessedTag:
                    totals[trueTag]['truePositives'] += 1
                else:
                    totals[trueTag]['falseNegatives'] += 1
                    totals[guessedTag]['falsePositives'] += 1
    

    【讨论】:

    • 谢谢,我已经实现了类似的东西,但忘记了进行完整性检查以查看文件是否同步。好提示!
    • 很好的答案!但是,我在一些论文中看到,他们将系统的召回率和精度作为一个数字,一个数字表示召回率,另一个数字表示精度。我想知道它们是如何计算的,拜托。谢谢。
    猜你喜欢
    • 2014-11-20
    • 2012-11-26
    • 2016-07-26
    • 1970-01-01
    • 2017-08-21
    • 2010-10-14
    • 2020-02-23
    • 2017-11-13
    • 2019-12-14
    相关资源
    最近更新 更多