给定一个输入单词,我想确定它是否是名词(如果有歧义,例如
cook
可以是名词或动词,则必须将该单词识别为名词)。
实际上,我使用斯坦福解析器中的 POS 标记器(我给它一个单词作为输入,然后从结果中仅提取 POS 标记)。结果很好,但是需要很长时间。
有没有办法(用Python,请:)比我实际做的更快地执行这个任务?
如果您只是想检查单个单词是否可以用作名词,最快的方法可能是构建所有名词的集合,然后只需检查该单词是否属于该集合。
要获取所有名词的列表,您可以使用 WordNet 语料库(例如可以通过 NLTK 访问):
>>> from nltk.corpus import wordnet as wn
>>> nouns = {x.name().split('.', 1)[0] for x in wn.all_synsets('n')}
>>> "cook" in nouns
True
>>> "and" in nouns
False
我不能代表Python包装器,但如果你使用Stanford
POS tagger
而不是解析器,它应该会快得多。有 Stanford CoreNLP
的包装器,其中包括标记器:https://pypi.python.org/pypi/corenlp-python;或者,看起来 nltk
也有一个斯坦福标记器模块 http://www.nltk.org/_modules/nltk/tag/stanford.html 。
如果将单个单词嵌入到玩具句子中,您也可能会获得更好的结果。类似“X 是一个东西”之类的东西。根据句子的不同,这也可能会让您偏向或不将单词猜测为名词。
如果您要检查单个单词,我会支持使用 Wordnet。我还使用了免费提供的 TreeTagger: http://www.cis.uni-muenchen.de/~schmid/tools/TreeTagger/ 该二进制文件运行速度非常快并且支持多种语言。 如果您需要纯 Pythonic 解决方案,请检查 Brill Tagger 的 NLTK 实现:http://www.nltk.org/_modules/nltk/tag/brill.html
要从 wordnet 获得更详细的名词列表,您可以这样做:
from nltk.corpus import wordnet as wn
import re
possible_nouns = [word for synset in wn.all_synsets('n') for word in synset.lemma_names()]
all_nouns = []
for eachNoun in possible_nouns:
eachNoun = re.sub("""_"""," ", eachNoun)
all_nouns.append(eachNoun.lower())
all_nouns = list(set(all_nouns)) #some different synsets of the same word are filtered
len(all_nouns) # should be roughly 117798