其他分享
首页 > 其他分享> > 计算文档与文档的相似度

计算文档与文档的相似度

作者:互联网

最近帮很多本科毕业生做文本数据分析,经常遇到的一个需求是计算文档相似度。

思路:

  1. 抽取语料(所有文档)中的词语,构建词典(词语与数字对应起来)。

  2. 根据构建的词典对每个文档进行重新编码(将文档转化为向量)。

  3. 使用余弦计算相似度

下面的corpus是我在知乎live随便找到的几个评论,拿来当做测试的例子。好像数据不怎么好玩,大家跟着一起凑合凑合吧。


corpus = ['老师讲的很好很全面干货很多',
        '讲述的很好干货满满',
        '满满的干货很实用',
        '感谢老师无私的分享啦',
        '真水呵呵哒']

构建词典-学习语料特征
其实在机器学习里,学习语料的所有词语并将其转化为数字,这一步骤叫做特征化。强烈推荐对数据科学感兴趣的童鞋学学scikit-learn库,人工智能咱们小白可能还玩不转,但是调用封装好的机器学习算法,浅显的玩玩机器学习还是没啥难度的。

在scikit-learn中,涉及到文本数据特征化的类有sklearn.feature_extraction.text.CountVectorizer 和sklearn.feature_extraction.text.TfidfVectorizer 。我们先以常见的词频统计作为特征抽取的方式开始探索,由于scikit默认使用英文空格作为分词符号,所以处理中文数据前我们要分词并以空格间隔开来。


from sklearn.feature_extraction.text import CountVectorizer
import jieba
corpus = [' '.join(jieba.lcut(doc))
          for doc in corpus]corpus
['老师 讲 的 很 好 很 全面 干货 很多',
 '讲述 的 很 好 干货 满满',
 '满满的 干货 很 实用',
 '感谢 老师 无私 的 分享 啦',
 '真水 呵呵 哒']
wordcounter = CountVectorizer()

#学习特征(构建词典)fit  并转化为特征矩阵。
matrix=wordcounter.fit_transform(corpus)
print(matrix.toarray())

#查看下特征与词语对应关系
print(wordcounter.get_feature_names())
[[1 0 0 0 1 1 0 0 0 0 0 1 0]
 [0 0 0 0 1 0 0 0 1 0 0 0 1]
 [0 0 0 1 1 0 0 0 0 1 0 0 0]
 [0 1 0 0 0 0 1 1 0 0 0 1 0]
 [0 0 1 0 0 0 0 0 0 0 1 0 0]]
['全面', '分享', '呵呵', '实用', '干货', 
'很多', '感谢', '无私', '满满', '满满的', 
'真水', '老师', '讲述']

计算相似度
这里使用scikit提供的cosine-similarity函数。


from sklearn.metrics.pairwise import cosine_similarity

cosine_similarity(matrix)
array([[1.        , 0.28867513, 0.28867513, 0.25      , 0.        ],
       [0.28867513, 1.        , 0.33333333, 0.        , 0.        ],
       [0.28867513, 0.33333333, 1.        , 0.        , 0.        ],
       [0.25      , 0.        , 0.        , 1.        , 0.        ],
       [0.        , 0.        , 0.        , 0.        , 1.        ]])
我们看到这个矩阵是沿着对角线对称的,所以我们只需要看第一行。

第一个评论与第一个评论之间的相似度为1
第一个评论与第二个评论的相似度为0.28867513
第一个评论与第三个评论的相似度为0.28867513
第一个评论与第四个评论的相似度为0.25
第一个评论与第四个评论的相似度为0

高中数学知识cos相似性计算公式
本以为自己对这里很熟悉,结果自己写cos计算公式时居然出错了。粘贴到这里,帮助大家回忆高中知识。(a和b是向量)

计算文档与文档的相似度

#cos相似性计算


def cosVector(x,y):
    result1=0.0
    result2=0.0
    result3=0.0
    for i in range(len(x)):
        result1 +=x[i]*y[i]   #sum(a*b)
        result2 +=x[i]**2     #sum(a*a)
        result3 +=y[i]**2     #sum(b*b)

    return str(result1/((result2*result3)**0.5))
vect1 = [1,0,1]
vect2 = [0,1,0]
vect3 = [1,1,1]

print("vect1与vect2相似度为:", cosVector(vect1, vect2))
print("vect1与vect3相似度为:", cosVector(vect1, vect3))
print("vect2与vect3相似度为:", cosVector(vect2, vect3))
vect1与vect2相似度为: 0.0
vect1与vect3相似度为: 0.8164965809277261
vect2与vect3相似度为: 0.5773502691896258

标签:计算,相似,度为,干货,文档,vect2,vect1,vect3
来源: https://blog.51cto.com/15069487/2581480