最近帮不少本科毕业生作文本数据分析,常常遇到的一个需求是计算文档类似度。算法
思路:机器学习
抽取语料(全部文档)中的词语,构建词典(词语与数字对应起来)。ide
根据构建的词典对每一个文档进行从新编码(将文档转化为向量)。函数
下面的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