关于SimHash算法的实现及测试V1.0

coding

@祁俊辉,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

回到顶部