2

我现在正在玩 nltk。我正在尝试使用 nltk 创建各种分类器,进行命名实体识别,以比较它们的结果。创建 n-gram 标记器很容易,但是我在为朴素贝叶斯或决策树分类器创建 ClassifierBasedTagger 时遇到了一些问题。

我的数据采用 conll iob 格式。读完后,我将它转换成一个看起来像这样的元组:(word, POS-tag), entity)

我创建了以下创建分类器的类:

class ClassifierChunker(ChunkParserI):

def __init__(self, trainSents, tagger,  **kwargs):
    if type(tagger) is not nltk.tag.sequential.UnigramTagger and  type(tagger) is not nltk.tag.sequential.BigramTagger and type(tagger) is not nltk.tag.sequential.TrigramTagger:
        self.featureDetector = tagger.feature_detector
    self.tagger = tagger

def parse(self, sentence):
    chunks = self.tagger.tag(sentence)
    iobTriblets = [(word, pos, entity) for ((word, pos), entity) in chunks]
    return conlltags2tree(iobTriblets)

def evaluate2(self, testSents):
    return self.evaluate([conlltags2tree([(word, pos, entity) for (word, pos), entity in iobs]) for iobs in testSents])

我就是这样称呼它的:

 #naiveBayers
naiveBayers =  NaiveBayesClassifier.train
naiveBayersTagger = ClassifierBasedTagger(train=completeTaggedSentencesTrain, feature_detector=features, classifier_builder=naiveBayers)
nerChunkerNaiveBayers = ClassifierChunker(completeTaggedSentencesTrain, naiveBayersTagger)
evalNaiveBayers = nerChunkerNaiveBayers.evaluate2(completeTaggedSentencesTest)
print(evalNaiveBayers)

我遇到的问题出在第一行代码中(naiveBayers = NaiveBayesClassifier.train) 我知道我应该将训练函数传递给标记的特征集。但是,我不确定这意味着什么。在文档中它说以下内容:

:param tags_featuresets:分类特征集列表,即元组列表(featureset, label)

特征集是单词,标签是实体吗?

遇到这个问题后,我做了一些研究并找到了nltk-trainer。在args.py文件中创建了分类器构建器,更具体地说,在函数“make_classifier_builder”的内部类“trainf”中创建。但是我不知道变量“train_feats”是从哪里来的。可能和我对内在功能的理解有限有关。我找不到它在任何地方被调用。

如果有人能指出我正确的方向,我会非常感激。

编辑:我刚刚在NLTK 3 Cookbook中读到 feature_detector 函数返回一个功能集(第 143 页)。那么我应该以某种方式使用该功能吗?

我当前的功能 Detector 看起来如下,并从那本书中取出:

def prev_next_pos_iob(tokens, index, history):
    word, pos = tokens[index]

    if index == 0:
        prevword, prevpos, previob = ('<START>',) * 3
    else:
        prevword, prevpos = tokens[index - 1]
        previob = history[index - 1]

    if index == len(tokens) - 1:
        nextword, nextpos = ('<END>',) * 2
    else:
        nextword, nextpos = tokens[index + 1]

    feats = {
        'word': word,
        'pos': pos,
        'nextword': nextword,
        'nextpos': nextpos,
        'prevword': prevword,
        'prevpos': prevpos,
        'previob': previob
    }
    return feats
4

0 回答 0