Python 检查两个单词是否相互关联
我有两个列表:一个是用户的兴趣;第二,关于一本书的关键词。我想根据用户给定的兴趣列表向用户推荐这本书。我正在使用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
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)相同的效果(iterablessem1
和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