Newsgroup: it.comp.lang.delphi
Titolo: Percentuale di riconoscimento di un dato

Buongiorno a tutti innanzitutto.
sono nuovo del newsgroup e spero di essere nel posto giusto per porre il mio quesito.
 
Avrei la necessità ricercare un dato in archivio ed ottenere una lista dei possibili record che soddisfano maggiormente la mia richiesta.
 
Cerco di spiegarmi meglio.
Ho un cliente che ha un archivio di anagrafiche con oltre un milione di nominativi.
 
Questo archivio di anagrafiche viene anche popolato da procedure automatiche che leggono dei file che arrivano da fonti diverse per cui mi ritrovo spesso con nominativi molto simili tra di loro che magari cambiano anche solo per pochi caratteri. 
 
Vorrei quindi fare una pre-elaborazione che mi identifichi maggiormente per quanto possibile la presenza o meno di una data anagrafica in archivio.
 
Supponendo di avere in anagrafica dei nominativi quali
 
ARMANDO & ALBERTO SNC
ARMANDO & FIGLI SAS
ALBERTO & ARMANDO
ARMANDO ALBERTO
 
Ora, dato in input il valore di "ARMANDO ALBERTO" vorrei che il programma mi restituisse il record set precedente con una "percentuale di riconoscimento" tipo :
 
ARMANDO & ALBERTO SNC -> 90%
ARMANDO & FIGLI SAS -> 20%
ALBERTO & ARMANDO -> 70%
ARMANDO ALBERTO -> 100%
 
E' solo un esempio ma spero di aver reso l'idea.
 
Grazie
 
 
 
 

Guarda con l'SQL non so ma in delphi puoi provare con una cosa simile
 
Function NoSpace(Const S : String) : String;
Var
   S1 : String;
Begin
   S1 := S;
   While Pos(' ', S1) > 0 Do Delete(S1, Pos(' ', S1), 1);
   Result := S1;
End;
 
Function Controlla(Const FraseData, FraseControllo : String) : Integer;
Var
   Caratteri : Integer;
   S, S1, Sx : String;
   Frase     : String;
   Ind       : Integer;
Begin
   Caratteri := 0;
   S         := FraseControllo;
   Frase     := FraseData;
 
   While (S <> '') Do
         Begin
           Ind := Pos(' ', S);
           If Ind > 0 Then
              Begin
                S1 := Copy(S, 1, Ind-1);
                Delete(S, 1, Ind);
              End
                Else
              Begin
                S1 := S;
                S  := '';
              End;
 
           Ind := Pos(S1, Frase);
           If Ind > 0 Then
              Begin
                Inc(Caratteri, Length(S1));
                Sx := Copy(Frase, 1, Ind-1);
                Delete(Frase, 1, Ind+Length(S1)-1);
                Frase := Sx+Frase;
              End;
         End;
 
   Result := Round(Caratteri*100/Length(NoSpace(FraseData)));
End;
 
Dove FraseData inserisci il nominativo letto dal data-base e se 
FraseControllo metti quello da cercare

 
L'argomento  prescinde da delphi e cmomunque non è una cosa semplice.
Alcuni database supportano nativamente il "soundex".
Io l'ho provato anni fa per un progetto nel quale avevo esattamente lo stesso problema...e alla fine lascai perdere sia il problema che soundex che non faceva cio' che a me serviva.
 

 ARMANDO ALBERTO -> 100%
 
Io proverei questa strada:
 
Costruisci una funzione che tokenizza le stringhe, separando le parole
in base a qualche criterio da affinare in seguito (magari che ti ignora alcuni
simboli o parole "comuni" come "&", "e", "." eccetera).
 
A quel punto il tuo algoritmo consiste in una funzione che 
genera il punteggio in base non alle due stringhe ma 
in base alle liste di parole estratte dalle due stringhe. 
 
ListaInput := Tokenize( StringaInput );
Per ogni stringa S nel DB:
  ListaS := Tokenize( S );
  PunteggioS := CalcolaPunteggio( ListaInput, ListaS );
 
La funzione CalcolaPunteggio potrebbe essere composta da una
serie di regole tipo queste:
 
- le due liste sono identiche => 100%
- stesse parole ma in seguenza diversa => 70%
- tutte le parole di ListaInput compaiono in ListaS => 50%
- come sopra ma in piu' sono nella stessa sequenza => 70%
- solo N parole di ListaInput compaiono in ListaS => 1/N
 
eccetera.
 
Ovviamente questo e' solo un abbozzo ed e' tutto da realizzare!
 
ciao
Giacomo

On 29.03.2013 12:01, 
leo...@hotmail.it
 wrote:
 > Buongiorno a tutti innanzitutto.
 >[...]
 > Ora, dato in input il valore di "ARMANDO ALBERTO" vorrei che il 
programma mi restituisse il record set precedente con una "percentuale 
di riconoscimento" tipo :
 
Quello che chiedi riguarda in generale gli algoritmi.
Un algoritmo che si avvicina a quanto da te richiesto, � quello di 
Levenshtein: misura la distanza tra una stringa e l'altra in termini di 
modifiche. Cio� risponde alla domanda: quanti caratteri devi modificare 
per partire da una stringa e arrivare all'altra?
 
Qui ho trovato la versione delphi:
http://stackoverflow.com/questions/54797/how-do-you-implement-levenshtein-distance-in-delphi
 
 
Su wikipedia citano anche delle implementazioni native nei databases.
 
-- 
morde
Android
QT 4.7
Delphi (5,6,7.. expired)
Firebird Database