我正在使用WordNet访问具有共同含义的同义词。这是一个示例:
from itertools import chain
from nltk.corpus import wordnet as wn
synsets = wn.synsets("drink")
# synsets = [Synset('drink.n.01'), Synset('drink.n.02'), Synset('beverage.n.01'), ...]
synonyms = set(chain(*(x.lemma_names() for x in synsets)))
# synonyms = {'drinking', 'drinkable', 'crapulence', 'toast', 'drink', 'drunkenness', ...}
同义词集排序了吗?而且,如果是的话,标准是什么?列表中的第一个同义词集与那些与给定单词相关的机会更高吗?
我想通过仅保留“最重要”的名称来限制同义词的数量(在此上下文中,“重要”的含义是要定义的,但我想知道WordNet是否具有自己的“重要”概念)。
如果未对同义词集进行排序,那么找到单词最合适的同义词的另一种方法是什么?
答案 0 :(得分:2)
文档中有一个相关部分:https://www.nltk.org/howto/wordnet.html#similarity
提供了各种相似性查找方法:path_similarity
,lch_similarity
,wup_similarity
,res_similarity
等
例如,从文档(对于path_similarity
为):
synset1.path_likeity(synset2):根据连接is-a(双音节/音韵符号)分类法中的两个最短路径返回分数,表示两个单词的意义相似。分数在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()方法。
同义词集排序了吗?而且,如果是的话,标准是什么?列表中的第一个同义词集与那些与给定单词相关的机会更高吗?
我不能果断地回答这个问题,但是我认为没有标准。您可以使用上述方法根据特定的同义词集查找最相似的单词。
编辑:如下面的评论所述,问题的作者正在wordnet的synsets()
方法返回的列表中寻找顺序。< / p>
从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
的nltk的POS_LIST
标记,然后取决于方法_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')]
>>>
希望更新后的答案会有所帮助!