從100萬篇文件中找出相似度較高的文件對

2021-12-30 11:40:58 字數 2257 閱讀 6135

當我們想從100萬篇文件中找出相似項較高的文件對,就需要兩兩相互比較,一共是5千億次,如果每次比較花費1微秒,那一共需要6天才能計算完,這肯定是不行的。

問題應用:

1、**查重,讀過大學的就都聽過這個詞,讓無數人崩潰的查重,就是本題的一種應用,只是將一篇和上千萬篇比較,但原理是一樣的。

2、同源文件。我們再**百度一些東西時,點開幾個頁面,可能發現很多頁面及其相似,內容甚至重複,比如csdn上的部落格就有很多是從別的地方複製過來的,各個**上的新聞等也有時候會相同或相似。如果乙個**彙總每天的新聞,那肯定是要能識別內容相似的兩篇文章,選乙個即可。

相似度定義:

jaccard相似度:集合s和t的交集與集合並集大小的比率。加入s文件有三個字母a,b,c,t文件有5個字母b,c,d,e,f,那麼s和t的相似度就是2除以6,三分之一。

問題處理

1、單個文件處理

步驟1——shingling

文件一般都很長,總不能乙個字元乙個字元的比較,最有效的解決方法就是把整個文件拆分成短字元集合(長度為k),這樣處理後如果集合中相同元素越多,那麼相似度也就越高,同時還能忽略句子順序(很多人抄**時就經常改句子順序)。

例:文件為abcdabd,選擇k=2,那字元集合就是。

當然k=2肯定是不行的,這樣集合最大才是26^2,估計任何兩個長文件都會認為相似。

具體k應該為多少呢?如果文件是郵件,那麼k=5就夠了,如果像**這樣大文件,一般k=9.

此外,文件中有很多次被稱作停用詞,像the,and,to等,一般是忽略這些詞,因為對文章主題無作用。

步驟2——雜湊

如果k=9,那麼集合最大為26^9,每個元素需要9個位元組來表示,而實際的集合大小是文件長度*9,現在我想把這多麼元素雜湊到2^32個桶中,這樣每個元素就可以用4個位元組來表示,這種做法的效果要比直接另k=4要好。原因是k=4時,實際集合中的元素最多為26^4,而且通常是20^4,因為像字母z,j的頻率出現的次數是很低的。而9個位元組的集合大小最大能達到26^9

感謝雜湊演算法一次。

步驟3——最小雜湊

即使用4個位元組的shingle,那麼每篇文件難道要儲存4倍的文件大小的資訊?本步驟的目標就是將大集合替換成小很多的「簽名」,通過計算簽名集合的相似度來估計原始集合的相似的,當用50kb的文件shingle到200kb,而最後的簽名集合只有1kb時,最終差異值可能在幾個百分點之內。

假設有m個文件集合,一共有n元素(所有集合中元素的並集,n很大),那麼集合可以用乙個n行m列來表示,當這個集合含這個元素時,對應位置為1,否則為0.

我們隨機選擇n(通常為幾百)為簽名大小,可以構建集合s的最小雜湊簽名向量[h1(r),h2(r)...hn(r)]。

步驟如下:

初始矩陣sig(大小n*m)都為正無窮,對每行r如下處理:

(1)隨機選擇n個雜湊函式,計算出h1(r)...hn(r).

(2)如果原n*m矩陣對應位置為0,什麼都不做,如果為1,那麼將sig中新的值變為hi(r)和sig中原值的最小值。

也就是通過n步迭代,把原來的n*m大小矩陣,變成n*m大小的矩陣(對於乙個文件來說,就是n變成了n)。

這種方法能估計準確有一定的理論依據,概括為:兩個集合的兩個最小雜湊值相等的概率等於這連個幾個的相似度。

再次感謝雜湊演算法。

現在文件本身不是很大,但是需要比較的文件對的數目太大。

實際中我們關注的是相似度大於某個值的文件對,這樣很多相似度較低的文件對是不需要比較的。處理方法:區域性敏感雜湊(lsh)我們對目標項進行多次雜湊處理,使得相似項會比不相似項更可能到同乙個桶中,然後只要比較同乙個桶中的文件對。雜湊到同乙個桶的非相似文件對成為偽正例,而真正相似的分到兩個桶的為偽反例,我們希望這兩個越少越好。

一種有效的方法是將上面的n*m矩陣再分為b塊,每塊是r行*m列,(n=br)。將每個r長的序列雜湊到乙個大數目範圍的桶。這樣矩陣縮小為b*m,對於兩列來說,只要有一行在乙個桶中,就是相似候選對,這種方法的準確也是很高的,關於lsh技術詳細理論分析可以檢視其他文獻。

這種lsh技術由於在過濾階段非相似的資料物件大部分被過濾掉,因而極大地縮短了查詢計算時間,提高了效率。

再次感謝雜湊。總結最後總結這種問題常用思路:

1、先選擇k,構建shingle集合,可以再通過雜湊對映成更短的桶編號。

2、計算出最小雜湊簽名。

3、應用lsh技術構建候選對。

每一步都用了雜湊演算法,複雜度一再縮小。

堆排序思想 找出100萬個資料中的前100大資料

首先在c 的檔案下新建乙個txt檔案,命名為test.txt,然後在generate random.cpp中寫如下 先讀取txt檔案中生成的100萬個隨機數,這個量是很大的 其實可以生成更多,這裡用100w為例 如果完整排序後輸出前100大,這樣非常耗時!所以選擇如下演算法 構造乙個容量為100的小...

從Kickstarter融資100萬美元的專案盤點

1 專案名稱 ogre designer s edition 投資者數目 5512 初始融資目標 20,000 融資總額 923,680 簡介 開發於1977年的 經典戰爭遊戲 2 專案名稱 hidden radio bluetooth speaker 投資者數目 5358 初始融資目標 125,0...

窮人如何致富 從1萬賺到100萬究竟需要多長時間?

物欲橫流的世界,金錢總是會讓人眼冒綠光,以金錢為標題難免有譁眾取寵之嫌,身在金融場,天天與銅臭味相伴,談金錢反而比談情說愛更讓自己舒服,所以文章滿是銅臭味,實在羞於登大雅之堂。在現實中,我發現越簡單的事實,越沒有人提,從而使得我不停地繞彎路,而這些事實都可以用最簡單的數學來表達,今天也不例外。利潤率...