文档章节

利用word分词来计算文本相似度

杨尚川
 杨尚川
发布于 2015/05/20 06:36
字数 1907
阅读 6847
收藏 91

word分词提供了多种文本相似度计算方式:

方式一:余弦相似度,通过计算两个向量的夹角余弦值来评估他们的相似度

实现类:org.apdplat.word.analysis.CosineTextSimilarity

用法如下:

String text1 = "我爱购物";
String text2 = "我爱读书";
String text3 = "他是黑客";
TextSimilarity textSimilarity = new CosineTextSimilarity();
double score1pk1 = textSimilarity.similarScore(text1, text1);
double score1pk2 = textSimilarity.similarScore(text1, text2);
double score1pk3 = textSimilarity.similarScore(text1, text3);
double score2pk2 = textSimilarity.similarScore(text2, text2);
double score2pk3 = textSimilarity.similarScore(text2, text3);
double score3pk3 = textSimilarity.similarScore(text3, text3);
System.out.println(text1+" 和 "+text1+" 的相似度分值:"+score1pk1);
System.out.println(text1+" 和 "+text2+" 的相似度分值:"+score1pk2);
System.out.println(text1+" 和 "+text3+" 的相似度分值:"+score1pk3);
System.out.println(text2+" 和 "+text2+" 的相似度分值:"+score2pk2);
System.out.println(text2+" 和 "+text3+" 的相似度分值:"+score2pk3);
System.out.println(text3+" 和 "+text3+" 的相似度分值:"+score3pk3);

运行结果如下:

我爱购物 和 我爱购物 的相似度分值:1.0
我爱购物 和 我爱读书 的相似度分值:0.67
我爱购物 和 他是黑客 的相似度分值:0.0
我爱读书 和 我爱读书 的相似度分值:1.0
我爱读书 和 他是黑客 的相似度分值:0.0
他是黑客 和 他是黑客 的相似度分值:1.0


方式二:简单共有词,通过计算两篇文档共有的词的总字符数除以最长文档字符数来评估他们的相似度

实现类:org.apdplat.word.analysis.SimpleTextSimilarity

用法如下:

String text1 = "我爱购物";
String text2 = "我爱读书";
String text3 = "他是黑客";
TextSimilarity textSimilarity = new SimpleTextSimilarity();
double score1pk1 = textSimilarity.similarScore(text1, text1);
double score1pk2 = textSimilarity.similarScore(text1, text2);
double score1pk3 = textSimilarity.similarScore(text1, text3);
double score2pk2 = textSimilarity.similarScore(text2, text2);
double score2pk3 = textSimilarity.similarScore(text2, text3);
double score3pk3 = textSimilarity.similarScore(text3, text3);
System.out.println(text1+" 和 "+text1+" 的相似度分值:"+score1pk1);
System.out.println(text1+" 和 "+text2+" 的相似度分值:"+score1pk2);
System.out.println(text1+" 和 "+text3+" 的相似度分值:"+score1pk3);
System.out.println(text2+" 和 "+text2+" 的相似度分值:"+score2pk2);
System.out.println(text2+" 和 "+text3+" 的相似度分值:"+score2pk3);
System.out.println(text3+" 和 "+text3+" 的相似度分值:"+score3pk3);

运行结果如下:

我爱购物 和 我爱购物 的相似度分值:1.0
我爱购物 和 我爱读书 的相似度分值:0.5
我爱购物 和 他是黑客 的相似度分值:0.0
我爱读书 和 我爱读书 的相似度分值:1.0
我爱读书 和 他是黑客 的相似度分值:0.0
他是黑客 和 他是黑客 的相似度分值:1.0


方式三:编辑距离,通过计算两个字串之间由一个转成另一个所需的最少编辑操作次数来评估他们的相似度

实现类:org.apdplat.word.analysis.EditDistanceTextSimilarity

用法如下:

String text1 = "我爱购物";
String text2 = "我爱读书";
String text3 = "他是黑客";
Similarity textSimilarity = new EditDistanceTextSimilarity();
double score1pk1 = textSimilarity.similarScore(text1, text1);
double score1pk2 = textSimilarity.similarScore(text1, text2);
double score1pk3 = textSimilarity.similarScore(text1, text3);
double score2pk2 = textSimilarity.similarScore(text2, text2);
double score2pk3 = textSimilarity.similarScore(text2, text3);
double score3pk3 = textSimilarity.similarScore(text3, text3);
System.out.println(text1+" 和 "+text1+" 的相似度分值:"+score1pk1);
System.out.println(text1+" 和 "+text2+" 的相似度分值:"+score1pk2);
System.out.println(text1+" 和 "+text3+" 的相似度分值:"+score1pk3);
System.out.println(text2+" 和 "+text2+" 的相似度分值:"+score2pk2);
System.out.println(text2+" 和 "+text3+" 的相似度分值:"+score2pk3);
System.out.println(text3+" 和 "+text3+" 的相似度分值:"+score3pk3);

运行结果如下:

我爱购物 和 我爱购物 的相似度分值:1.0
我爱购物 和 我爱读书 的相似度分值:0.5
我爱购物 和 他是黑客 的相似度分值:0.0
我爱读书 和 我爱读书 的相似度分值:1.0
我爱读书 和 他是黑客 的相似度分值:0.0
他是黑客 和 他是黑客 的相似度分值:1.0


方式四:SimHash + 汉明距离,先使用SimHash把不同长度的文本映射为等长文本,然后再计算等长文本的汉明距离

实现类:org.apdplat.word.analysis.SimHashPlusHammingDistanceTextSimilarity

用法如下:

String text1 = "我爱购物";
String text2 = "我爱读书";
String text3 = "他是黑客";
TextSimilarity textSimilarity = new SimHashPlusHammingDistanceTextSimilarity();
double score1pk1 = textSimilarity.similarScore(text1, text1);
double score1pk2 = textSimilarity.similarScore(text1, text2);
double score1pk3 = textSimilarity.similarScore(text1, text3);
double score2pk2 = textSimilarity.similarScore(text2, text2);
double score2pk3 = textSimilarity.similarScore(text2, text3);
double score3pk3 = textSimilarity.similarScore(text3, text3);
System.out.println(text1+" 和 "+text1+" 的相似度分值:"+score1pk1);
System.out.println(text1+" 和 "+text2+" 的相似度分值:"+score1pk2);
System.out.println(text1+" 和 "+text3+" 的相似度分值:"+score1pk3);
System.out.println(text2+" 和 "+text2+" 的相似度分值:"+score2pk2);
System.out.println(text2+" 和 "+text3+" 的相似度分值:"+score2pk3);
System.out.println(text3+" 和 "+text3+" 的相似度分值:"+score3pk3);

运行结果如下:

我爱购物 和 我爱购物 的相似度分值:1.0
我爱购物 和 我爱读书 的相似度分值:0.95
我爱购物 和 他是黑客 的相似度分值:0.83
我爱读书 和 我爱读书 的相似度分值:1.0
我爱读书 和 他是黑客 的相似度分值:0.86
他是黑客 和 他是黑客 的相似度分值:1.0


方式五:Jaccard相似性系数,通过计算两个集合交集的大小除以并集的大小来评估他们的相似度

实现类:org.apdplat.word.analysis.JaccardTextSimilarity

用法如下:

String text1 = "我爱购物";
String text2 = "我爱读书";
String text3 = "他是黑客";
TextSimilarity textSimilarity = new JaccardTextSimilarity();
double score1pk1 = textSimilarity.similarScore(text1, text1);
double score1pk2 = textSimilarity.similarScore(text1, text2);
double score1pk3 = textSimilarity.similarScore(text1, text3);
double score2pk2 = textSimilarity.similarScore(text2, text2);
double score2pk3 = textSimilarity.similarScore(text2, text3);
double score3pk3 = textSimilarity.similarScore(text3, text3);
System.out.println(text1+" 和 "+text1+" 的相似度分值:"+score1pk1);
System.out.println(text1+" 和 "+text2+" 的相似度分值:"+score1pk2);
System.out.println(text1+" 和 "+text3+" 的相似度分值:"+score1pk3);
System.out.println(text2+" 和 "+text2+" 的相似度分值:"+score2pk2);
System.out.println(text2+" 和 "+text3+" 的相似度分值:"+score2pk3);
System.out.println(text3+" 和 "+text3+" 的相似度分值:"+score3pk3);

运行结果如下:

我爱购物 和 我爱购物 的相似度分值:1.0
我爱购物 和 我爱读书 的相似度分值:0.5
我爱购物 和 他是黑客 的相似度分值:0.0
我爱读书 和 我爱读书 的相似度分值:1.0
我爱读书 和 他是黑客 的相似度分值:0.0
他是黑客 和 他是黑客 的相似度分值:1.0


方式六:欧几里得距离(Euclidean Distance),通过计算两点间的距离来评估他们的相似度

实现类:org.apdplat.word.analysis.EuclideanDistanceTextSimilarity

用法如下:

String text1 = "我爱购物";
String text2 = "我爱读书";
String text3 = "他是黑客";
TextSimilarity textSimilarity = new EuclideanDistanceTextSimilarity();
double score1pk1 = textSimilarity.similarScore(text1, text1);
double score1pk2 = textSimilarity.similarScore(text1, text2);
double score1pk3 = textSimilarity.similarScore(text1, text3);
double score2pk2 = textSimilarity.similarScore(text2, text2);
double score2pk3 = textSimilarity.similarScore(text2, text3);
double score3pk3 = textSimilarity.similarScore(text3, text3);
System.out.println(text1+" 和 "+text1+" 的相似度分值:"+score1pk1);
System.out.println(text1+" 和 "+text2+" 的相似度分值:"+score1pk2);
System.out.println(text1+" 和 "+text3+" 的相似度分值:"+score1pk3);
System.out.println(text2+" 和 "+text2+" 的相似度分值:"+score2pk2);
System.out.println(text2+" 和 "+text3+" 的相似度分值:"+score2pk3);
System.out.println(text3+" 和 "+text3+" 的相似度分值:"+score3pk3);

运行结果如下:

我爱购物 和 我爱购物 的相似度分值:1.0
我爱购物 和 我爱读书 的相似度分值:0.41
我爱购物 和 他是黑客 的相似度分值:0.29
我爱读书 和 我爱读书 的相似度分值:1.0
我爱读书 和 他是黑客 的相似度分值:0.29
他是黑客 和 他是黑客 的相似度分值:1.0


方式七:曼哈顿距离(Manhattan Distance),通过计算两个点在标准坐标系上的绝对轴距总和来评估他们的相似度

实现类:org.apdplat.word.analysis.ManhattanDistanceTextSimilarity

用法如下:

String text1 = "我爱购物";
String text2 = "我爱读书";
String text3 = "他是黑客";
TextSimilarity textSimilarity = new ManhattanDistanceTextSimilarity();
double score1pk1 = textSimilarity.similarScore(text1, text1);
double score1pk2 = textSimilarity.similarScore(text1, text2);
double score1pk3 = textSimilarity.similarScore(text1, text3);
double score2pk2 = textSimilarity.similarScore(text2, text2);
double score2pk3 = textSimilarity.similarScore(text2, text3);
double score3pk3 = textSimilarity.similarScore(text3, text3);
System.out.println(text1+" 和 "+text1+" 的相似度分值:"+score1pk1);
System.out.println(text1+" 和 "+text2+" 的相似度分值:"+score1pk2);
System.out.println(text1+" 和 "+text3+" 的相似度分值:"+score1pk3);
System.out.println(text2+" 和 "+text2+" 的相似度分值:"+score2pk2);
System.out.println(text2+" 和 "+text3+" 的相似度分值:"+score2pk3);
System.out.println(text3+" 和 "+text3+" 的相似度分值:"+score3pk3);

运行结果如下:

我爱购物 和 我爱购物 的相似度分值:1.0
我爱购物 和 我爱读书 的相似度分值:0.33
我爱购物 和 他是黑客 的相似度分值:0.14
我爱读书 和 我爱读书 的相似度分值:1.0
我爱读书 和 他是黑客 的相似度分值:0.14
他是黑客 和 他是黑客 的相似度分值:1.0




© 著作权归作者所有

杨尚川

杨尚川

粉丝 1100
博文 220
码字总数 1624053
作品 12
东城
架构师
私信 提问
加载中

评论(29)

j
jinzhaoOMG
老师你好,项目中文本相似度场景,请问如何把同义词也算到文本相似度中
杨尚川
杨尚川

引用来自“Ryan-fr”的评论

老师好,最近项目中遇到了分词场景,我用余弦相似度来判断“上期年初金额“和 “上年期初余额“ 的相似度分值:0.0,但是在项目业务中认为这应该是相似的,还有这种:上年期初余额 和 上期期初余额 的相似度分值:0.5 ,有办法解决么?我试了下不管我是加同义词还是增加词库都不好用
这种用普通方法就解决不了了,因为这是属于典型的语义分析了。
Ryan-fr
Ryan-fr
老师好,最近项目中遇到了分词场景,我用余弦相似度来判断“上期年初金额“和 “上年期初余额“ 的相似度分值:0.0,但是在项目业务中认为这应该是相似的,还有这种:上年期初余额 和 上期期初余额 的相似度分值:0.5 ,有办法解决么?我试了下不管我是加同义词还是增加词库都不好用
杨尚川
杨尚川

引用来自“lidaoyang”的评论

老师,我需要用相识度计算两个新闻标题的相识度,类似(词1:万达股债双杀市值蒸发666亿全世界都等王思聪发微博,词2:万达股债双杀市值半日蒸发666亿元全世界都在等王思聪发微博)我用简单共有词得到的是0.586,用编辑距离得到的是0.862,其他几个的我没有试过,不知道用哪个合适?很头疼啊!请求帮助分析一下用哪个好?
首先,你弄一个测试数据集,标注100对句子,并标上相似度分值,分值可以简单地分为五个档次如0,0.25,0.5,0.75,1。
然后,你用各种算法来计算分值,并比较计算出来的分值跟标注分值之间的差距,把这100个差距分值取绝对值累加起来。
最后,哪一种算法的累加值最小,就说明哪一种算法效果最好。
l
lidaoyang
老师,我需要用相识度计算两个新闻标题的相识度,类似(词1:万达股债双杀市值蒸发666亿全世界都等王思聪发微博,词2:万达股债双杀市值半日蒸发666亿元全世界都在等王思聪发微博)我用简单共有词得到的是0.586,用编辑距离得到的是0.862,其他几个的我没有试过,不知道用哪个合适?很头疼啊!请求帮助分析一下用哪个好?
杨尚川
杨尚川

引用来自“figzha”的评论

大神,这个solr里面加配置 tokenizer class="org.apdplat.word.solr.ChineseWordTokenizerFactory" conf="D:/word-dic/word.local.conf

后面的conf配置可否配相对路径? word-dic配置包放在哪儿
可以配置相对路径,相对于你启动solr的目录
figzha
figzha
大神,这个solr里面加配置 tokenizer class="org.apdplat.word.solr.ChineseWordTokenizerFactory" conf="D:/word-dic/word.local.conf

后面的conf配置可否配相对路径? word-dic配置包放在哪儿
杨尚川
杨尚川

引用来自“figzha”的评论

问一下,为什么用word1.3的jar运行一下上面几个算法要花费1分钟呢?

引用来自“杨尚川”的评论

第一次启动的时候要初始化加载资源,比较耗时,之后就快了

引用来自“figzha”的评论

你好,我把word1.3.1 配置在 solr6.3.0下时报错,帮忙看下怎么回事,谢谢

配置如下:


  




报错如下:

null:java.lang.RuntimeException: java.lang.AbstractMethodError: org.apache.lucene.analysis.util.TokenizerFactory.create(Lorg/apache/lucene/util/AttributeFactory;)Lorg/apache/lucene/analysis/Tokenizer;
  at org.apache.solr.servlet.HttpSolrCall.sendError(HttpSolrCall.java:607)
  at org.apache.solr.servlet.HttpSolrCall.call(HttpSolrCall.java:475)
  at org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:303)

引用来自“杨尚川”的评论

要用word1.3这个版本。

word 1.3.1是从代码分支ForElasticsearch1.7.2中编译出来的,主要目的是支持 与lucene4.10.4、solr4.10.4和elasticsearch1.7.2兼容的版本。

引用来自“figzha”的评论

好的,谢谢啊
不客气
figzha
figzha

引用来自“figzha”的评论

问一下,为什么用word1.3的jar运行一下上面几个算法要花费1分钟呢?

引用来自“杨尚川”的评论

第一次启动的时候要初始化加载资源,比较耗时,之后就快了

引用来自“figzha”的评论

你好,我把word1.3.1 配置在 solr6.3.0下时报错,帮忙看下怎么回事,谢谢

配置如下:


  




报错如下:

null:java.lang.RuntimeException: java.lang.AbstractMethodError: org.apache.lucene.analysis.util.TokenizerFactory.create(Lorg/apache/lucene/util/AttributeFactory;)Lorg/apache/lucene/analysis/Tokenizer;
  at org.apache.solr.servlet.HttpSolrCall.sendError(HttpSolrCall.java:607)
  at org.apache.solr.servlet.HttpSolrCall.call(HttpSolrCall.java:475)
  at org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:303)

引用来自“杨尚川”的评论

要用word1.3这个版本。

word 1.3.1是从代码分支ForElasticsearch1.7.2中编译出来的,主要目的是支持 与lucene4.10.4、solr4.10.4和elasticsearch1.7.2兼容的版本。
好的,谢谢啊
杨尚川
杨尚川

引用来自“figzha”的评论

问一下,为什么用word1.3的jar运行一下上面几个算法要花费1分钟呢?

引用来自“杨尚川”的评论

第一次启动的时候要初始化加载资源,比较耗时,之后就快了

引用来自“figzha”的评论

你好,我把word1.3.1 配置在 solr6.3.0下时报错,帮忙看下怎么回事,谢谢

配置如下:


  




报错如下:

null:java.lang.RuntimeException: java.lang.AbstractMethodError: org.apache.lucene.analysis.util.TokenizerFactory.create(Lorg/apache/lucene/util/AttributeFactory;)Lorg/apache/lucene/analysis/Tokenizer;
  at org.apache.solr.servlet.HttpSolrCall.sendError(HttpSolrCall.java:607)
  at org.apache.solr.servlet.HttpSolrCall.call(HttpSolrCall.java:475)
  at org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:303)
要用word1.3这个版本。

word 1.3.1是从代码分支ForElasticsearch1.7.2中编译出来的,主要目的是支持 与lucene4.10.4、solr4.10.4和elasticsearch1.7.2兼容的版本。
利用word分词通过计算词的语境来获得相关词

我们如何通过计算词的语境来获得相关词呢? 语境的定义是:在一段文本中,任意一个词的语境由它的前N个词和后N个词组成。 相关词的定义是:如果两个词的语境越相似,那么这两个词就越相似,也...

杨尚川
2015/05/21
0
1
Word2vector句子相似度计算

word2vector 最近有任务要对句子和文档的相似读进行评估计算,学习了词向量的相关知识,并做了简单的测试。在测试过程中发现网上完整且简单的词向量分析句子相似度的文章比较少,所以打算整理...

zqh_zy
2017/07/05
0
0
利用word分词提供的文本相似度算法来辅助记忆英语单词

本文实现代码:利用word分词提供的文本相似度算法来辅助记忆英语单词 本文使用的英语单词囊括了几乎所有的考纲词汇共18123词: /** * 考纲词汇 * @return */public static Set<Word> getSyl...

杨尚川
2015/05/29
0
3
从0到1,了解NLP中的文本相似度

本文由云+社区发表 作者:netkiddy 导语 AI在2018年应该是互联网界最火的名词,没有之一。时间来到了9102年,也是项目相关,涉及到了一些AI写作相关的功能,为客户生成一些素材文章。但是,A...

腾讯云加社区
02/27
0
0
word v1.3 发布,Java 分布式中文分词组件

word 分词是一个Java实现的分布式的中文分词组件,提供了多种基于词典的分词算法,并利用ngram模型来消除歧义。能准确识别英文、数字,以及日期、时间等数量词,能识别人名、地名、组织机构名...

杨尚川
2015/08/29
4.5K
0

没有更多内容

加载失败,请刷新页面

加载更多

backbone源码学习中的知识点整理(一)

一、self var root = (typeof self == 'object' && self.self === self && self) || (typeof global == 'object' && global.global === global && global); 现代web之前的window.self和self ......

学霸猫
37分钟前
2
0
linux高级文件数据操作

cat :显示切割数据 -f:选择显示切割列; -s:比现实没有分割的行 -d:自定义分隔符 cut -d ‘ ’-f 1,3 a.txt : 以空格为分隔符显示第一列和第三列;这种情况不能分隔的行也会显示出来,如...

为何不可1995
今天
2
0
在Javascript中Eval函数的使用

【eval()函数】 JavaScript有许多小窍门来使编程更加容易。 其中之一就是eval()函数,这个函数可以把一个字符串当作一个JavaScript表达式一样去执行它。 举个小例子: var the_unevaled_ans...

花漾年华
今天
3
0
[日更-2019.5.22、23] Android 系统的分区和文件系统(二)--Android 文件系统中的文件

声明 Android系统中有很多分区,每个分区内的文件系统一般都不同的,使用ADB进入系统/目录下可发现挂载这很多的目录,不同的目录中可来自不同的分区及文件系统; 那么,就来分下这些目录里面...

小馬佩德罗
今天
2
0
数组操作相关算法

/*数组的相关的算法操作:1、在数组中找最大值/最小值*/class Test11_FindMax{public static void main(String[] args){int[] array = {4,2,6,8,1};//在数组中找最大...

architect刘源源
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部