您的位置:首页 > 其它

大文本相似度比较

2013-07-17 18:19 78 查看
   这个月一直在做文本匹配研究,大到一篇文章,现在小到一个字段。处于自由散漫的探索,而且时间较短,所以可能较为肤浅,感兴趣的可以一起交流。
1.查找一篇重复文本。前一段时间做过测试,Google的SimHash算法效果还是不错的,文本长度与一篇论文长度差不多。
步骤为: a. 给整篇文档分词 term ,分词用的是IKAnalyzer。
b.计算每个分词term的MD5 哈希值。由于比较的文本长度不大,所以采用的是32位哈希。原本的MD5是直 接生成32位哈希的,16位的就是截取中间32位。代码如下:

public String Md5(String plainText ) {
		  try {
		   MessageDigest md = MessageDigest.getInstance("MD5");   
		   md.update(plainText.getBytes());
		   byte b[] = md.digest();
		   int i;
		   StringBuffer buf = new StringBuffer(""); 
		   for (int offset = 0; offset < b.length; offset++) {
		    i = b[offset];
		    if(i<0) i+= 256;
		    if(i<16)
		     buf.append("0");
		    buf.append(Integer.toHexString(i));
		   }
		  System.out.println("result(32位): " + buf.toString());//32位的加密
		  System.out.println("result(16位): " + buf.toString().substring(8,24));//16位的加密
		   
		   return buf.toString().substring(8,24);

		  } catch (NoSuchAlgorithmException e) {
		   // TODO Auto-generated catch block
		   e.printStackTrace();
		   return null;
		  }
		 }

c. SimHash计算的是全部MD5哈希的最后哈希值。算法思路是:



1,将一个f维的向量V初始化为0;f位的二进制数S初始化为0;
	2,对每一个特征:用传统的hash算法对该特征产生一个f位的签名b。对i=1到f:
    		如果b的第i位为1,则V的第i个元素加上该特征的权重;
    		否则,V的第i个元素减去该特征的权重。  
	3,如果V的第i个元素大于0,则S的第i位为1,否则为0;
	4,输出S作为签名


用一篇文档测试,Google SimHash用汉明距离度量。通常是汉明距离小于5即可认为两篇文档重复。我取为10的时候发现出现多篇文档,但是内容上却相差很大。具体的细节就不写了。

2.段落比较采用的是计算段落每个分词term的tfidf值,然后匹配。为了提高效率,我假设匹配之前已经清楚该文档所属分类。

用tfidf可以确定的找到测试文档的出处。十分准确。不像SimHash会出现不相干的文档。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: