文档有一个相关部分:https://www.nltk.org/howto/wordnet.html#similarity
提供多种相似度查找方法:path_similarity、lch_similarity、wup_similarity、res_similarity等
例如,来自文档(for path_similarity):
synset1.path_similarity(synset2):根据连接 is-a(hypernym/hypnoym)分类法中的意义的最短路径,返回一个分数,表示两个词义的相似程度。分数在 0 到 1 的范围内。
您可以使用以下格式的方法:
# Assuming we are comparing with 0th synset of "drink"
syn_to_compare = wn.synsets("drink")[0]
all_synsets = wn.synsets("drink")
corr = [(all_synsets[i],syn_to_compare.path_similarity(all_synsets[i])) for i in range(len(all_synsets))]
将生成如下输出:
[(Synset('drink.n.01'), 1.0), (Synset('drink.n.02'), 0.06666666666666667), (Synset('beverage.n.01'), 0.08333333333333333), (Synset('drink.n.04'), 0.09090909090909091), (Synset('swallow.n.02'), 0.07692307692307693), (Synset('drink.v.01'), None), (Synset('drink.v.02'), None), (Synset('toast.v.02'), None), (Synset('drink_in.v.01'), None), (Synset('drink.v.05'), None)]
然后,您可以使用 sorted() 方法对它们进行排序,提供相似度分数作为值。
sorted(corr, key=lambda x: x[1] if x[1] != None else 0, reverse=True)
[(Synset('drink.n.01'), 1.0), (Synset('drink.n.04'), 0.09090909090909091), (Synset('beverage.n.01'), 0.08333333333333333), (Synset('swallow.n.02'), 0.07692307692307693), (Synset('drink.n.02'), 0.06666666666666667), (Synset('drink.v.01'), None), (Synset('drink.v.02'), None), (Synset('toast.v.02'), None), (Synset('drink_in.v.01'), None), (Synset('drink.v.05'), None)]
如果你想处理专有名词,我建议研究一下gensim的most_similar()方法。
同义词是否已排序?而且,如果是的话,标准是什么?列表中的第一个同义词是那些与给定单词相关的机会更高的同义词吗?
我无法果断地回答这个问题,但我认为没有标准。您可以使用上述方法根据特定的同义词找到最相似的单词。
编辑:正如下面的 cmets 所述,问题的作者正在寻找 wordnet 的 synsets() 方法返回的列表中的顺序。
来自 Github 上的代码:https://github.com/nltk/nltk/blob/develop/nltk/corpus/reader/wordnet.py#L1563 用于方法 synset()
if lang == "eng":
get_synset = self.synset_from_pos_and_offset
index = self._lemma_pos_offset_map
if pos is None:
pos = POS_LIST
return [
get_synset(p, offset)
for p in pos
for form in self._morphy(lemma, p, check_exceptions)
for offset in index[form].get(p, [])
]
其中POS_LIST 的值为:POS_LIST = [NOUN, VERB, ADJ, ADV]。
因此,优先考虑上述顺序。此外,根据他们的代码:NOUN="n", VERB="v", ADJ="a", ADV="r"
所以顺序主要取决于基于POS_LIST的nltk的pos标签,其次是_morphy()方法返回的lemma和pos标签,然后是_lemma_pos_offset_map()返回的内容。
例如:
>>> POS_LIST = ["n", "v", "a", "r"]
>>> syn = list()
>>> lemma = "drink"
>>> for p in POS_LIST:
... for form in wn._morphy(lemma, p, True):
... for offset in wn._lemma_pos_offset_map[form].get(p, []):
... syn.append(wn.synset_from_pos_and_offset(p, offset))
...
>>> syn
[Synset('drink.n.01'), Synset('drink.n.02'), Synset('beverage.n.01'), Synset('drink.n.04'), Synset('swallow.n.02'), Synset('drink.v.01'), Synset('drink.v.02'), Synset('toast.v.02'), Synset('drink_in.v.01'), Synset('drink.v.05')]
>>> # You can verify it with what synsets() is providing
...
KeyboardInterrupt
>>> wn.synsets("drink")
[Synset('drink.n.01'), Synset('drink.n.02'), Synset('beverage.n.01'), Synset('drink.n.04'), Synset('swallow.n.02'), Synset('drink.v.01'), Synset('drink.v.02'), Synset('toast.v.02'), Synset('drink_in.v.01'), Synset('drink.v.05')]
>>>
希望更新后的答案有帮助!