2011-07-13 45 views
41

我試圖清理一個數據庫,這些年來,已經獲得了許多重複記錄,名稱略有不同。例如,在公司表中,有「Some Company Limited」和「Some Company LTD!」等名稱。找到接近重複記錄的技巧

我的計劃是將違規表導出爲R,將名稱轉換爲小寫,替換常見同義詞(如「limited」 - >「ltd」),去掉非字母字符,然後使用agrep來查看外觀類似。

我的第一個問題是agrep只接受匹配的單個模式,並且循環每個公司名稱以匹配其他公司名稱很慢。 (要清洗一些表將有幾十,甚至幾百個幾千名的檢查。)

我很簡單的看了看tm包(JSS article),而且看起來很強大,但對分析的大塊減速文字,而不僅僅是名字。

我有幾個相關的問題:

  1. tm包適合這種任務的?

  2. 有沒有更快的選擇agrep? (該函數使用 的Levenshtein編輯距離是閒談慢。)

  3. agreptm是否有R以外的合適的工具,除了?

  4. 我應該甚至在R這麼做,或者應該直接在數據庫中做這種事情嗎? ? (這是一個Access數據庫,所以我最好 而儘可能避免觸碰它。)

+5

相關[如何測量字符串之間的相似性?] (http://stackoverflow.com/questions/6044112/r-how-to-measure-similarity-between-strings) –

回答

29

如果你只是在做小批量相對形成清楚,然後在RecordLinkage packagecompare.linkage()compare.dedup()功能應該是一個很好的起點。但是如果你有大批量的產品,那麼你可能需要做更多的修補。

我使用的功能jarowinkler()levenshteinSim(),並在RecordLinkagesoundex()寫我自己的函數,用我自己的權重方案(也,不如說是,你不能對大數據集使用soundex()RecordLinkage)。

如果我有兩個我想匹配的名稱列表(「記錄鏈接」),那麼我通常會將它們都轉換爲小寫字母並刪除所有標點符號。爲了照顧「有限」而不是「有限公司」,我通常從每個列表創建第一個單詞的另一個向量,這允許對第一個單詞進行額外的加權。如果我認爲一個列表可能包含首字母縮略詞(可能是ATT或IBM),那麼我將首字母縮寫爲另一個列表。對於每個列表,我最終都會得到一個字符串數據框,我想比較一下,我將它們作爲單獨的表格寫入MySQL數據庫中。

所以,我不太多考生結束了,我LEFT OUTER JOIN的東西,到兩個列表之間的匹配(也許這是每個列表中的前三個字母或前三這兩個表首字母縮寫中的前三個字母)。然後我使用上述函數計算比賽分數。

您仍然需要進行大量的人工檢查,但您可以根據分數進行排序以快速排除不匹配。

+4

+1解釋如何正常化文本。所有經常被忽視的「第一步」。 tolower(),gsub()。我通過查看摘要(as.factor(my_vector))並查看不匹配的內容來做類似的事情。有時它非常簡單,寫出線條可能比嘗試使用正則表達式更清晰。 –

+2

@AndrewMedico是的,它看起來像包在CRAN中不再有效。您可以從檔案中獲得過去的版本。我有義務成爲軟件包維護人員嗎? –

+0

@RichardHerron感謝指向這些軟件包,它現在在CRAN上。如果我只有數字列,並且它們隨機波動不同,並且我希望在數字數據中找到匹配項,您是否有要做的事情? – Richard

9

也許google refine可以提供幫助。如果你有很多例外,而且你還不知道它們,它看起來可能更合適。

+0

感謝您指出該工具。看起來非常有用! –

+0

我還沒有使用谷歌提煉,但我對這些視頻印象深刻。它似乎擅長處理模糊匹配,並且最重要的是,似乎可以保存下位代碼,以便在需要時再次運行它,或者如果希望對類似數據運行相同的算法。 – Farrel

5

你正在做的事情叫做record linkage,它已經是數十年來一個巨大的研究領域了。幸運的是,有一大堆工具可以爲這類事情做好準備。基本上,你可以將它們指向你的數據庫,設置一些清理和比較(比如Levenshtein或者Jaro-Winkler或者......),然後他們會離開併爲你完成這項工作。

這些工具通常具有解決性能問題的功能,因此儘管Levenshtein速度較慢,但​​它們可以快速運行,因爲大多數記錄對根本不會進行比較。

上面的維基百科鏈接有許多可以使用的記錄鏈接工具的鏈接。我親自編寫了一個名爲Duke的Java,我已經成功地使用了它。如果你想要一些大而昂貴的東西,你可以購買主數據管理工具。