文档章节

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

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

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




© 著作权归作者所有

杨尚川

杨尚川

粉丝 1103
博文 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
1K
1
Word2vector句子相似度计算

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

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

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

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

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

腾讯云加社区
02/27
724
0
Java分布式中文分词组件--word

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

杨尚川
2014/04/26
8.4K
1

没有更多内容

加载失败,请刷新页面

加载更多

SSH安全加强两步走

从 OpenSSH 6.2 开始已经支持 SSH 多因素认证,本文就来讲讲如何在 OpenSSH 下启用该特性。 OpenSSH 6.2 以后的版本多了一个配置项 AuthenticationMethods。该配置项可以让 OpenSSH 同时指定...

xiangyunyan
27分钟前
4
0
C或C++不是C/C++

http://www.voidcn.com/article/p-mucdruqa-ws.html

shzwork
今天
6
0
OSChina 周六乱弹 —— 如何将梳子卖给和尚

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @for_ :划水五分钟,专注两小时。分享Various Artists的单曲《贝多芬第8号钢琴奏鸣曲悲伤的第三乐章》: 《贝多芬第8号钢琴奏鸣曲悲伤的第三乐...

小小编辑
今天
179
8
ES5

什么是ES5:比普通js运行要求更加严格的模式 为什么:js语言本身有很多广受诟病的缺陷 如何:在当前作用域的顶部添加:"use strict" 要求: 1、禁止给未声明的变量赋值 2、静默失败升级为错误...

wytao1995
今天
7
0
c++ 内联函数调用快的原因

见图片分析

天王盖地虎626
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部