"Jag försöker hitta en tillförlitlig metod för att matcha dubbla personposter i databasen."
Tyvärr finns det inget sådant. Det mesta du kan hoppas på är ett system med ett rimligt inslag av tvivel.
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>
Den stora fördelen med SOUNDEX är att det symboliserar strängen. Det betyder att det ger dig något som kan indexeras :detta är otroligt värdefullt när det kommer till stora mängder data. Å andra sidan är den gammal och rå. Det finns nyare algoritmer, som Metaphone och Double Metaphone. Du bör kunna hitta PL/SQL-implementeringar av dem via Google.
Fördelen med poäng är att de tillåter en viss grad av luddighet; så att du kan hitta alla rader where name_score >= 90%
. Den förkrossande nackdelen är att poängen är relativa och därför kan du inte indexera dem. Den här typen av jämförelse dödar dig med stora volymer.
Vad detta betyder är:
- Du behöver en blandning av strategier. Ingen enskild algoritm kommer att lösa ditt problem.
- Datarensning är användbart. Jämför poängen för MARX vs MRX och M4RX:att ta bort siffror från namn förbättrar träfffrekvensen.
- Du kan inte få stora mängder namn direkt. Använd tokenizing och pre-scoring om du kan. Använd cachning om du inte har mycket churn. Använd partitionering om du har råd.
- Använd en Oracle-text (eller liknande) för att bygga en synonymordbok med smeknamn och varianter.
- Oracle 11g introducerade specifik namnsökningsfunktion i Oracle Text. Ta reda på mer.
- Skapa en tabell med kanoniska namn för poängsättning och länka faktiska dataposter till det.
- Använd andra datavärden, särskilt indexerbara sådana som födelsedatum, för att förfiltrera stora volymer namn eller för att öka förtroendet för föreslagna matchningar.
- Var medveten om att andra datavärden kommer med sina egna problem:är någon född den 31/01/11 elva månader eller åttio år gammal?
- Kom ihåg att namn är knepiga, speciellt när du måste tänka på namn som har romaniserats:det finns över fyrahundra olika sätt att stava Moammar Khadaffi (i det romerska alfabetet) - och inte ens Google kan komma överens om vilken variant som är mest kanoniska.
Enligt min erfarenhet är det en blandad välsignelse att sammanfoga tokens (förnamn, efternamn). Det löser vissa problem (som om vägnamnet förekommer på adressrad 1 eller adressrad 2) men orsakar andra problem:överväg att poängsätta GRAHAM OLIVER vs OLIVER GRAHAM mot poäng OLIVER vs OLIVER, GRAHAM vs GRAHAM, OLIVER vs GRAHAM och GRAHAM vs OLIVER .
Vad du än gör kommer du fortfarande att få falska positiva resultat och missade träffar. Ingen algoritm är bevis mot stavfel (även om Jaro Winkler klarade sig ganska bra med MARX vs AMRX).