I record corrispondenti in base a Nome di Persona
-
13-09-2019 - |
Domanda
Ci sono strumenti o metodi che possono essere utilizzati per la corrispondenza da un nome di persona tra due diverse fonti di dati?
I sistemi hanno in nessun altro comune le informazioni e i nomi sono stati inseriti in modo diverso, in molti casi.
Esempi di non esatta):
King Jr, Martin Luther = King, Martin (escludere suffisso)
Erving, Dr.J.= Erving, J.(escludere prefisso)
Obama, Barak Hussein = Obama, Barak (escludere secondo nome)
Pufnstuf, H. R.= Pufnstuf, Haibane Renmei (match abbreviazioni)
Tankengine, Thomas = Tankengine, Tom (match comune nickname)
Flair, Rick "il Natureboy" = Flair, Natureboy (partita sul nickname)
Soluzione
ho dovuto usare una varietà di tecniche suggerite. Grazie avermi nella giusta direzione (s). Si spera, la seguente vi aiuterà a qualcun altro con questo tipo di problema da risolvere.
Rimozione caratteri in eccesso
CREATE FUNCTION [dbo].[fn_StripCharacters]
(
@String NVARCHAR(MAX),
@MatchExpression VARCHAR(255)
)
RETURNS NVARCHAR(MAX)
AS
BEGIN
SET @MatchExpression = '%['+@MatchExpression+']%'
WHILE PatIndex(@MatchExpression, @String) > 0
SET @String = Stuff(@String, PatIndex(@MatchExpression, @String), 1, '')
RETURN @String
END
Utilizzo:
--remove all non-alphanumeric and non-white space
dbo.fn_StripCharacters(@Value, , '^a-z^0-9 ')
nome Spalato in parti
CREATE FUNCTION [dbo].[SplitTable] (@sep char(1), @sList StringList READONLY)
RETURNS @ResultList TABLE
(
[ID] VARCHAR(MAX),
[Val] VARCHAR(MAX)
)
AS
BEGIN
declare @OuterCursor cursor
declare @ID varchar(max)
declare @Val varchar(max)
set @OuterCursor = cursor fast_forward for (SELECT * FROM @sList) FOR READ ONLY
open @OuterCursor
fetch next from @OuterCursor into @ID, @Val
while (@@FETCH_STATUS=0)
begin
INSERT INTO @ResultList (ID, Val)
select @ID, split.s from dbo.Split(@sep, @Val) as split
where len(split.s) > 0
fetch next from @OuterCursor into @ID, @Val
end
close @OuterCursor
deallocate @OuterCursor
CREATE FUNCTION [dbo].[Split] (@sep char(1), @s varchar(8000))
RETURNS table
AS
RETURN (
WITH Pieces(pn, start, stop) AS (
SELECT 1, 1, CHARINDEX(@sep, @s)
UNION ALL
SELECT pn + 1, stop + 1, CHARINDEX(@sep, @s, stop + 1)
FROM Pieces
WHERE stop > 0
)
SELECT pn,
LTRIM(RTRIM(SUBSTRING(@s, start,
CASE WHEN stop > 0
THEN stop-start
ELSE 8000
END))) AS s
FROM Pieces
)
RETURN
Utilizzo:
--create split name list
DECLARE @NameList StringList
INSERT INTO @NameList (ID, Val)
SELECT id, firstname FROM dbo.[User] u
WHERE PATINDEX('%[^a-z]%', u.FirstName) > 0
----remove split dups
select u.ID, COUNT(*)
from dbo.import_SplitTable(' ', @NameList) splitList
INNER JOIN dbo.[User] u
ON splitList.id = u.id
soprannomi comuni:
Ho creato una tabella basata su questa lista e lo ha utilizzato per unire il nome comune equivalenti.
Utilizzo:
SELECT u.id
, u.FirstName
, u_nickname_maybe.Name AS MaybeNickname
, u.LastName
, c.ID AS ContactID from
FROM dbo.[User] u
INNER JOIN nickname u_nickname_match
ON u.FirstName = u_nickname_match.Name
INNER JOIN nickname u_nickname_maybe
ON u_nickname_match.relatedid = u_nickname_maybe.id
LEFT OUTER JOIN
(
SELECT c.id, c.LastName, c.FirstName,
c_nickname_maybe.Name AS MaybeFirstName
FROM dbo.Contact c
INNER JOIN nickname c_nickname_match
ON c.FirstName = c_nickname_match.Name
INNER JOIN nickname c_nickname_maybe
ON c_nickname_match.relatedid = c_nickname_maybe.id
WHERE c_nickname_match.Name <> c_nickname_maybe.Name
) as c
ON c.AccountHolderID = ah.ID
AND u_nickname_maybe.Name = c.MaybeFirstName AND u.LastName = c.LastName
WHERE u_nickname_match.Name <> u_nickname_maybe.Name
algoritmi di fonetica (Jaro Winkler):
L'articolo incredibile, Al di là SoundEx - Funzioni per la ricerca Fuzzy in MS SQL Server , mostra come installare e utilizzare il SimMetrics libreria in SQL Server. Questa libreria permette di trovare somiglianza relativa tra le stringhe e include numerosi algoritmi. Ho finito per lo più utilizzando Jaro Winkler per corrispondere ai nomi.
Utilizzo:
SELECT
u.id AS UserID
,c.id AS ContactID
,u.FirstName
,c.FirstName
,u.LastName
,c.LastName
,maxResult.CombinedScores
from
(
SELECT
u.ID
,
max(
dbo.JaroWinkler(lower(u.FirstName), lower(c.FirstName))
* dbo.JaroWinkler(LOWER(u.LastName), LOWER(c.LastName))
) AS CombinedScores
FROM dbo.[User] u, dbo.[Contact] c
WHERE u.ContactID IS NULL
GROUP BY u.id
) AS maxResult
INNER JOIN dbo.[User] u
ON maxResult.id = u.id
INNER JOIN dbo.[Contact] c
ON maxResult.CombinedScores =
dbo.JaroWinkler(lower(u.FirstName), lower(c.FirstName))
* dbo.JaroWinkler(LOWER(u.LastName), LOWER(c.LastName))
Altri suggerimenti
Si tratta di un problema molto complesso e ci sono un sacco di costosi strumenti per farlo correttamente.
Se vi siete mai chiesti perché non è possibile il check-in di un volo di Tom, Dick o Harry (o Fattura)
O perché no-fly liste e i terroristi liste di controllo non funzionano-considerare:
(1) Di Muammar Gheddafi
(2) Mo'ammar Gheddafi
(3) Muammar Kaddafi
(4) Muammar Qadhafi
(5) Moammar El Kadhafi
(6) Muammar Gadafi
(7) Mu'ammar al-Qadafi
(8) Moamer El Kazzafi
(9) Moamar al-Gheddafi
(10) Mu'ammar Al Qathafi
(11) Muammar Al Qathafi
(12) Mo'ammar el-Gheddafi
(13) Moamar El Kadhafi
(14) Muammar al-Qadhafi
(15) Mu'ammar al-Qadhdhafi
(16) Mu'ammar Qadafi
(17) Moamar Gheddafi
(18) Mu'ammar Qadhdhafi
(19) Muammar Considerazioni Di Gheddafi E Guida
(20) Muammar al-considerazioni di gheddafi e guida
(21) Mu'amar al-Kadafi
(22) Muammar Ghaddafy
(23) Muammar Ghadafi
(24) Muammar Gheddafi
(25) Muamar Kaddafi
(26) Muammar Quathafi
(27) Muammar Gheddafi
(28) Muamar Al-Kaddafi
(29) Muammar Gheddafi
(30) Muammar Qudhafi
(31) Mu'ammar al-Gheddafi
(32) Mulazim Awwal Mu'ammar Muhammad Abu Minyar al-Qadhafi
Ed è solo l'ortografia ufficiale - non vi sono errori di battitura!
Mi capita spesso impiegano algoritmi Soundex tipo per questo tipo di situazione. Prova il doppio Metaphone algoritmo. Se si utilizza SQL Server, c'è qualche codice sorgente per creare una funzione definita dall'utente.
Poiché avete trasposto dei dati, si consiglia di normalizzare un po ', per esempio, rimuovere tutte le virgole e le risultanti parole per lettera. Che vi darà un certo potenziale migliore corrispondenza. Nel caso in cui le parole sono state aggiunte nel mezzo, diventa un po 'più dura. Si potrebbe prendere in considerazione la rottura di un nome in parole, controllando con Double Metaphone se c'è una parola nell'altra colonna che corrisponde, e poi raccogliere il conteggio complessivo delle partite contro le parole, che vi dirà quanto vicino le due colonne sono.
Vorrei anche filtrare parole comuni come Dr., Mr., la signora, la signora, ecc, prima di fare i confronti.
Ecco alcune opzioni:
algoritmi di fonetica ...
Soundex ( http://en.wikipedia.org/wiki/Soundex )
Doppia Metaphone (href="http://en.wikipedia.org/wiki/Double_Metaphone" http://en.wikipedia.org/wiki/Double_Metaphone )
Modifica Distanza ( http://en.wikipedia.org/wiki/Levenshtein_distance )
Jaro-Winkler Distanza ( http://en.wikipedia.org/wiki/Jaro- Winkler_distance )
Un'altra cosa che si potrebbe provare sarebbe quello di confrontare ogni parola (splitting sullo spazio e forse trattino) con ogni parola l'altro nome e vedere quante parole corrispondono. Forse combinare questo con algoritmi fonetici per la corrispondenza più sfocata. Per un set di dati enorme, si vorrebbe indice di ogni parola e abbinarlo con un nome id. Per l'abbreviazione corrispondente è possibile confrontare solo la prima lettera. Probabilmente si desidera ignorare tutto ciò, ma le lettere quando si confronta pure parole.
Molti degli algoritmi fonetici hanno open source / campioni on-line.
Metaphone 3 è la terza generazione dell'algoritmo Metaphone. Aumenta la precisione di codifica fonetica dal 89% di Double Metaphone a 98% , come testato su un database dei più comuni parole in inglese, e nomi e le parole non in lingua inglese familiari in Nord America. Questo produce una codifica fonetica estremamente affidabile pronunce americane.
Metaphone 3 è stato progettato e sviluppato da Lawrence Philips, che progettato e sviluppato l'originale Metaphone e Double Metaphone algoritmi.