为了匹配相关的知识点,要比较知识点之间的相似度,但文本相似度计算可采用多种方法,
- 基于集合的方法(如Jaccard、Dice系数)适合短文本或关键词匹配,计算简单但忽略语义;
- 基于词频的方法(如TF-IDF+余弦相似度、BM25)适用于文档检索,考虑词频和重要性;
- 基于词嵌入的方法(如Word2Vec、Sentence-BERT)能捕捉语义信息,适合高精度匹配;
- 基于编辑距离的方法(如Levenshtein、Jaro-Winkler)用于拼写纠错或模糊匹配;
- 基于N-gram的方法可检测局部相似性,常用于抄袭识别。
结合我们的情况,我们首先选择了基于集合的方法,对二者进行初步的比较,作为一个参考,和筛选掉一部分无关的内容。
def word_score(sents_1, sents_2):
counter = 0
for sent in sents_1:
if sent in sents_2:
counter += 1
sents_similarity=counter/(len(sents_1) + len(sents_2) - counter)
return sents_similarity
我们采用jaccard方法,比较相似度。
sents_1
:第一个句子集合(可迭代对象,如列表或字符串列表)。sents_2
:第二个句子集合
- 分子:统计两个集合中共同出现的元素数量(
counter
)。 - 分母:两个集合的总唯一元素数(
len(sents_1) + len(sents_2) - counter
)。 - 遍历
sents_1
的每个元素,检查是否存在于sents_2
中(if sent in sents_2
)。 - 时间复杂度:最坏情况下为 O(n×m)O(n×m)(
n
和m
为两个集合的长度)。
下面是相似度在外面代码中的具体使用,
# 两个三元组相关度得分
def list_score(list1,list2):
score1 = word_score(''.join(list1),''.join(list2))
score2 = cos_score(list1,list2)
res =(score1 + score2) / 2
# print("得分:", res)
return res
#取得列表中相似度最大的元素
def kp_score(kp,list):
res=0
for l in list:
s=cos_score(kp,l)
res=max(s,res)
# print("得分:", res)
return res
1. list_score(list1, list2)
计算两个三元组列表(list1
和 list2
)的综合相似度得分。
- 词重叠率(Jaccard相似度):
- 将两个列表拼接成字符串,计算基于字符的
word_score
(即Jaccard
相似度)。
- 将两个列表拼接成字符串,计算基于字符的
- 余弦相似度(
cos_score
):- 直接计算两个列表的向量余弦相似度(需确保
cos_score
已实现)。
- 直接计算两个列表的向量余弦相似度(需确保
- 综合得分:
- 取
word_score
和cos_score
的平均值作为最终相似度
- 取
2. kp_score(kp, list)
计算一个三元组 kp
与列表 list
中所有三元组的 最大余弦相似度。
计算逻辑:
- 遍历
list
中的每个元素l
,计算cos_score(kp, l)
。 - 返回所有相似度中的最大值(即最匹配的项)。
适用场景:
- 在候选三元组集合中,找到与目标三元组
kp
最相似的项