曾经使用这个算法进行文章查重的应用(日常排查100w篇左右),以下只是整个计算的原理和过程,计算的效率 更多是根据编程语言和架构决定,并不是本文关注的重点。
计算原理:
布隆过滤原理,不多解释,看百科吧:http://baike.baidu.com/link?url=nAPkTtMtrb8kI-ZSare68S3SJ-p4sMs28RYerkgDzs2-0IBC4aEvMxFJQiARvj1L6DRbm5q-yr8euv2jH_P2xa
文本相似度计算:
将布隆过滤的计算原型,转换成文本相似度计算,关键在于提取文本的信息特征,形成文本的指纹,最后根据指纹的相似度进行最终的判断。
文本信息特征:提取一个信息的特征,通常是一组词或者一组词+权重,然后根据这组词调用特别的算法,例如MD5,将之转化为一组代码,这组代码就成为标识这个信息的指纹。
计算过程:
- 初始一个N长度的二进制数R,所有值均为0;
- 标点符号、停用词过滤;
- 统计文章的TF-IDF;
- 每个词语生成N长度的二进制哈希值(md5、sha1);
- 若该词第i位二进制数为1,则Ri+=Wi(其中Wi为该词的TF*IDF值),若该词第i位二进制数为0,则Ri-=Wi
- 遍历所有词语后,得到新的二进制数R’
- 遍历该二进制数R’,若第i位的值>0,则记为1,其余记为0;
- 遍历完该二进制数R’后,最终得到文本的信息指纹(N位的位二进制数)
适用场景:
文本相似度的判断
测试效率(PHP脚本):
160位指纹:≈7.7万/s 128位指纹:≈8.0万/s 64位指纹:≈8.8万/s
小结:
1. 关键点在于文本特征的提取方法,是否足够代表一个文本所具备的特征;
2. 指纹的长度越大,理论上判断的准确率会越高,但生成指纹和计算的过程会越慢;
3. 最后是选取阀值,阀值越高,精度越高,但查全率会降低
4. 文本确定后,指纹就已经确定,可以一次性生成,并不需要重复计算(除非 相关词库有变化)
整理于2013/04