Toy程序中很重要的一个功能是去重:即去掉那种转载流的文字,转载扩赛了信息但是也造成了相当麻烦的信息冗余,我不想看的信息逼着我看了一遍又一遍。
最牛逼的方法当然是能比较两个文章的全文,看全文的匹配度了,但是这个方法的时间代价太大。还有那种选取一部分Digest 出来比较的方法理论性远远大于使用性。最直接的方法就是看两个文章的标题的最长公共子串,亦即LCS( longest common substring).

LCS的原理非常的简单:

A串为:   A1 A2 A3 .....  An
B串为: B1 B2 B3 .....  Bm

只要反复的算下AB以各种位置叠在一起的最长连续字符个数就好了

数学上来说:就是写成这样一个矩阵:
match[n][m]=

  A1 A2 ..... ..... Am
B1 01 01 ... ... 01
B2 01 01 ... ... 01
... ... ... ... ... ...
Bn 01 01 ... ... 01

中间的值match[i][j]都是0或者1 (match[i][j]=1 means Bi=Aj),下面就在这个表中选出最长的连续对角线都是1的串,对应的子串就是AB的最大的匹配。

举个例子吧:

from:  http://www.5do8.com/blog/doc/569/index.aspx

  A= I MISS MY CODE HI

  B= One Like MY Code

  i m i s s m y c o d e h i
o 0 0 0 0 0 0 0 0 1 0 0 0 0
n 0 0 0 0 0 0 0 0 0 0 0 0 0
e 0 0 0 0 0 0 0 0 0 0 1 0 0
l 0 0 0 0 0 0 0 0 0 0 0 0 0
i 1 0 1 0 0 0 0 0 0 0 0 0 1
k 0 0 0 0 0 0 0 0 0 0 0 0 0
e 0 0 0 0 0 0 0 0 0 0 1 0 0
m 0 1 0 0 0 1 0 0 0 0 0 0 0
y 0 0 0 0 0 0 1 0 0 0 0 0 0
c 0 0 0 0 0 0 0 1 0 0 0 0 0
o 0 0 0 0 0 0 0 0 1 0 0 0 0
d 0 0 0 0 0 0 0 0 0 1 0 0 0
e 0 0 0 0 0 0 0 0 0 0 1 0 0

那个mycode就是最长匹配的串
在具体计算的时候考虑到汉字字符的多变性和英文很不一样,我们可以直接计算一个对角线上的所有的1而不用考虑联系性。
就变成了MCC(Max common characters)了,而这个MCC就是我们去判定重复的一个重要依据。
如果len(MCC) / min( len(string_A) ,len(string_B))>valve_Value就判定为转载。
-----------------------
这里可以有一个非常重要的改进,认为连续匹配会有非线性加成,如match_degree=sigma( len(common_substring[i])^2)
甚至我觉得可能某些搜索引擎就是这么干的。。【未验证】

----------------------
这样就实现了新闻的唯一性的保证,为了确保系统的效率不会被这个比较拖累的太多,可以只比较最近3个月的标题。

晚上写一个实现,能配合现在已经有的模块实现标题的唯一性。




Comments

Good.Be the first to comment on this entry.

Post comment

comment has COPYRIGHT too!

Note: Commenter is allowed to use '@User+blank' to automatically notify your reply to other commenter. e.g, if ABC is one of commenter of this post, then write '@ABC '(exclude ') will automatically send your comment to ABC. Using '@all ' to notify all previous commenters. Be sure that the value of User should exactly match with commenter's name (case sensitive).