计算文档与文档的类似度

最近帮不少本科毕业生作文本数据分析,常常遇到的一个需求是计算文档类似度。算法

思路:机器学习

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

  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是向量)code

计算文档与文档的类似度

#cos类似性计算orm

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
相关文章
相关标签/搜索