检查两个单词是否相互关联

Anu*_*rma 4 python nlp nltk python-2.7

我有两个清单:一,用户的利益; 第二,关于一本书的关键词.我想根据他给定的兴趣列表向用户推荐这本书.我使用的是SequenceMatcher类Python库的difflib匹配像"游戏","游戏","游戏","玩家"等类似的词语的ratio功能给我之间的数[0,1],说明了2串如何相似.但我陷入了一个例子,我计算了"循环"和"射击"之间的相似性.它出来了0.6667.

for interest in self.interests:
    for keyword in keywords:
       s = SequenceMatcher(None,interest,keyword)
       match_freq = s.ratio()
       if match_freq >= self.limit:
            #print interest, keyword, match_freq
            final_score += 1
            break 
Run Code Online (Sandbox Code Playgroud)

有没有其他方法可以在Python中执行这种匹配?

alv*_*vas 10

首先,一个词可以有很多感官,当你试图找到相似的词时,你可能需要一些词义消除歧义http://en.wikipedia.org/wiki/Word-sense_disambiguation.

给出一对单词,如果我们采用最相似的一对意义来判断两个单词是否相似,我们可以尝试这样做:

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

wordx, wordy = "cat","dog"
sem1, sem2 = wn.synsets(wordx), wn.synsets(wordy)

maxscore = 0
for i,j in list(product(*[sem1,sem2])):
  score = i.wup_similarity(j) # Wu-Palmer Similarity
  maxscore = score if maxscore < score else maxscore
Run Code Online (Sandbox Code Playgroud)

您可以使用其他相似性功能.http://nltk.googlecode.com/svn/trunk/doc/howto/wordnet.html.唯一的问题是当你遇到不在wordnet中的单词时.然后我建议你回避difflib.

  • 你的产品电话中有'*[...]`的原因吗?看起来你可以把它留下来得到相同的效果(iterables`sem1`和`sem2`的产品)只有`product(sem1,sem2)`.我错过了什么吗? (2认同)

eyq*_*uem 5

起初,我想到用正则表达式执行额外的测试来区分低比率的匹配。它可以是处理特定问题的解决方案,例如以ing结尾的单词发生的问题。但这只是有限的情况,可能还有许多其他情况,需要针对每种情况添加特定的治疗方法。

然后我认为我们可以尝试找到额外的标准来消除语义上不匹配的单词,这些单词的字母相似度足以被检测为匹配在一起,尽管比率很低,
同时捕获具有低比率的真正语义匹配术语,因为它们很短。

这是一种可能性

from difflib import SequenceMatcher

interests = ('shooting','gaming','looping')
keywords = ('loop','looping','game')

s = SequenceMatcher(None)

limit = 0.50

for interest in interests:
    s.set_seq2(interest)
    for keyword in keywords:
        s.set_seq1(keyword)
        b = s.ratio()>=limit and len(s.get_matching_blocks())==2
        print '%10s %-10s  %f  %s' % (interest, keyword,
                                      s.ratio(),
                                      '** MATCH **' if b else '')
    print
Run Code Online (Sandbox Code Playgroud)

给出

  shooting loop        0.333333  
  shooting looping     0.666667  
  shooting game        0.166667  

    gaming loop        0.000000  
    gaming looping     0.461538  
    gaming game        0.600000  ** MATCH **

   looping loop        0.727273  ** MATCH **
   looping looping     1.000000  ** MATCH **
   looping game        0.181818  
Run Code Online (Sandbox Code Playgroud)

请注意文档中的这一点:

SequenceMatcher 计算并缓存有关第二个序列的详细信息,因此,如果您想要将一个序列与多个序列进行比较,请使用 set_seq2() 设置常用序列一次,然后重复调用 set_seq1(),对每个其他序列调用一次。

  • 考虑“词干”是一个好主意。感谢分享。 (2认同)