相似度度量:计算个体间相似度
相似度值越小,距离越大,相似度越大,距离越小
余弦相似度:
一个向量空间中两个向量夹角的余弦值作为衡量两个个体之间差异的大小
余弦值接近1,夹角趋于0,表明两个向量越相似
例如:文本相似度计算
1.找出两篇文章的关键词
2.每篇文章各取出若干关键词,合并成一个集合,计算每篇文章对于这个词的词频
3.生成两篇文章各自的词频向量
4.计算两个向量的余弦相似度,值越大就表示越相似
import jieba
import numpy as np
s1 = '这只皮靴号码大了,那只号码合适'
s2 = '这只皮靴号码不小,那只更合适'
# 切词
s1_list = [x for x in jieba.cut(s1,cut_all=True) if x!='']
s2_list = [x for x in jieba.cut(s2,cut_all=True) if x!='']
# 去重
s1_set = set(s1_list)
s2_set = set(s2_list)
# 合并俩个集合
s_set = s1_set.union(s2_set)
# 对单词计数
# s1_dict = {}
# for word in s1_list:
# if s1_dict.get(word, -1) == -1:
# s1_dict[word] = 1
# else:
# s1_dict[word] += 1
# 加入停用词
# 获取停用词集合
stop_set = set()
with open('stop_list.txt','r',encoding='utf-8') as f:
for word_list in f.readlines():
word = word_list[0]
stop_set.add(word)
print("停用词:",stop_set)
# 生成向量,对所有的汉语单词进行编码,
# 给每一个汉语对应的位置,对应的位置放上对应的词频
index = 0
word_encode_dict = {}
for word in s_set:
# 加入停用词判断
if word in stop_set:
continue
word_encode_dict[word] = index
index +=1
print('字典:',word_encode_dict)
# 封装单词计数方法
def word_cnt (lis):
s_dict ={}
for word in lis:
if s_dict.get(word, -1) == -1:
s_dict[word] = 1
else:
s_dict[word] += 1
return s_dict
# 计算单词对应的数据
s1_dict_re = word_cnt(s1_list)
s2_dict_re = word_cnt(s2_list)
# 实现哪个位置哪个词,集合要和词频字典一样长,s1向量,s2向量
s1_freq_list = [0]*len(word_encode_dict)
s2_freq_list = [0]*len(word_encode_dict)
# 将字典位置的词填上对应的单词数量
# for word ,cnt in dict_re.items():
# s1_freq_list[word_encode_dict[word]] = cnt
def freq_func(dict,word_encode_dict, s_freq):
if len(dict) < 1:
return
for word,cnt in dict.items():
# 加入停用词
if word in stop_set:
continue
s_freq[word_encode_dict[word]] = cnt
# 计算向量
freq_func(s1_dict_re,word_encode_dict,s1_freq_list)
freq_func(s2_dict_re,word_encode_dict,s2_freq_list)
#
# 可以用余弦公式计算 cos(A,B) = (A*B) / (||A|| * ||B||)
# python 中计算向量余弦相似度可以用NumPy
def consine_func(a,b):
return np.dot(a,b) / (np.linalg.norm(a) * np.linalg.norm(b))
# 计算余弦值
print(consine_func(s1_freq_list,s2_freq_list))