3

这是我的要求。我想以允许我实现以下内容的方式标记和标记段落。

  • 应该在段落中识别日期和时间并将它们标记为日期和时间
  • 应该识别段落中的已知短语并将它们标记为 CUSTOM
  • 其余内容应该被标记化应该被默认的nltk的word_tokenize和pos_tag函数标记化?

例如,下面的句子

"They all like to go there on 5th November 2010, but I am not interested."

如果自定义短语是“我不感兴趣”,则应按如下方式标记和标记。

[('They', 'PRP'), ('all', 'VBP'), ('like', 'IN'), ('to', 'TO'), ('go', 'VB'), 
('there', 'RB'), ('on', 'IN'), ('5th November 2010', 'DATE'), (',', ','), 
('but', 'CC'), ('I am not interested', 'CUSTOM'), ('.', '.')]

任何建议都会很有用。

4

2 回答 2

7

正确的答案是编译一个以您想要的方式标记的大型数据集,然后在其上训练一个机器学习的分块器。如果这太耗时,那么简单的方法是运行 POS 标记器并使用正则表达式对其输出进行后处理。获得最长的匹配是这里的难点:

s = "They all like to go there on 5th November 2010, but I am not interested."

DATE = re.compile(r'^[1-9][0-9]?(th|st|rd)? (January|...)( [12][0-9][0-9][0-9])?$')

def custom_tagger(sentence):
    tagged = pos_tag(word_tokenize(sentence))
    phrase = []
    date_found = False

    i = 0
    while i < len(tagged):
        (w,t) = tagged[i]
        phrase.append(w)
        in_date = DATE.match(' '.join(phrase))
        date_found |= bool(in_date)
        if date_found and not in_date:          # end of date found
            yield (' '.join(phrase[:-1]), 'DATE')
            phrase = []
            date_found = False
        elif date_found and i == len(tagged)-1:    # end of date found
            yield (' '.join(phrase), 'DATE')
            return
        else:
            i += 1
            if not in_date:
                yield (w,t)
                phrase = []

待办事项:扩展DATEre,插入代码以搜索CUSTOM短语,通过匹配 POS 标签和标记使其更加复杂,并5th自行决定是否应计为日期。(可能不是,因此过滤掉仅包含序数的长度为 1 的日期。)

于 2010-10-14T13:33:53.627 回答
2

您可能应该使用 nltk.RegexpParser 进行分块以实现您的目标。

参考: http: //nltk.googlecode.com/svn/trunk/doc/book/ch07.html#code-chunker1

于 2010-10-14T20:39:11.067 回答