NLTK中动态创建的语法

2024-04-23 21:36:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在做一个使用NLTK的项目,在语法生成方面遇到了一个问题。我已经看了一些其他的问题,但我没有看到任何问题与我的一致。在

我已经研究过使用NLTK的CFG和{}分别与一个或一个ViterbiParser结合使用,但是我希望能够向函数发送一个原始字符串并返回其标记。我也尝试过使用nltk.pos_tag(nltk.word_tokenize(str)),希望我可以从训练数据中手动生成语法树,这让我很接近,但在给定字符串My dog also likes eating sausage.时失败了:

>>> nltk.pos_tag(nltk.word_tokenize("My dog also likes eating sausage."))
[('My', 'PRP$'), ('dog', 'NN'), ('also', 'RB'), ('likes', 'VBZ'), 
('eating', 'JJ'), ('sausage', 'NN'), ('.', '.')]

单词eating被标记为形容词,而不是动词VBG。在

有没有语法字符串/对象/模块可以使用而不必硬编码语法字符串NLTK?如果没有,NLTK中是否有一种方法可以在不手动的情况下生成经过训练的语法?如果不需要的话,我不想重新发明轮子。在


Tags: 字符串标记posmytag语法wordalso
1条回答
网友
1楼 · 发布于 2024-04-23 21:36:07

我发现了一个潜在的解决问题的方法,在研究了SND的评论后发现了一个兔子洞。除了默认的那个,我不知道标记符。最后我做的是用一系列标记器训练默认的标记器和一个内置的语料库(稍后我将尝试不同的语料库)。为了便于以后移植,它被包装到一个类中,并使用pickle保存:

import nltk
from nltk.corpus import *
from pickle import dump, load

CUTOFF = 2


class MyTagger:

    def __init__(self, path: str=None):
        self.isTrained = False
        self.path = path
        if path:
            try:
                with open(path, 'rb') as src:
                    self.tagger = load(src)
            except Exception:  # Broad Exception intentional; code not complete
                print("Pickle dump could not be loaded at path: ", path)
                pass

    def train(self, corpus) -> float:
        sents = corpus.tagged_sents(corpus.fileids())
        training_data = sents[int(len(sents) * 0.9):]
        testing_data = sents[:int(len(sents) * 0.1)]
        t0 = nltk.DefaultTagger('NN')
        t1 = nltk.UnigramTagger(training_data, cutoff=CUTOFF, backoff=t0)
        t2 = nltk.BigramTagger(training_data, cutoff=CUTOFF, backoff=t1)
        t3 = nltk.TrigramTagger(training_data, cutoff=CUTOFF, backoff=t2)
        self.tagger = t3
        if self.path:
            self.save(self.path)
        return self.evaluate(testing_data)

    def evaluate(self, corpus: list) -> float:
        return self.tagger.evaluate(corpus)

    def tag(self, text) -> list:
        if not self.tagger:
            raise Exception("")
        else:
            if isinstance(text, str):
                return self.tagger.tag(text.split())
            elif isinstance(text, list) and isinstance(text[0], str):
                return self.tagger.tag(text)

    def save(self, path):
        with open(path, 'wb') as out:
            dump(self.tagger, out, -1)

用法如下:

^{pr2}$

相关问题 更多 >