【问题标题】:General synonym and part of speech processing using nltk使用 nltk 处理一般同义词和词性
【发布时间】:2012-06-15 20:36:46
【问题描述】:

我正在尝试为句子中重要的单词(即不是“a”或“the”)创建一个通用同义词标识符,并且我正在使用 python 中的自然语言工具包(nltk)。我遇到的问题是 nltk 中的同义词查找器需要词性参数才能链接到它的同义词。我尝试的解决方法是使用 nltk 中存在的简化词性标注器,然后减少第一个字母以便将此参数传递给同义词查找器,但这不起作用。

def synonyms(Sentence):
    Keywords = []
    Equivalence = WordNetLemmatizer()
    Stemmer = stem.SnowballStemmer('english')
    for word in Sentence:
        word = Equivalence.lemmatize(word)
    words = nltk.word_tokenize(Sentence.lower())
    text = nltk.Text(words)
    tags = nltk.pos_tag(text)
    simplified_tags = [(word, simplify_wsj_tag(tag)) for word, tag in tags]
    for tag in simplified_tags:
        print tag
        grammar_letter = tag[1][0].lower()
        if grammar_letter != 'd':
            Call = tag[0].strip() + "." + grammar_letter.strip() + ".01"
            print Call
            Word_Set = wordnet.synset(Call)
            paths = Word_Set.lemma_names
            for path in paths:
                Keywords.append(Stemmer.stem(path))
    return Keywords

这是我目前正在使用的代码,如您所见,我首先对输入进行词形还原,以减少从长远来看我将拥有的匹配数(我计划在数万个句子上运行它) ,从理论上讲,我会在此之后对单词进行词干以进一步提高这种效果并减少我生成的冗余单词的数量,但是这种方法几乎总是以下面的形式返回错误:

Traceback (most recent call last):
  File "C:\Python27\test.py", line 45, in <module>
    synonyms('spray reddish attack force')
  File "C:\Python27\test.py", line 39, in synonyms
    Word_Set = wordnet.synset(Call)
  File "C:\Python27\lib\site-packages\nltk\corpus\reader\wordnet.py", line 1016, in synset
    raise WordNetError(message % (lemma, pos))
WordNetError: no lemma 'reddish' with part of speech 'n'

我对将要运行的数据没有太多控制权,因此简单地清理我的语料库并不是一个真正的选择。关于如何解决这个问题的任何想法?

我做了更多的研究,我有一个很有希望的领先优势,但我仍然不确定如何实施它。在未找到或错误分配的单词的情况下,我想使用相似度度量(Leacock Chodorow、Wu-Palmer 等)将该单词链接到最接近正确分类的其他关键字。也许与编辑距离测量相结合,但我仍然无法找到任何关于此的文档。

【问题讨论】:

    标签: python machine-learning nlp nltk wordnet


    【解决方案1】:

    显然,nltk 允许检索与单词相关的所有同义词。当然,通常有许多反映不同的词义。为了在功能上找到同义词(或者如果两个词是同义词),您必须尝试尽可能匹配最接近的同义词集,这可以通过上述任何相似性度量来实现。为此,我编写了一些基本代码,如下所示,如何查找两个单词是否为同义词:

    from nltk.corpus import wordnet
    from nltk.stem.wordnet import WordNetLemmatizer
    import itertools
    
    
    def Synonym_Checker(word1, word2):
        """Checks if word1 and word2 and synonyms. Returns True if they are, otherwise False"""
        equivalence = WordNetLemmatizer()
        word1 = equivalence.lemmatize(word1)
        word2 = equivalence.lemmatize(word2)
    
        word1_synonyms = wordnet.synsets(word1)
        word2_synonyms = wordnet.synsets(word2)
    
        scores = [i.wup_similarity(j) for i, j in list(itertools.product(word1_synonyms, word2_synonyms))]
        max_index = scores.index(max(scores))
        best_match = (max_index/len(word1_synonyms), max_index % len(word1_synonyms)-1)
    
        word1_set = word1_synonyms[best_match[0]].lemma_names
        word2_set = word2_synonyms[best_match[1]].lemma_names
        match = False
        match = [match or word in word2_set for word in word1_set][0]
    
        return match
    
    print Synonym_Checker("tomato", "Lycopersicon_esculentum")
    

    我可能会尝试逐步实现更强大的词干提取算法,但在我最初做的几个测试中,这段代码实际上适用于我能找到的每个单词。如果有人对如何改进此算法有任何想法,或者有任何可以改进此答案的方法,我很乐意听到。

    【讨论】:

    • 我一直试图让这段代码工作一段时间,但它似乎充满了错误。一方面,“worndet”不是 NLTK 的一部分,而且包的组织也发生了一些变化。
    • 抱歉,此代码已有 11 个月的历史。是的,nltk 发生了一些变化,发布了新版本的 nltk 的更改和工作版本来代替旧版本。
    • 另外值得注意的是 wordnet 查找实际上很慢,理论上应该委托给子进程。如果您想进一步清理它并使其成为更好的实用程序,请告诉我,我可以在 Github 上为此打开一个要点并将您复制到上面。
    • 作为对我的编程改进的有用反思,从那时起我重写了一堆它变得更快,更pythonic,然后我也让它符合pep8。要点也在这里:gist.github.com/Slater-Victoroff/5713821
    【解决方案2】:

    你能用try: 包裹你的Word_Set = wordnet.synset(Call) 并忽略WordNetError 异常吗?看起来您遇到的错误是某些单词没有正确分类,但是对于无法识别的单词也会发生此异常,因此捕获异常对我来说似乎是个好主意。

    【讨论】:

    • 补充一点:WordNet 没有所有可能的单词或所有可能的同义词集,所以你不能假设它总是会返回结果。
    • WordNet 可能没有每个单词,但是从单词到同义词的转换率非常低,即使是在 lemmitization 之后(小于 50%)。我已经尝试过,但存在比 WordNet 的限制更深的问题。此外,我正在寻找的词都不是不寻常或不常见的。
    • 您确定这些词被识别为正确的词性吗? Reddish 是 Adj 而不是 N,还是我误解了异常消息?
    • 这是其中的一部分,能够解决这个问题将是这个问题的一个很好的开始。你知道这怎么可能吗?
    • 你知道reddish是否在数据库中吗?可能是它说未知词必须是名词,但我猜......
    猜你喜欢
    • 1970-01-01
    • 2018-08-30
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 2012-05-27
    • 1970-01-01
    • 1970-01-01
    • 2015-06-11
    相关资源
    最近更新 更多