关于SimHash算法的实现及测试V1.0
@祁俊辉,2017年5月21日测试。
1 说明
- 本程序是简化版的SimHash算法(分词暂为手动分词,每个词的权重都设为1);
- 本程序是基于《数学之美 》第二版第16章所介绍的原理展开;
- 本篇文章将计算多个字符串的SimHash值,并将对其分析;
- 本篇文章暂不介绍SimHash算法的原理,因为网上的资源相对较杂,待我彻底理解,整理过后更新(已在笔记本中);
- 本篇文章(程序)将持续更新。
2 程序(32位)
关于程序的解释,都在程序源码中有相应的注释。若有不明白之处,请联系本人:qce.hui@qq.com。
1/* 【算法】SimHash->32位 2 * 【说明】1.本程序手动分词,假设每个词的权重都为1 3 * 【说明】2.对每个词进行BKDRHash算法,在此基础上加减权重 4 * 【说明】3.将所有词整合后,降维 5 * 【说明】4.计算各个句子的海明距离 6 * 【时间】祁俊辉->2017.5.19 7 * */ 8publicclass SimHash_32 {
9//定义待比较的字符串
10static String s1="SimHash/算法/的/研究";
11static String s2="SimHash/算法/的/探讨";
12static String s3="SimHash/研究/的/算法";
13static String s4="SimHash/是/一种/文本/相似性/算法";
14//定义待比较的字符串
15static String s5="电视剧/小时代/由/郭敬明/的/同名/小说/改编/而/成/故事/以/经济/飞速/发展/的/上海/这/座/风光/而/时尚/的/城市/为/背景/讲述/了/林萧/南湘/顾里/唐宛如/这/四/个/从小/感情/深厚/有着/不同/价值观/和/人生观/的/女生/先后/所/经历/的/友情/爱情/乃至/亲情/的/巨大/转变/是/一/部/当下/年轻人/生活/一个/侧面/的/真实/写照";
16static String s6="电视剧/大时代/由/郭敬明/的/同名/小说/改编/而/成/该剧情/以/经济/飞速/发展/的/大上海/这/座/风光/而/时尚/的/城市/为/背景/讲述/了/林萧/南湘/顾里/唐宛如/这/四/个/从小/感情/深厚/有着/不同/价值观/和/人生观/的/女生/先后/所/经历/的/友情/爱情/乃至/亲情/的/巨大/转变/是/一/部/当下/年轻人/生活/一个/侧面/的/真实/写照";
17//定义待比较的字符串
18static String s7="你/妈妈/喊/你/回家/吃饭/哦/回家/喽/回家/喽";
19static String s8="你/妈妈/叫/你/回家/吃饭/哦/回家/喽/回家/喽";
20/* 函数名:BKDR_Hash(String str)
21 * 功能:计算字符串str的32位hash值,并将其以int型返回
22 * */
23staticint BKDR_Hash(String str){
24int seed=131;
25int hash=0;
26for(int i=0;i<str.length();i++){
27 hash=hash*seed+str.charAt(i);
28//System.out.println(hash);
29 }
30return (hash & 0x7FFFFFFF);//32位
31//return (hash & 0x7FFFFFFFFFFFFFFFL);//64位
32 }
33/* 函数名:First_FC(String str)
34 * 功能:1.先创建一个存储SimHash值的32数组,并初始化为0
35 * 功能:2.将str字符串分词,并存入临时数组
36 * 功能:3.计算此字符串的SimHash值(加权、但没有降维),存储在数组中
37 * 功能:4.将数组中的SimHash值降维,并以字符串形式返回
38 * */
39static String First_FC(String str){
40//1.先创建一个存储SimHash值的32数组,并初始化为0
41int Hash_SZ[] = newint[32];
42for(int i=0;i<Hash_SZ.length;i++)
43 Hash_SZ[i]=0;
44//2.将str字符串分词,并存入临时数组
45 String[] newstr = str.split("/");
46//下面的for循环是为了增加前后文关联性//即12/23/34/45···
47/*for(int i=0;i<newstr.length-1;i++){
48 newstr[i]=newstr[i]+newstr[i+1];
49 }*/
50//相应的,若增加上面的关联性语句,下面一行的代码要改为
51//for(int i=0;i<newstr.length-1;i++){
52//3.计算此字符串的SimHash值(加权、但没有降维),存储在数组中
53for(int i=0;i<newstr.length;i++){//循环传入字符串的每个词
54int str_hash=BKDR_Hash(newstr[i]);//先计算每一个词的Hash值(32位)
55//System.out.println(Integer.toBinaryString(str_hash));
56//对每个词的Hash值(32位)求j位是1还是0,1的话加上该词的权重,0的话减去该词的权重
57for(int j=0;j<Hash_SZ.length;j++){
58int flag = (str_hash>>j)&1;//不要忘记上面计算的值是十进制,并不能直接知道j位是多少
59//System.out.println(flag);
60if(1 == flag){
61 Hash_SZ[j]++;//权重先设置为1//Hash_SZ中,0是最低位,依次排高
62 }else{
63 Hash_SZ[j]--;
64 }
65 }
66 }
67//4.将数组中的SimHash值降维,并以字符串形式返回
68 String SimHash_number="";//存储SimHash值
69for(int i=Hash_SZ.length-1;i>=0;i--){//从高位到低位
70 System.out.print(Hash_SZ[i]+" ");//输出未降维的串
71if(Hash_SZ[i]<=0)//小于等于0,就取0
72 SimHash_number += "0";
73else//大于0,就取1
74 SimHash_number += "1";
75 }
76 System.out.println("");//换行
77return SimHash_number;
78 }
79/* 函数名:HMJL(String a,String b)
80 * 功能:a、b都是以String存储的二进制数,计算他们的海明距离,并将其返回
81 * */
82staticint HMJL(String a,String b){
83char[] FW1 = a.toCharArray();//将a每一位都存入数组中
84char[] FW2 = b.toCharArray();//将b每一位都存入数组中
85int haiming=0;
86if(FW1.length == FW2.length){//确保a和b的位数是相同的
87for(int i=0;i<FW1.length;i++){
88if(FW1[i] != FW2[i])//如果该位不同,海明距离加1
89 haiming++;
90 }
91 }
92return haiming;
93 }
94
95publicstaticvoid main(String[] args) {
96 String a1 = First_FC(s1);
97 String a2 = First_FC(s2);
98 String a3 = First_FC(s3);
99 String a4 = First_FC(s4);
100 System.out.println("【s1】的SimHash值为:"+a1);
101 System.out.println("【s2】的SimHash值为:"+a2);
102 System.out.println("【s3】的SimHash值为:"+a3);
103 System.out.println("【s4】的SimHash值为:"+a4);
104 System.out.println("【s1】和【s2】的海明距离为:"+HMJL(a1,a2));
105 System.out.println("【s1】和【s3】的海明距离为:"+HMJL(a1,a3));
106 System.out.println("【s1】和【s4】的海明距离为:"+HMJL(a1,a4));
107 System.out.println("【s2】和【s3】的海明距离为:"+HMJL(a2,a3));
108 System.out.println("【s2】和【s4】的海明距离为:"+HMJL(a2,a4));
109 System.out.println("【s3】和【s4】的海明距离为:"+HMJL(a3,a4));
110
111 String a5 = First_FC(s5);
112 String a6 = First_FC(s6);
113 String a7 = First_FC(s7);
114 String a8 = First_FC(s8);
115 System.out.println("【s5】的SimHash值为:"+a5);
116 System.out.println("【s6】的SimHash值为:"+a6);
117 System.out.println("【s7】的SimHash值为:"+a7);
118 System.out.println("【s8】的SimHash值为:"+a8);
119 System.out.println("【s5】和【s6】的海明距离为:"+HMJL(a5,a6));
120 System.out.println("【s5】和【s7】的海明距离为:"+HMJL(a5,a7));
121 System.out.println("【s5】和【s8】的海明距离为:"+HMJL(a5,a8));
122 System.out.println("【s6】和【s7】的海明距离为:"+HMJL(a6,a7));
123 System.out.println("【s6】和【s8】的海明距离为:"+HMJL(a6,a8));
124 System.out.println("【s7】和【s8】的海明距离为:"+HMJL(a7,a8));
125 }
126 }
3 测试结果
3.1 第一个测试A1
测试时使用短字符串,对每个词使用的是32位BKDRHash算法,此次测试并未考虑上下文相关性,四个字符串分别为:
- S1:SimHash/算法/的/研究
- S2:SimHash/算法/的/探讨
- S3:SimHash/研究/的/算法
- S4:SimHash/是/一种/文本/相似性/算法
未降维时四个字符串的SimHash值为:
降维后的SimHash值为:
计算各个字符串之间的海明距离:
从上可以看出,S1和S3之间的海明距离竟然为0,这是因为并未考虑上下文相关性,而S1和S3是相同的内容,但顺序不同。
另外,看似最相似的S1和S2之间的海明距离为4(因为这两个字符串只有最后两个字不一样)。
最后,S1、S2、S3都与S4之间的海明距离较大(比其他各个之间的大),这一点还蛮准确。
3.2 第二个测试A2
测试时使用短字符串,对每个词使用的是32位BKDRHash算法,此次测试考虑上下文相关性(主要是与第一个测试A1做对比),四个字符串分别为:
- S1:SimHash/算法/的/研究
- S2:SimHash/算法/的/探讨
- S3:SimHash/研究/的/算法
- S4:SimHash/是/一种/文本/相似性/算法
注:“考虑上下文相关性”,即比如S1字符串,将其分解为:“SimHash算法”、“算法的”、“的研究”。
未降维时四个字符串的SimHash值为:
降维后的SimHash值为:
计算各个字符串之间的海明距离:
从上可以看出,在这次测试的结果中,S1和S2之间的的海明距离最小(为6),也就是这两个字符串最为相似,这与预料中的是一样的。
另外,因为考虑到上下文相关性,S1和S3之间的海明距离也不再是0,说明这两个字符串之间还是有差别的。
最后,S1、S2、S3都与S4之间的海明距离较大(比其他各个之间的大),这一点相对于第一个测试A1更为明显。
3.3 第三个测试A3
测试时使用中等长度字符串,对每个词使用的是32位BKDRHash算法,此次测试并未考虑上下文相关性,四个字符串分别为:
- S5:电视剧/小时代/由/郭敬明/的/同名/小说/改编/而/成/故事/以/经济/飞速/发展/的/上海/这/座/风光/而/时尚/的/城市/为/背景/讲述/了/林萧/南湘/顾里/唐宛如/这/四/个/从小/感情/深厚/有着/不同/价值观/和/人生观/的/女生/先后/所/经历/的/友情/爱情/乃至/亲情/的/巨大/转变/是/一/部/当下/年轻人/生活/一个/侧面/的/真实/写照
- S6:电视剧/大时代/由/郭敬明/的/同名/小说/改编/而/成/该剧情/以/经济/飞速/发展/的/大上海/这/座/风光/而/时尚/的/城市/为/背景/讲述/了/林萧/南湘/顾里/唐宛如/这/四/个/从小/感情/深厚/有着/不同/价值观/和/人生观/的/女生/先后/所/经历/的/友情/爱情/乃至/亲情/的/巨大/转变/是/一/部/当下/年轻人/生活/一个/侧面/的/真实/写照
- S7:你/妈妈/喊/你/回家/吃饭/哦/回家/喽/回家/喽
- S8:你/妈妈/叫/你/回家/吃饭/哦/回家/喽/回家/喽
未降维时四个字符串的SimHash值为(太长,截取了一部分):
降维后的SimHash值为:
计算各个字符串之间的海明距离:
从上可以看出,在这次测试的结果中,因为S5和S6本就是相似的(两个词不同),S7和S8本就是相似的(一个词不同),检测结果显示S5和S6、S7和S8之间的海明距离都非常小(1和0),而其他情况的海明距离就相对比较大了(因为根本很明显不是相似的),这与预期是相同的。
3.4 第四个测试A4
测试时使用中等长度字符串,对每个词使用的是32位BKDRHash算法,此次测试考虑上下文相关性(主要是与第三个测试A3做对比),四个字符串分别为:
- S5:电视剧/小时代/由/郭敬明/的/同名/小说/改编/而/成/故事/以/经济/飞速/发展/的/上海/这/座/风光/而/时尚/的/城市/为/背景/讲述/了/林萧/南湘/顾里/唐宛如/这/四/个/从小/感情/深厚/有着/不同/价值观/和/人生观/的/女生/先后/所/经历/的/友情/爱情/乃至/亲情/的/巨大/转变/是/一/部/当下/年轻人/生活/一个/侧面/的/真实/写照
- S6:电视剧/大时代/由/郭敬明/的/同名/小说/改编/而/成/该剧情/以/经济/飞速/发展/的/大上海/这/座/风光/而/时尚/的/城市/为/背景/讲述/了/林萧/南湘/顾里/唐宛如/这/四/个/从小/感情/深厚/有着/不同/价值观/和/人生观/的/女生/先后/所/经历/的/友情/爱情/乃至/亲情/的/巨大/转变/是/一/部/当下/年轻人/生活/一个/侧面/的/真实/写照
- S7:你/妈妈/喊/你/回家/吃饭/哦/回家/喽/回家/喽
- S8:你/妈妈/叫/你/回家/吃饭/哦/回家/喽/回家/喽
未降维时四个字符串的SimHash值为(太长,截取了一部分):
降维后的SimHash值为:
计算各个字符串之间的海明距离:
从上可以看出,在这次测试的结果中,因为S5和S6本就是相似的(两个词不同),S7和S8本就是相似的(一个词不同),检测结果显示S5和S6、S7和S8之间的海明距离都非常小(1和0),而其他情况的海明距离就相对比较大了(因为根本很明显不是相似的),这与预期是相同的。
另外,与第三次测试A3相比较,这次的结果与上次基本相同(相似的海明距离小,不相似的海明距离大),只是海明距离数值有差别而已。
3.5 第五个测试A5
以上四个测试(A1~A4)中,对每个词使用的都是32位BKDRHash算法,至于这一块需要使用哪一种Hash转换算法,在我查找的资料中并没有给出明确表示,只有在一篇文章中说“使用传统的Hash算法”,下面对这一块做测试,将分别使用RSHash、BKDRHash、DJBHash、JSHash和SDBMHash。
本次测试以第一个测试A1为基准,测试时使用短字符串,对每个词分别使用32位的RSHash、BKDRHash、DJBHash、JSHash和SDBMHash(至于这几种Hash算法,请参考我的另一篇文章《关于Hash的几种常用算法》),此次测试并未考虑上下文相关性,四个字符串分别为:
- S1:SimHash/算法/的/研究
- S2:SimHash/算法/的/探讨
- S3:SimHash/研究/的/算法
- S4:SimHash/是/一种/文本/相似性/算法
本次测试将只看以上四个字符串的SimHash值(降维后)和各个字符串之间的海明距离:
RSHash
BKDRHash
DJBHash
JSHash
SDBMHash
此次测试总结:之前我以为,不管使用哪种Hash算法对词转换,最后得到的字符串之间海明距离是由规律的(比如最小的还是最小,最大的还是最大),可事实证明,然后并没有。
3.6 第六个测试A6
在第五个测试A5中,并未考虑上下文相关性,本次测试考虑上下文相关性,再次对5钟Hash算法进行比较。
本次测试以第一个测试A1为基准,测试时使用短字符串,对每个词分别使用32位的RSHash、BKDRHash、DJBHash、JSHash和SDBMHash(至于这几种Hash算法,请参考我的另一篇文章《关于Hash的几种常用算法》),此次测试考虑上下文相关性(主要是与第五个测试A5做对比),四个字符串分别为:
- S1:SimHash/算法/的/研究
- S2:SimHash/算法/的/探讨
- S3:SimHash/研究/的/算法
- S4:SimHash/是/一种/文本/相似性/算法
本次测试将只看以上四个字符串的SimHash值(降维后)和各个字符串之间的海明距离:
RSHash
BKDRHash
DJBHash
JSHash
SDBMHash
此次测试总结:此次测试结合第五次测试A5,几乎证明了在对文本进行SimHash时,对每个词Hash转换所使用的Hash算法还是对结果会产生较大影响的,但至于使用哪一种Hash算法更准确,我目前还不太清楚。
3.7 第七个测试A7
从前几次测试中,不知读者是否发现一个现象:在不考虑文本上下文相关性的前提下(文本相同),计算得到的SimHash值较小;考虑文本上下文相关性后(文本相同),计算得到的SimHash值相对较大。这与所使用的Hash函数有直接的关系,但是还有一个因素->每个词的长度。
当对每个词进行Hash函数转换时,大多数Hash函数是根据词的长度进行循环累乘的,所以考虑文本上下文相关性后,词的长度变长了,计算所得的Hash值固然就变长了,进而也就影响了SimHash值的长度(所有词的Hash累加)。
以上分析都是在相同文本下两种情况所产生的SimHash长度,当然,SimHash长度主要还与文本的长度有关,在进行大文本处理时,累加所产生的长度变化也是要考虑的。下面一段程序是基于第一次测试A1扩展成的64位SimHash算法,但是前面那么多位的“0”好像并没有太大意义哦。
注:怎么产生64位呢?其实就是“int”和“long”的差别,在对每个词进行Hash函数转换时,所使用的数值类型不同而已。
1/* 【算法】SimHash->64位 2 * 【说明】1.本程序手动分词,假设每个词的权重都为1 3 * 【说明】2.对每个词进行BKDRHash算法,在此基础上加减权重 4 * 【说明】3.将所有词整合后,降维 5 * 【说明】4.计算各个句子的海明距离 6 * 【时间】祁俊辉->2017.5.20 7 * */ 8publicclass SimHash_64 {
9//定义待比较的字符串
10static String s1="SimHash/算法/的/研究";
11static String s2="SimHash/算法/的/探讨";
12static String s3="SimHash/研究/的/算法";
13static String s4="SimHash/是/一种/文本/相似性/算法";
14//定义待比较的字符串
15static String s5="电视剧/小时代/由/郭敬明/的/同名/小说/改编/而/成/故事/以/经济/飞速/发展/的/上海/这/座/风光/而/时尚/的/城市/为/背景/讲述/了/林萧/南湘/顾里/唐宛如/这/四/个/从小/感情/深厚/有着/不同/价值观/和/人生观/的/女生/先后/所/经历/的/友情/爱情/乃至/亲情/的/巨大/转变/是/一/部/当下/年轻人/生活/一个/侧面/的/真实/写照";
16static String s6="电视剧/大时代/由/郭敬明/的/同名/小说/改编/而/成/该剧情/以/经济/飞速/发展/的/大上海/这/座/风光/而/时尚/的/城市/为/背景/讲述/了/林萧/南湘/顾里/唐宛如/这/四/个/从小/感情/深厚/有着/不同/价值观/和/人生观/的/女生/先后/所/经历/的/友情/爱情/乃至/亲情/的/巨大/转变/是/一/部/当下/年轻人/生活/一个/侧面/的/真实/写照";
17//定义待比较的字符串
18static String s7="你/妈妈/喊/你/回家/吃饭/哦/回家/喽/回家/喽";
19static String s8="你/妈妈/叫/你/回家/吃饭/哦/回家/喽/回家/喽";
20/* 函数名:BKDR_Hash(String str)
21 * 功能:计算字符串str的64位hash值,并将其以int型返回
22 * */
23staticlong BKDR_Hash(String str){
24int seed=131;//数乘因子
25long hash=0;
26for(int i=0;i<str.length();i++){
27 hash=hash*seed+str.charAt(i);
28//System.out.println(hash);
29 }
30//return (hash & 0x7FFFFFFF);//32位
31return (hash & 0x7FFFFFFFFFFFFFFFL);//64位
32 }
33/* 函数名:First_FC(String str)
34 * 功能:1.先创建一个存储SimHash值的64数组,并初始化为0
35 * 功能:2.将str字符串分词,并存入临时数组
36 * 功能:3.计算此字符串的SimHash值(加权、但没有降维),存储在数组中
37 * 功能:4.将数组中的SimHash值降维,并以字符串形式返回
38 * */
39static String First_FC(String str){
40//1.先创建一个存储SimHash值的64数组,并初始化为0
41int Hash_SZ[] = newint[64];
42for(int i=0;i<Hash_SZ.length;i++)
43 Hash_SZ[i]=0;
44//2.将str字符串分词,并存入临时数组
45 String[] newstr = str.split("/");
46//下面的for循环是为了增加前后文关联性//即12/23/34/45···
47/*for(int i=0;i<newstr.length-1;i++){
48 newstr[i]=newstr[i]+newstr[i+1];
49 }*/
50//相应的,若增加上面的关联性语句,下面一行的代码要改为
51//for(int i=0;i<newstr.length-1;i++){
52//3.计算此字符串的SimHash值(加权、但没有降维),存储在数组中
53for(int i=0;i<newstr.length;i++){//循环传入字符串的每个词
54long str_hash=BKDR_Hash(newstr[i]);//先计算每一个词的Hash值(64位)
55//System.out.println(Integer.toBinaryString(str_hash));
56//对每个词的Hash值(32位)求j位是1还是0,1的话加上该词的权重,0的话减去该词的权重
57for(int j=0;j<Hash_SZ.length;j++){
58long flag = (str_hash>>j)&1;//不要忘记上面计算的值是十进制,并不能直接知道j位是多少
59//System.out.println(flag);
60if(1 == flag){
61 Hash_SZ[j]++;//权重先设置为1//Hash_SZ中,0是最低位,依次排高
62 }else{
63 Hash_SZ[j]--;
64 }
65 }
66 }
67//4.将数组中的SimHash值降维,并以字符串形式返回
68 String SimHash_number="";//存储SimHash值
69for(int i=Hash_SZ.length-1;i>=0;i--){//从高位到低位
70 System.out.print(Hash_SZ[i]+" ");//输出未降维的串
71if(Hash_SZ[i]<=0)//小于等于0,就取0
72 SimHash_number += "0";
73else//大于0,就取1
74 SimHash_number += "1";
75 }
76 System.out.println("");//换行
77return SimHash_number;
78 }
79/* 函数名:HMJL(String a,String b)
80 * 功能:a、b都是以String存储的二进制数,计算他们的海明距离,并将其返回
81 * */
82staticint HMJL(String a,String b){
83char[] FW1 = a.toCharArray();//将a每一位都存入数组中
84char[] FW2 = b.toCharArray();//将b每一位都存入数组中
85int haiming=0;
86if(FW1.length == FW2.length){//确保a和b的位数是相同的
87for(int i=0;i<FW1.length;i++){
88if(FW1[i] != FW2[i])//如果该位不同,海明距离加1
89 haiming++;
90 }
91 }
92return haiming;
93 }
94
95publicstaticvoid main(String[] args) {
96 String a1 = First_FC(s1);
97 String a2 = First_FC(s2);
98 String a3 = First_FC(s3);
99 String a4 = First_FC(s4);
100 System.out.println("【s1】的SimHash值为:"+a1);
101 System.out.println("【s2】的SimHash值为:"+a2);
102 System.out.println("【s3】的SimHash值为:"+a3);
103 System.out.println("【s4】的SimHash值为:"+a4);
104 System.out.println("【s1】和【s2】的海明距离为:"+HMJL(a1,a2));
105 System.out.println("【s1】和【s3】的海明距离为:"+HMJL(a1,a3));
106 System.out.println("【s1】和【s4】的海明距离为:"+HMJL(a1,a4));
107 System.out.println("【s2】和【s3】的海明距离为:"+HMJL(a2,a3));
108 System.out.println("【s2】和【s4】的海明距离为:"+HMJL(a2,a4));
109 System.out.println("【s3】和【s4】的海明距离为:"+HMJL(a3,a4));
110
111 String a5 = First_FC(s5);
112 String a6 = First_FC(s6);
113 String a7 = First_FC(s7);
114 String a8 = First_FC(s8);
115 System.out.println("【s5】的SimHash值为:"+a5);
116 System.out.println("【s6】的SimHash值为:"+a6);
117 System.out.println("【s7】的SimHash值为:"+a7);
118 System.out.println("【s8】的SimHash值为:"+a8);
119 System.out.println("【s5】和【s6】的海明距离为:"+HMJL(a5,a6));
120 System.out.println("【s5】和【s7】的海明距离为:"+HMJL(a5,a7));
121 System.out.println("【s5】和【s8】的海明距离为:"+HMJL(a5,a8));
122 System.out.println("【s6】和【s7】的海明距离为:"+HMJL(a6,a7));
123 System.out.println("【s6】和【s8】的海明距离为:"+HMJL(a6,a8));
124 System.out.println("【s7】和【s8】的海明距离为:"+HMJL(a7,a8));
125 }
126 }
依然测试时使用短字符串,对每个词使用的是64位BKDRHash算法,此次测试并未考虑上下文相关性,四个字符串分别为:
- S1:SimHash/算法/的/研究
- S2:SimHash/算法/的/探讨
- S3:SimHash/研究/的/算法
- S4:SimHash/是/一种/文本/相似性/算法
未降维时四个字符串的SimHash值为(太长,截取了一部分):
降维后的SimHash值为:
计算各个字符串之间的海明距离:
从上可以看出,与第一次测试A1所产生的结果完全相同,无非就是前面加了几个“0”而已。
可以得出:在进行短文本计算时,完全没必要使用64位的SimHash算法。
以上是 关于SimHash算法的实现及测试V1.0 的全部内容, 来源链接: utcz.com/z/509912.html