当前位置:   article > 正文

自然语言处理(2)——文档相似度计算_vsm矩阵

vsm矩阵

上一篇讲了如何利用ICTCLAS分词工具进行分词,这一次讲一下文本相似度计算,从字面上理解就是比较两个文本之间的相似性。在文本分类和聚类中都会用到文本相似度的计算。

1.VSM

在讲文本相似度之前,先讲一下VSM即向量空间模型,该模型将文档映射到向量空间中。假设文档用表示文档集中D中的第i个文本,则可以表示为:


其中 可以有两种表达方式

(1)布尔类型表达,用0或1表示该词条是否在中出现,即该词出现则为1,否则为0;

(2)表示该词在中的权重,即,N代表文档中词的总数,表示词j在文档中出现的次数。

举个例子:

=小米 n 手机 n 4m 的 u 屏幕 n 太 d 给力 a 了 y , w 5m 英寸 q 的 u 高 a 色彩 n 饱和度 n 夏普 n wJ DI n 屏幕 n , w 1920x1080 n 全 d 高清 a 分辨率 n 。 w

=锤子 n 手机 n 终于 d 要 v 发货 v 了 y ! w 只 d 是 v 没 v 4Gn 的 u 机子 n , w 我 r 基本 a 不 d 要 v 了 y ! w 有 v 哪 r 位 q 同学 n 要 v 的 u , w 这 r 单子 n 给 p 你 r ! w 不 d 加收 v 任何 r 费用 n ! w

过滤掉停用词后,则抽取出词袋<小米,手机,屏幕,太,给力,高,色彩,饱和度,完善,全,高清,分辨率,锤子,终于,要,发货,4G,机子,基本,同学,单子,加收,费用>。用VSM模型表示该文本,采用第1种布尔类型表达方式



2.文本相似度计算

本文采用余弦相似度来度量文本的相似度,该公式如下:


表示两个向量的内积,即假设两个向量为n维向量,则


可以通过下式计算:

现在可以通过余弦相似度公式计算上述两个文档的相似度。


最后我们就需要确定阈值来进行判断两个文档是否相似。这在以后分类和聚类中来讨论阈值的选定。

如果只是想了解一下文本相似度那么到这里已经差不多了,如果是想实现的那么可以接着往下看。
3.文本相似度计算C++实现
(1)构建词袋
  1. int foundWordBag(char *file,vector<string> &vc_word){
  2. ifstream ifs;
  3. string word;
  4. char mark;
  5. int flag=0;
  6. vector<string>::iterator vc_ite;
  7. ifs.open(file,ios::in);
  8. while(!ifs.eof()){
  9. ifs>>word>>mark;
  10. if(mark=='n'||mark=='a'||mark=='d'||mark=='v'){
  11. flag=0;
  12. for(vc_ite=vc_word.begin();vc_ite!=vc_word.end();vc_ite++){
  13. if(*vc_ite==word){
  14. flag=1;
  15. break;
  16. }
  17. }
  18. if(flag==0)
  19. vc_word.push_back(word);
  20. }
  21. }
  22. ifs.close();
  23. return 0;
  24. }

第一个参数是所需要计算相似度的文本路径,其格式是在上一篇中讲的分词处理后的格式,第二个参数是一个string类型的vector容器,用于存放词袋的。

(2)构建VSM矩阵

  1. int foundVSMMatrix(char *file,char *result,vector<string> vc_word){
  2. ifstream ifs;
  3. ofstream ofs;
  4. string words;
  5. char mark;
  6. vector<string>::iterator ite;
  7. int n=vc_word.size();
  8. float *matrix=new float[n];
  9. int i;
  10. ifs.open(file,ios::in);
  11. ofs.open(result,ios::ate);
  12. for(i=0;i<n;i++)
  13. matrix[i]=0;
  14. while(!ifs.eof()){
  15. ifs>>words>>mark;
  16. if(ifs.fail())
  17. break;
  18. if(mark!='l'){//文档结尾标记
  19. if(mark=='n'||mark=='a'||mark=='d'||mark=='v'){
  20. for(ite=vc_word.begin(),i=0;ite!=vc_word.end();ite++,i++)
  21. if(*ite==words){
  22. matrix[i]++;
  23. }
  24. }
  25. }else if(mark=='l'){
  26. for(i=0;i<n;i++)
  27. ofs<<matrix[i]<<"\t";
  28. ofs<<endl;
  29. for(i=0;i<n;i++)
  30. matrix[i]=0;
  31. }
  32. }
  33. ifs.close();
  34. ofs.close();
  35. return 0;
  36. }

第一个参数为文档分词处理文件路径,第二个参数是VSM矩阵存放的文件路径,第3个参数为词袋。

(3)计算相似度

  1. float countSimilarity(int v,float d1[],float d2[]){
  2. float sim;
  3. float m=0;
  4. float n1=0,n2=0;
  5. int i;
  6. for(i=0;i<v;i++){
  7. m=m+d1[i]*d2[i];
  8. n1=n1+d1[i]*d1[i];
  9. n2=n2+d2[i]*d2[i];
  10. }
  11. sim=m/(sqrt(n1)*sqrt(n2));
  12. return sim;
  13. }
第一个参数是向量的维度,第二个和第三个参数是一个n维的向量,即用VSM模型表示的两个文档。返回值是两个文档的相似度。

文档相似度计算就介绍到这里,感兴趣的同学可以自己做一个模型自己测试一下。


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/356862
推荐阅读
  

闽ICP备14008679号