NLTK Wordnet词组的同义词集

5

我正在使用Python NLTK Wordnet API。我试图找到代表一组单词的最佳synset。

如果我需要找到“学校和办公用品”这样的最佳synset,我不确定该怎么做。到目前为止,我已经尝试查找每个单词的synset,然后像这样计算最佳的最低通用上位词:

def find_best_synset(category_name):
    text = word_tokenize(category_name)
    tags = pos_tag(text)

    node_synsets = []
    for word, tag in tags:
        pos = get_wordnet_pos(tag)
        if not pos:
            continue
        node_synsets.append(wordnet.synsets(word, pos=pos))

    max_score = 0
    max_synset = None
    max_combination = None
    for combination in itertools.product(*node_synsets):
        for test in itertools.combinations(combination, 2):
            score = wordnet.path_similarity(test[0], test[1])
            if score > max_score:
                max_score = score
                max_combination = test
                max_synset = test[0].lowest_common_hypernyms(test[1])
    return max_synset

然而,这种方法并不是很有效,并且成本非常高。有没有办法找出最好地表示多个单词的同义词集?

感谢您的帮助!


如果你所有的表达都像那个例子一样,那么你可能不应该寻找一个共同的上义词。 "学校用品"是一种用品,但它们并不是某种学校。相反,你可以考虑最后一个单词的同义词集,并使用前面的单词进行消歧义(但我不确定如何做到这一点)。 - lenz
嗯,我明白你的观点,但我认为并不是所有的表达方式都像那个例子。我意识到“学校和办公室”是一种用品类型,但它们仍然被认为是名词而不是形容词。 - kevin.w.johnson
好的,如果表达式具有不同的内部结构,它不会简化您的任务。我建议您手动分配正确的同义词集在一个随机样本中(例如从20个开始),然后查看是否可以看到模式。或者手动执行更多实例并训练决策树。 - lenz
1个回答

4
除了我在评论中提到的内容之外,我认为你选择最佳上位词的方式可能存在缺陷。你得到的同义词集不是所有单词的最低通用上位词,而只是其中两个单词的最低通用上位词。
让我们以“学校和办公用品”为例。对于表达式中的每个单词,您都会得到一些同义词集。因此,变量node_synsets看起来会像以下示例:
[[school_1, school_2], [office_1, office_2, office_3], [supply_1]]

在这个例子中,有6种方法可以将每个synset与其他任何synset组合起来:
[(school_1, office_1, supply_1),
 (school_1, office_2, supply_1),
 (school_1, office_3, supply_1),
 (school_2, office_1, supply_1),
 (school_2, office_2, supply_1),
 (school_2, office_3, supply_1)]

这些三元组是您在外部的for循环(使用itertools.product)中迭代的内容。如果表达式有4个单词,您将迭代四元组,如果有5个单词,则为五元组,以此类推。

现在,通过内部的for循环,您将每个三元组配对。第一个三元组为:

[(school_1, office_1),
 (school_1, supply_1),
 (office_1, supply_1)]

你需要确定每对词语之间的最低上位词。例如,school_2office_1的最低上位词可能是某种机构。但这可能并不十分有意义,因为它没有考虑到任何最后一个单词的同义词集。
也许你应该尝试在每个同义词集的组合中找到所有三个词的最低公共上位词,并选择其中得分最高的一个。

我同意,我试图在后续迭代中实现这一点。我最终使用的解决方案是不将它们缩减为单个超义词,而是使用所有生成的同义词集来获得最佳分数。基本上返回“node_synsets”并使用它。如果我确实想要找到所有三个的LCH ... 我会在其中两个之间找到它,然后在第三个中使用它进行LCH计算吗? - kevin.w.johnson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接