我正在寻找的不仅仅是两个文本之间的简单相似性得分。但是字符串中子字符串的相似性得分。说:
text1
在上面的示例中,text2
的所有单词都完全出现在text1
中,因此相似度应为100%。
如果缺少std::vector<uchar>
的某些单词,则分数应该更低。
我正在使用不同段落大小的大型数据集,因此在较大的段落中找到较小的段落具有这样的相似性得分是至关重要的。
我发现只有字符串相似性,例如余弦相似度,difflib相似性等,它们比较两个字符串。但不是关于另一个字符串中的子串的分数。
答案 0 :(得分:4)
根据您的描述,如何:
>>> a = "cat is sleeping on the mat"
>>> b = "the cat is sleeping on the red mat in the living room"
>>> a = a.split(" ")
>>> score = 0.0
>>> for word in a: #for every word in your string
if word in b: #if it is in your bigger string increase score
score += 1
>>> score/len(a) #obtain percentage given total word number
1.0
如果它有一个遗漏的单词,例如:
>>> c = "the cat is not sleeping on the mat"
>>> c = c.split(" ")
>>> score = 0.0
>>> for w in c:
if w in b:
score +=1
>>> score/len(c)
0.875
此外,您可以按@roadrunner建议并拆分b
并将其保存为一组,以便b = set(b.split(" "))
加快您的效果。这会将该部分复杂度降低到O(1)
,并将整体算法提高到O(n)
复杂度。
编辑:你说你已经尝试了一些像Cosine Similarity等指标。但是我怀疑你可能会从检查Levenshtein Distance相似性中受益,我怀疑这可能会对此有所帮助案例作为所提供解决方案的补充。
答案 1 :(得分:4)
您还可以使用collections.defaultdict
来存储word_a
中存在的word_b
中的字数,然后sum()
计算word_a
的长度from collections import defaultdict
a = "the cat is not sleeping on the mat"
b = "the cat is sleeping on the red mat in the living room"
word_a = a.split()
word_b = set(b.split())
d = defaultdict(int)
for word in word_a:
if word in word_b:
d[word] += 1
print(sum(d.values()) / len(word_a))
最后:
0.875
哪个输出:
word_a
注意:由于我们只关心检查word_b
中是否存在word_b
中的字词,因此将set()
转换为O(1)
将允许O(n)
查找,而不是保持列表,O(n)
。然后,这使得上述代码import { Pusher } from 'pusher-js';
的总时间复杂度成为可能。
答案 2 :(得分:2)
与DarkCygbus类似,但相似性基于其计数总字符而非单词。另一方面,此脚本仅检查与完整单词(text_2.split())
的重合from __future__ import division
text_1 = 'cat is sleeping on the mat'
text_2 = 'The cat is sleeping on the red mat in the living room'
no_match = 0
match = 0
for word in text_1.split():
if word not in text_2.split():
no_match += len(word)
else:
match += len(word)
similarity = match/(match + no_match)
print ('{0:.0%}'.format(similarity))