2010-03-12 7 views
3

Je travaille actuellement sur un projet dans lequel un algorithme de correspondance de données doit être implémenté. Un système externe transmet toutes les données qu'il connaît sur un client et le système I doit retourner le client correspondant. Ainsi, le système externe connaît alors l'identifiant correct du client plus il obtient des données supplémentaires ou peut mettre à jour ses propres données du client spécifique.Algorithme de correspondance de données

Les champs suivants sont transmis dans:

  • Nom
  • Nom2
  • Rue
  • Ville
  • ZipCode
  • BankAccountNumber
  • BANKNAME
  • BANKCODE
  • Email
  • Téléphone
  • Fax
  • Web

Les données peuvent être de grande qualité et beaucoup d'informations sont disponibles, mais souvent les données est merdique et que le nom et l'adresse est disponible et pourrait avoir des orthographes.

Je suis mise en œuvre du projet en .Net. Ce que je fais actuellement est quelque chose comme ce qui suit:

public bool IsMatch(Customer customer) 
{ 
    // CanIdentify just checks if the info is provided and has a specific length (e.g. > 1) 
    if (CanIdentifyByStreet() && CanIdentifyByBankAccountNumber()) 
    { 
     // some parsing of strings done before (substring, etc.) 
     if(Street == customer.Street && AccountNumber == customer.BankAccountNumber) return true; 
    } 
    if (CanIdentifyByStreet() && CanIdentifyByZipCode() &&CanIdentifyByName()) 
    { 
     ... 
    } 
} 

Je ne suis pas très satisfait de l'approche ci-dessus. C'est parce que je devrais écrire si des déclarations pour tous les cas raisonnables (combinaisons) ainsi je ne manque aucune chance de correspondre à l'entité.

Je pensais que je pourrais créer une sorte de points correspondant. Donc, pour chaque critère correspondant, un score serait ajouté. Comme:

public bool IsMatch(Customer customer) 
{ 
    int matchingScore = 0; 
    if (CanIdentifyByStreet()) 
    { 
     if(....) 
      matchingScore += 10; 
    } 
    if (CanIdentifyByName()) 
    { 
     if(....) 
      matchingScore += 10; 
    } 
    if (CanIdentifyBankAccountNumber()) 
    { 
     if(....) 
      matchingScore += 10; 
    } 

    if(matchingScore > iDontKnow) 
     return true; 
} 

Cela me permettrait de prendre en considération toutes les données correspondantes, et en fonction d'un certain poids j'augmenterais le score d'appariement. Si le score est assez élevé, c'est un match.

savoir ma question est: Y a-t-il des meilleures pratiques là-bas pour de telles choses, comme correspondant à des modèles d'algorithme, etc? Merci beaucoup!

+1

Vous voulez dire "fautes d'orthographe" quand vous dites "orthographes", n'est-ce pas? – Svante

Répondre

1

Pour l'inspiration, regardez les Levenshtein distance algorithm. Cela vous donnera un mécanisme raisonnable pour pondérer vos comparaisons.

Je voudrais aussi ajouter que dans mon expérience, vous ne pouvez jamais correspondre à deux morceaux de données arbitraires dans la même entité avec une certitude absolue. Vous devez présenter des correspondances plausibles à un utilisateur, qui peut ensuite vérifier avec certitude que John Smith sur 1920 E. Pine est la même personne que Jon Smith sur 192 East Pine Road ou non.

+0

Levenshtein et le Hamming seraient exagérés. – rook

+0

Peut-être, je ne suis pas sûr exactement quelles sont ses exigences. La variable matchingScore dans sa solution proposée m'a amené à croire qu'il avait besoin d'un système de pondération pour les correspondances, et ne savait pas comment procéder. –

+0

+1; vous pouvez ensuite stocker la différence de la n-ème variable dans le n-ième élément d'un vecteur puis calculer la distance euclidienne de deux objets de domaine pour obtenir la correspondance (je suppose que vous aurez besoin de plusieurs constantes avant chaque variable pour pondérer les) @The Rook pourquoi? Regardez le pseudo code wikipedia. – Karussell

2

Dans mon expérience avec ce genre de chose, il était en fait les gens d'affaires qui ont défini les règles de ce qui était acceptible comme un match, plutôt que ce soit une décision technique. Cela a eu du sens pour moi, puisque l'entreprise finit par assumer le risque. En outre, ce qui constitue une correspondance peut être sujet à changement, comme s'ils utilisaient le système et trouvaient que trop de personnes étaient exclues.

Je pense que votre première approche a plus de sens, en ce sens que si vous pouvez faire correspondre quelqu'un par nom et numéro de compte bancaire, alors vous êtes sûr que ce sont eux. Cependant, si le nom et l'information bancaire ne correspondent pas, mais que l'adresse, le numéro de téléphone et tout ce qui correspond (par exemple, un conjoint), le système de notation risque de ne pas correspondre correctement aux personnes. Je me rends compte que c'est beaucoup de code, mais tant que vous extrayez le code correspondant réel (méthode matchPhoneNumber, etc), alors c'est bien au niveau du design.

Je prendrais probablement un peu plus loin et retirerais l'appariement en une énumération et aurais alors des listes de correspondances acceptables. Un peu comme ceci: interface Match { correspondances booléennes (client c1, client c2); }

class BankAccountMatch implements Match 
{ 
    public boolean matches(Customer c1, Customer c2) 
    { 
     return c1.getBankAccountNumber() == c2.getBankAccountNumber(); 
    } 
} 

static Match BANK_ACCOUNT_MATCH = new BankAccountMatch(); 

Match[][] validMatches = new Match[] [] { 
     {BANK_ACCOUNT_MATCH, NAME_MATCH}, 
     {NAME_MATCH, ADDRESS_MATCH, FAX_MATCH}, ... 
}; 

Et puis le code qui fait la validation serait juste itérer sur le tableau validMatches et de les tester pour voir si l'on convient. Je pourrais même retirer les listes de correspondances valides dans un fichier de configuration. Tout dépend du niveau de robustesse dont votre système a besoin.

0

Si vous vous limitez à l'adresse et au nom, vous pouvez simplement utiliser la formule de moissonneuse ou un index spatial si vous avez la géolocalisation. Pour le nom, vous pouvez utiliser un trie et obtenir seulement les premiers résultats, peut-être 10.

0

Qu'en est-il une approche d'apprentissage automatique. Créer. Distances par article.

Ceux-ci deviennent votre espace d'entrée. Construire un ensemble d'entraînement sur des custers correctement appariés en fonction de ces distances. Courir à travers votre algo de l'apprenti machine préféré. Obtenez vos paramètres pour les fonctions de décision qui reflètent la force de la correspondance. Régler. Appliquer aux nouveaux cas. Aller à la banque.

Questions connexes