2011-11-22 22 views
3

我正試圖找到一種可靠的方法來匹配數據庫中的重複人員記錄。這些數據有一些嚴重的數據質量問題,我也試圖解決這個問題,但是直到我有這樣的努力,我才堅持使用我得到的數據。使用Soundex,Jaro Winkler和編輯距離匹配Oracle重複列值(UTL_MATCH)

提供給我的表列是:

SURNAME  VARCHAR2(43) 
FORENAME  VARCHAR2(38) 
BIRTH_DATE DATE 
ADDRESS_LINE1 VARCHAR2(60) 
ADDRESS_LINE2 VARCHAR2(60) 
ADDRESS_LINE3 VARCHAR2(60) 
ADDRESS_LINE4 VARCHAR2(60) 
ADDRESS_LINE5 VARCHAR2(60) 
POSTCODE  VARCHAR2(15) 

SOUNDEX功能是用於此用途相對有限,但UTL_MATCH包似乎提供了使用哈羅溫克算法匹配的較好水平。

沒有重新發明輪子,有沒有人實現了匹配這種類型的數據的可靠方法?

數據質量問題與之抗衡:

  1. 郵政編碼,雖然強制性的,並不總是完全進入。
  2. 地址數據的質量相對較差,輸入的地址不是固定格式(即有些可能會將line1視爲「平面1」,而有些可能會將line1視爲「Flat1,22 Acacia Ave」)。
  3. forename列可以包含一個初始名稱,一個完整的名稱或者有時包含多個名字。

比如我正在考慮:

連接所有地址字段和應用哈羅溫克勒算法的詳細地址與連接在一起的全名的一個類似的試驗相結合。

出生日期可以直接比較匹配,但由於大量的數據只是匹配這是不夠的。

Oracle 10g R2企業版。

歡迎任何有幫助的建議。

+0

當您在標題中說「重複列值」時,您實際上表示「相似」或「幾乎相同」。 – APC

+0

是的,我認爲「重複」在邏輯上是不正確的,他們是同一個人,但數據不是完全匹配。 – Ollie

回答

6

「我試圖找到一種可靠的方法來匹配數據庫中的重複記錄 記錄。」

唉,沒有這樣的事情。你所希望的最多的是一個具有合理元素的懷疑係統。

SQL> select n1 
     , n2 
     , soundex(n1) as sdx_n1 
     , soundex(n2) as sdx_n2 
     , utl_match.edit_distance_similarity(n1, n2) as ed 
     , utl_match.jaro_winkler_similarity(n1, n2) as jw 
from t94 
order by n1, n2 
/


    2 3 4 5 6 7 8 9 
N1     N2     SDX_ SDX_   ED   JW 
-------------------- -------------------- ---- ---- ---------- ---------- 
MARK     MARKIE    M620 M620   67   93 
MARK     MARKS    M620 M620   80   96 
MARK     MARKUS    M620 M622   67   93 
MARKY    MARKIE    M620 M620   67   89 
MARSK    MARKS    M620 M620   60   95 
MARX     AMRX     M620 A562   50   91 
MARX     M4RX     M620 M620   75   85 
MARX     MARKS    M620 M620   60   84 
MARX     MARSK    M620 M620   60   84 
MARX     MAX     M620 M200   75   93 
MARX     MRX     M620 M620   75   92 

11 rows selected. 

SQL> SQL> SQL> 

SOUNDEX的一大優點是,它的標記化字符串。這意味着它可以爲您提供,它可以編入索引:當涉及到大量數據時,這是非常有價值的。另一方面,它又古老又粗俗。還有更新的算法,比如Metaphone和Double Metaphone。你應該能夠通過Google找到它們的PL/SQL實現。

評分的優點是它們允許一定程度的模糊性;所以你可以找到所有的行where name_score >= 90%。壓制的缺點是分數是相對的,所以你不能爲它們編制索引。這種比較會導致大量的處理。

這意味着:

  1. 你需要的戰略組合。沒有單一的算法可以解決你的問題。
  2. 數據清理很有用。比較MARX與MRX和M4RX的得分:名稱中的剝離數提高了命中率。
  3. 你無法在飛行中獲得大量的名字。如果可以的話,使用標記和預先評分。如果你沒有很多流失,請使用緩存。如果你負擔得起,使用分區。
  4. 使用Oracle Text(或類似軟件)構建暱稱和變體的同義詞庫。
  5. Oracle 11g爲Oracle Text引入了特定的名稱搜索功能。 Find out more.
  6. 建立一個規範名稱表來評分並將實際數據記錄鏈接到該表。
  7. 使用其他數據值(尤其是可編入索引的數據值,如出生日期)來預過濾大量名稱或提高建議匹配的置信度。
  8. 請注意,其他數據值也帶有自己的問題:出生在31/01/11 11個月或80歲的人是誰?
  9. 請記住,名字是棘手的,尤其是當你必須考慮名字被羅馬化時:有超過400種不同的拼寫方式,用Moammar Khadaffi(以羅馬字母表) - 甚至谷歌都不能同意哪個變體是最經典的。

根據我的經驗,連接令牌(名字,姓氏)是一種混合的祝福。它可以解決某些問題(比如道路名稱是出現在地址欄1還是地址欄2),但會導致其他問題:考慮格拉漢OLIVER vs OLIVER GRAHAM對OLIVER vs OLIVER,GRAHAM VS GRAHAM,OLIVER對GRAHAM和GRAHAM對OLIVER的得分。

無論你做什麼,你仍然會有誤報和錯過命中。沒有任何算法能夠抵抗拼寫錯誤(儘管Jaro Winkler在MARX和AMRX上表現不錯)。

+0

這就是我一直在尋找的東西。其中一些我已經實施,但其他一些部分是金粉。非常感謝。我會做一些關於Metaphone算法的研究。我正在使用的模糊分數已經以基本方式使用,並且有一些很好的方法來找到置信度閾值,所以您提供的額外信息將與此相吻合。很好的答案! – Ollie