5

我正在尝试使用 python nltk 的 wordnet 来查找两个单词之间的相似性。两个示例关键字是“游戏”和“莱昂纳多”。首先,我提取了这两个词的所有同义词集并交叉匹配每个同义词集以找到它们的相似性。这是我的代码

from nltk.corpus import wordnet as wn

xx = wn.synsets("game")
yy = wn.synsets("leonardo")
for x in xx:
    for y in yy:
        print x.name
        print x.definition
        print y.name
        print y.definition
        print x.wup_similarity(y)
        print '\n'

这是总输出:

game.n.01 用规则确定获胜者的竞赛 leonardo.n.01 意大利画家、雕塑家、工程师、科学家和建筑师;意大利文艺复兴时期最多才多艺的天才 (1452-1519) 0.285714285714

game.n.02 一项运动或其他比赛的单场比赛 leonardo.n.01 意大利画家、雕塑家、工程师、科学家和建筑师;意大利文艺复兴时期最多才多艺的天才 (1452-1519) 0.285714285714

game.n.03 娱乐或消遣 leonardo.n.01 意大利画家、雕塑家、工程师、科学家和建筑师;意大利文艺复兴时期最多才多艺的天才(1452-1519)0.25

game.n.04 为食物或运动而猎杀的动物 leonardo.n.01 意大利画家、雕塑家、工程师、科学家和建筑师;意大利文艺复兴时期最多才多艺的天才 (1452-1519) 0.923076923077

game.n.05(网球)比赛的一个部门,其中一名球员为 leonardo.n.01 意大利画家、雕塑家、工程师、科学家和建筑师服务;意大利文艺复兴时期最多才多艺的天才(1452-1519)0.222222222222

game.n.06(比赛)特定点的得分或获胜所需的得分 leonardo.n.01 意大利画家、雕塑家、工程师、科学家和建筑师;意大利文艺复兴时期最多才多艺的天才 (1452-1519) 0.285714285714

game.n.07 用于食用的野生动物的肉 leonardo.n.01 意大利画家、雕塑家、工程师、科学家和建筑师;意大利文艺复兴时期最多才多艺的天才(1452-1519)0.5

plot.n.01 做某事的秘密计划(尤其是秘密或非法的) leonardo.n.01 意大利画家、雕塑家、工程师、科学家和建筑师;意大利文艺复兴时期最多才多艺的天才(1452-1519)0.2

game.n.09 玩特定游戏所需的游戏设备 leonardo.n.01 意大利画家、雕塑家、工程师、科学家和建筑师;意大利文艺复兴时期最多才多艺的天才 (1452-1519) 0.666666666667

game.n.10 你的职业或工作 leonardo.n.01 意大利画家、雕塑家、工程师、科学家和建筑师;意大利文艺复兴时期最多才多艺的天才(1452-1519)0.25

game.n.11 轻浮或琐碎的行为 leonardo.n.01 意大利画家、雕塑家、工程师、科学家和建筑师;意大利文艺复兴时期最多才多艺的天才(1452-1519)0.222222222222

bet_on.v.01 押注 leonardo.n.01 意大利画家、雕塑家、工程师、科学家和建筑师;意大利文艺复兴时期最多才多艺的天才(1452-1519)-1

crippled.s.01 脚或腿残疾 leonardo.n.01 意大利画家、雕塑家、工程师、科学家和建筑师;意大利文艺复兴时期最多才多艺的天才(1452-1519)-1

game.s.02 愿意面对危险 leonardo.n.01 意大利画家、雕塑家、工程师、科学家和建筑师;意大利文艺复兴时期最多才多艺的天才(1452-1519)-1

但是 game.n.04 和 leonardo.n.01 之间的相似之处真的很奇怪。我认为相似度(0.923076923077)不应该那么高。

游戏.n.04

为食物或运动而猎杀的动物

莱昂纳多.n.01

意大利画家、雕塑家、工程师、科学家和建筑师;意大利文艺复兴时期最多才多艺的天才(1452-1519)

0.923076923077

我的概念有问题吗?

4

1 回答 1

8

根据文档,该wup_similarity()方法返回...

...一个分数,表示两个词义的相似程度,基于分类法中两种意义的深度及其最不常见的子类(最具体的祖先节点)的深度。

...和...

>>> from nltk.corpus import wordnet as wn
>>> game = wn.synset('game.n.04')
>>> leonardo = wn.synset('leonardo.n.01')
>>> game.lowest_common_hypernyms(leonardo)
[Synset('organism.n.01')]
>>> organism = game.lowest_common_hypernyms(leonardo)[0]
>>> game.shortest_path_distance(organism)
2
>>> leonardo.shortest_path_distance(organism)
3

...这就是为什么它认为它们相似,尽管我得到...

>>> game.wup_similarity(leonardo)
0.7058823529411765

...由于某种原因有所不同。


更新

我想要一些测量来表明差异('game','chess')远小于差异('game','leonardo')

像这样的东西怎么样...

from nltk.corpus import wordnet as wn
from itertools import product

def compare(word1, word2):
    ss1 = wn.synsets(word1)
    ss2 = wn.synsets(word2)
    return max(s1.path_similarity(s2) for (s1, s2) in product(ss1, ss2))

for word1, word2 in (('game', 'leonardo'), ('game', 'chess')):
    print "Path similarity of %-10s and %-10s is %.2f" % (word1,
                                                          word2,
                                                          compare(word1, word2))

...打印...

Path similarity of game       and leonardo   is 0.17
Path similarity of game       and chess      is 0.25
于 2013-06-25T12:29:25.263 回答