7

我正在使用Stanford POS Tagger执行 POS 标记。标注器只返回输入句子的一种可能的标注。例如,当提供输入句子“The clown weeps.”时,POS 标注器产生(错误的)“The_DT clown_NN weeps_NNS ._.”。

但是,我的应用程序将尝试解析结果,并且可能会拒绝 POS 标记,因为无法解析它。因此,在此示例中,它将拒绝“The_DT clown_NN weeps_NNS ._”。但会接受“The_DT 小丑_NN weeps_VBZ ._。” 我认为这是解析器的低置信度标记。

因此,我希望 POS 标注器为每个单词的标注提供多个假设,并用某种置信度值进行注释。通过这种方式,我的应用程序可以选择具有最高可信度的 POS 标记,以实现其目的的有效解析。

我没有办法让斯坦福词性标注器为每个单词(甚至整个句子)生成多个(n-best)标注假设。有没有办法做到这一点?(或者,我也可以使用另一个具有可比性能的 POS 标记器来支持这一点。)

4

3 回答 3

3

OpenNLP允许获得最佳的 POS 标记:

一些应用程序需要检索 n-best pos 标签序列,而不仅仅是最佳序列。topKSequences 方法能够返回顶部序列。它可以以与标签类似的方式调用。

Sequence topSequences[] = tagger.topKSequences(sent);

每个 Sequence 对象包含一个序列。可以通过 Sequence.getOutcomes() 检索序列,它返回一个标签数组,Sequence.getProbs() 返回这个序列的概率数组。

此外,还有一种方法可以让 spaCy 做这样的事情:

Doc.set_extension('tag_scores', default=None)
Token.set_extension('tag_scores', getter=lambda token: token.doc._.tag_scores[token.i])

class ProbabilityTagger(Tagger):
    def predict(self, docs):
        tokvecs = self.model.tok2vec(docs)
        scores = self.model.softmax(tokvecs)
        guesses = []
        for i, doc_scores in enumerate(scores):
            docs[i]._.tag_scores = doc_scores
            doc_guesses = doc_scores.argmax(axis=1)

            if not isinstance(doc_guesses, numpy.ndarray):
                doc_guesses = doc_guesses.get()
            guesses.append(doc_guesses)
        return guesses, tokvecs


Language.factories['tagger'] = lambda nlp, **cfg: ProbabilityTagger(nlp.vocab, **cfg)

然后每个标记将具有 tag_scores 以及 spaCy 的标签映射中每个词性的概率。

来源:https ://github.com/explosion/spaCy/issues/2087

于 2020-03-21T20:12:40.303 回答
0

我不知道一个为英语短语提供多种 POS 解释的标记器(这是针对西班牙语的)您的其他选择可能是更改或组合标记器,我的意思是,在Freeling中使用您自己的示例我得到了您的预期结果

在此处输入图像描述

此外,您还可以看到 Freeling 在其上下文中向您展示了某些单词的其他可能的 POS 解释。

注意:也许如果您使用过 Freeling,您可能知道为了机器可读性,您可以使用 xml 输出(在结果下方),而对于自动化,您可以将 Freeling 与 python/java 集成,但通常我更喜欢通过命令行调用它。

于 2018-03-17T15:34:23.230 回答
-1

我们发现 POS 标记的默认模型不够好。事实证明,使用不同的模型更好的标签。我们目前使用的是 wsj-0-18-bidirectional-distim,性能足以应付大多数任务。我像这样包括它:

props.put("pos.model",
    "edu/stanford/nlp/models/pos-tagger/wsj-bidirectional/wsj-0-18-bidirectional-distsim.tagger");
props.put("annotators", "tokenize, ssplit, pos, ...");
pipeline = new StanfordCoreNLP(props);
于 2013-11-21T17:07:31.193 回答