使用词向量计算文本相似度
杰卡德系数,英文叫做 Jaccard index,又称为 Jaccard 相似系数,用于比较有限样本集之间的相似性与差异性。Jaccard 系数值越大,样本相似度越高
计算方法:两个样本的交集除以并集得到的数值,
当两个样本完全一致时,结果为 1,当两个样本完全不同时,结果为 0。
import numpy as np from sklearn.feature_extraction.text import CountVectorizer def jaccard_similarity(s1, s2): def add_space(s): return " ".join(s) # 字中间加空格 s1, s2 = add_space(s1), add_space(s2) # 转为TF矩阵 cv = CountVectorizer(tokenizer=lambda s: s.split()) corpus = [s1, s2] vectors = cv.fit_transform(corpus).toarray() print(cv.get_feature_names()) print(vectors) # 求交集 numerator = np.sum(np.min(vectors, axis=0)) print(np.min(vectors, axis=0)) # 求并集 denominator = np.sum(np.max(vectors, axis=0)) print(np.max(vectors, axis=0)) # 计算杰卡德系数 return 1.0 * numerator / denominator if __name__ == "__main__": s1 = "你干啥呢?" s2 = "你在干什么?" print(jaccard_similarity(s1, s2))
直接计算 TF 矩阵中两个向量的相似度了,实际上就是求解两个向量夹角的余弦值:点乘积除以二者的模长,
def tf_similarity(s1, s2): def add_space(s): return " ".join(s) # 字中间加空格 s1, s2 = add_space(s1), add_space(s2) # 转为TF矩阵 cv = CountVectorizer(tokenizer=lambda s: s.split()) corpus = [s1, s2] vectors = cv.fit_transform(corpus).toarray() print(cv.get_feature_names()) print(vectors) # 计算TF系数 return np.dot(vectors[0], vectors[1]) / (norm(vectors[0]) * norm(vectors[1])) if __name__ == "__main__": s1 = "你干啥呢?" s2 = "你在干什么?" print(tf_similarity(s1, s2))
使用tf-idf计算夹角余弦值
def tfidf_similarity(s1, s2): def add_space(s): return ' '.join(s) # 将字中间加入空格 s1, s2 = add_space(s1), add_space(s2) # 转化为TF矩阵 cv = TfidfVectorizer(tokenizer=lambda s: s.split()) corpus = [s1, s2] vectors = cv.fit_transform(corpus).toarray() # 计算TF系数 return np.dot(vectors[0], vectors[1]) / (norm(vectors[0]) * norm(vectors[1])) if __name__ == "__main__": s1 = "你干啥呢?" s2 = "你在干什么?" print(tfidf_similarity(s1, s2))
编辑距离,( Edit Distance,Levenshtein 距离),指两个字符串间,由一个转成另一个所需的最少编辑操作次数。如果二者距离越大,说明越是不同。编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符
例如有两个字符串:string 和 setting,如果要把 string 转化为 setting,需要这么两步:
- 第一步,在 s 和 t 之间加入字符 e
- 第二步,把 r 替换成 t
此时编辑距离差是 2,就是二者要进行转化所要改变(添加、替换、删除)的最小步数。
def edit_distance(s1, s2): import distance # 需要安装distance包 return distance.levenshtein(s1, s2) if __name__ == "__main__": s1 = "你干啥呢?" s2 = "你在干什么?" print(edit_distance(s1, s2))