使用Python NLTK计算单词相似度遇问题:部分结果返回None
wup_similarity比较location和located的Synset时返回None? 嘿,我来帮你理清这个问题——你看到的None其实是因为你在**跨词性(名词<->动词)**比较WordNet的Synset,这刚好踩中了WUP(Wu-Palmer)相似度算法的核心限制!
问题根源
WordNet里的每个Synset都属于特定的词性(比如n代表名词,v代表动词),而且不同词性的Synset属于完全独立的语义层级树。WUP相似度的计算逻辑是找两个Synset在语义树中的共同上位词(hypernym),然后基于它们到共同上位词的路径长度来计算相似性。
但你看你的例子:
'location'的Synset都是名词(比如Synset('location.n.01'))'located'的Synset都是动词(比如Synset('locate.v.01'))
名词和动词的语义树根本没有交集,算法找不到任何共同的上位节点,自然就返回None表示无法计算有效相似度。
解决办法
要得到有效的相似度数值,你需要确保比较的是相同词性的Synset,这里有两种可行的思路:
1. 筛选同词性的Synset进行比较
比如你可以直接指定词性来获取Synset,或者用对应的同词性词形来对比。举个例子,把location换成它的动词形式locate来和located的动词Synset比较:
from itertools import product from nltk.corpus import wordnet # 获取'locate'的动词Synset syns_verb1 = wordnet.synsets('locate', pos=wordnet.VERB) # 获取'located'的动词Synset syns_verb2 = wordnet.synsets('located', pos=wordnet.VERB) for s1, s2 in product(syns_verb1, syns_verb2): print(f"{s1} -- {s2}:") print(s1.wup_similarity(s2))
运行这段代码你会看到,同词性的Synset比较会返回正常的相似度数值——比如Synset('locate.v.01')和Synset('locate.v.01')的相似度是1.0,和Synset('situate.v.01')的相似度会接近1.0(因为它们是近义动词)。
2. 跨词性比较的替代方案
如果确实需要跨词性比较单词相似度,WordNet的WUP算法就不太适用了。你可以考虑用基于词向量的方法(比如Word2Vec、GloVe),这类方法会把单词转换成向量,通过计算向量之间的余弦相似度来衡量跨词性的语义相似性——不过这就需要额外的词向量模型支持,不属于WordNet的范畴了。
总结
简单来说:跨词性的Synset在WordNet里没有共同的语义层级路径,所以WUP算法无法计算相似度,返回None。只要确保对比的是相同词性的Synset,就能得到你想要的结果啦!
内容的提问来源于stack exchange,提问作者Yann Droy




