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

Python 检查两个单词是否相互关联,python,python-2.7,nlp,nltk,Python,Python 2.7,Nlp,Nltk,我有两个列表:一个是用户的兴趣;第二,关于一本书的关键词。我想根据用户给定的兴趣列表向用户推荐这本书。我正在使用Python库difflib的SequenceMatcher类来匹配类似的单词,如“game”、“games”、“games”、“gamer”等。ratio函数给我一个介于[0,1]之间的数字,说明这两个字符串有多相似。但我被一个例子困住了,我计算了“循环”和“射击”之间的相似性。结果是0.6667 for interest in self.interests: for key

我有两个列表:一个是用户的兴趣;第二,关于一本书的关键词。我想根据用户给定的兴趣列表向用户推荐这本书。我正在使用Python库
difflib
SequenceMatcher
类来匹配类似的单词,如“game”、“games”、“games”、“gamer”等。
ratio
函数给我一个介于[0,1]之间的数字,说明这两个字符串有多相似。但我被一个例子困住了,我计算了“循环”和“射击”之间的相似性。结果是
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 

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

这是因为SequenceMatcher基于或类似的东西。语义相似性更适合您的情况或两者的混合情况

当您使用python时,请看一下NLTK包(),可能是这样的


对于使用C++的人,可以检查这个词,以供参考:

第一,<强>一个词可以有很多意义< /强>,当你试图找到相似的词时,你可能需要一些词义消歧。

给定一对单词,如果我们以最相似的一对感官作为判断两个单词是否相似的标准,我们可以尝试以下方法:

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
从nltk.corpus导入wordnet作为wn
来自itertools进口产品
wordx,wordy=“猫”,“狗”
sem1,sem2=wn.synsets(wordx),wn.synsets(wordy)
maxscore=0
对于列表中的i,j(产品(*[sem1,sem2]):
分数=i.wup_相似性(j)#Wu-Palmer相似性
maxscore=如果maxscore

您还可以使用其他相似性函数。唯一的问题是当你遇到wordnet中没有的单词时。然后我建议您回退到
difflib

开始,我想使用正则表达式执行额外的测试,以区分低比率的匹配。它可以是处理特定问题的解决方案,例如以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
给予

请从文档中注意这一点:

SequenceMatcher计算并缓存有关 第二个序列,所以如果你想比较一个序列和多个序列 序列,使用set_seq2()一次性设置常用的序列 重复调用set_seq1(),对其他每个序列调用一次


看看这个lib:Heelo。你的意思是0.6667小于self.limit,因此循环和射击被宣布为不匹配,而你希望结果在这两个词之间匹配吗?或者相反?@eyquem他们的循环和射击没有相似之处,但是比率函数给出了一个很高的匹配。。。这就是问题所在。你对提高self.limit的值有什么看法?@eyquem ratio()调用“gaming”和“game”的结果是“0.6”,同时“looping”和“shooting”的结果是调用ratio()的结果是“0.66667”,所以增加self.limit对推荐NLTK没有帮助+1!它非常适合这种用法。或者可能有助于语义相似性位这是一个好主意,可以考虑
词干分析。谢谢分享。@2对不起,英语不是我的母语,有时我很难理解。目前我不明白你想用
词干法表达什么意思
不用担心,这是
信息检索中的一种技术
,你的产品调用中使用
*[…]
有什么原因吗?似乎您可以忽略它以获得与
产品(sem1,sem2)相同的效果(iterables
sem1
sem2
)。我遗漏了什么吗?对不起,
*
,我的代码有点冗长。哈哈哈,这样做
product(*[sem1,sem2])
实际上与
product(sem1,sem2)
相同,但是您可以看到第一个列表是由
[sem1,sem2]
组成的单个列表,但是第二个作为两个参数
sem1,sem2
IsName=list(product(x,y))==list(product(*[x,y])传递
你会得到
isname==True
=)@alvas就在这里吐口水。。。你不想也做类似的事情吗?我发现“hot”、“warm”与“warm”、“hot”的得分不同。请注意
wup\u相似性
基于路径=)
  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