web-dev-qa-db-fra.com

Comment faire une correspondance approximative des noms de sociétés dans MYSQL avec PHP pour l'auto-complétion?

Mes utilisateurs vont importer par copier-coller une grande chaîne contenant les noms de sociétés. 

J'ai une base de données MYSQL existante et en croissance de noms de sociétés, chacune avec un unique company_id.

Je veux pouvoir analyser la chaîne et attribuer à chaque nom de société saisi par l'utilisateur une correspondance approximative.

À l'heure actuelle, il est également lent de faire une correspondance en chaîne. ** L'indexation Soundex sera-t-elle plus rapide? Comment puis-je donner à l'utilisateur certaines options lors de la frappe? **

Par exemple, quelqu'un écrit:

 Microsoft -> Microsoft 
 Bare Essentials -> Bare Escentuals 
 Polycom, Inc. -> Polycom 

J'ai trouvé les discussions suivantes qui semblent similaires à cette question, mais l'affiche n'a pas été approuvée et je ne sais pas si leur cas d'utilisation est applicable:

Comment trouver la meilleure correspondance approximative pour une chaîne dans une base de données de grande taille

Correspondant à des noms de société inexacts en Java

42
AFG

Vous pouvez commencer par utiliser SOUNDEX() , cela fera probablement ce dont vous avez besoin (j’imagine une boîte de suggestions auto-suggérant des alternatives déjà existantes pour ce que l’utilisateur tape).

Les inconvénients de SOUNDEX() sont les suivants:

  • son incapacité à différencier les chaînes plus longues. Seuls les premiers caractères sont pris en compte, les chaînes plus longues qui divergent à la fin génèrent la même valeur SOUNDEX
  • le fait que la première lettre doit être la même ou vous ne trouverez pas une correspondance facilement. SQL Server a la fonction DIFFERENCE () pour vous dire combien deux valeurs SOUNDEX sont séparées, mais je pense que MySQL n’a rien de tel intégré.
  • pour MySQL, au moins selon the docs , SOUNDEX est cassé pour l'entrée unicode

Exemple:

SELECT SOUNDEX('Microsoft')
SELECT SOUNDEX('Microsift')
SELECT SOUNDEX('Microsift Corporation')
SELECT SOUNDEX('Microsift Subsidary')

/* all of these return 'M262' */

Pour des besoins plus avancés, je pense que vous devez regarder la distance Levenshtein (aussi appelée "distance de montage") de deux chaînes et travailler avec un seuil. C'est la solution la plus complexe (= la plus lente), mais elle permet une plus grande flexibilité.

Le principal inconvénient est que vous avez besoin des deux chaînes pour calculer la distance qui les sépare. Avec SOUNDEX, vous pouvez stocker un fichier SOUNDEX pré-calculé dans votre tableau et comparer/trier/groupe/filtrer dessus. Avec la distance de Levenshtein, vous constaterez peut-être que la différence entre "Microsoft" et "Nzcrosoft" n'est que de 2, mais cela prendra beaucoup plus de temps pour arriver à ce résultat. 

Dans tous les cas, un exemple de fonction de distance Levenshtein pour MySQL est disponible sur codejanitor.com: Levenshtein Distance en tant que fonction stockée MySQL (10 février 2007) .

44
Tomalak

SOUNDEX est un algorithme correct pour cela, mais des avancées récentes ont été réalisées sur ce sujet. Un autre algorithme a été créé, appelé Metaphone, qui a ensuite été modifié en un algorithme Double Metaphone. J'ai personnellement utilisé l'implémentation Java double du commun, Apache, qui est personnalisable et précise.

Ils ont également des implémentations dans beaucoup d'autres langues sur la page wikipedia. Vous avez répondu à cette question, mais si vous rencontriez l'un des problèmes identifiés avec SOUNDEX et apparaissant dans votre application, il est bon de savoir qu'il existe des options. Parfois, il peut générer le même code pour deux mots très différents. Double métaphone a été créé pour aider à résoudre ce problème.

Volé sur wikipedia: http://fr.wikipedia.org/wiki/Soundex

En réponse aux insuffisances du Algorithme Soundex, Lawrence Philips développé l'algorithme Metaphone pour le même but. Philips plus tard développé une amélioration à Metaphone, qu'il a appelé Double-Metaphone . Double-métaphone comprend beaucoup ensemble de règles de codage plus grand que son prédécesseur, gère un sous-ensemble de caractères non latins, et retourne un primaire et un codage secondaire à rendre compte de différentes prononciations d'un seul mot en anglais.

Au bas de la page du double métaphone, ils ont les implémentations de tous les langages de programmation: http://en.wikipedia.org/wiki/Double-Metaphone

Implémentation Python & MySQL: https://github.com/AtomBoy/double-metaphone

22
Cheese Daneish

Tout d'abord, je voudrais ajouter que vous devez faire très attention lorsque vous utilisez une forme quelconque d'algorithme d'appariement Phonetic/Fuzzy, car ce type de logique est exactement cela, Fuzzy ou pour le dire plus simplement; potentiellement inexact. Cela est particulièrement vrai lorsqu'il est utilisé pour faire correspondre les noms de société.

Une bonne approche consiste à rechercher des corroborations à partir d'autres données, telles que des informations d'adresse, des codes postaux, des numéros de téléphone, des coordonnées géographiques, etc. Cela vous aidera à confirmer la probabilité d'une correspondance exacte de vos données.

Il existe toute une série de problèmes liés au rapprochement de données B2B trop nombreux pour être abordés ici. J'ai écrit davantage sur Correspondance de nom de société dans mon blog, mais en résumé, les principaux problèmes sont les suivants:

  • Regarder la chaîne entière est inutile car la partie la plus importante D'un nom de société n'est pas nécessairement au début de la sociétéNom. c’est-à-dire «The Proctor and Gamble Company» ou «Réserve fédérale des États-Unis».
  • Les abréviations sont courantes dans les noms de sociétés, à savoir HP, GM, GE, P & G, D & B, etc.
  • Certaines entreprises épellent délibérément leurs noms de manière incorrecte dans le cadre de leur marque et se différencient des autres entreprises.

Faire correspondre des données exactes est facile, mais faire correspondre des données non exactes peut prendre beaucoup plus de temps et je vous conseillerais donc de vérifier comment vous allez valider les correspondances non exactes afin de vous assurer qu'elles sont de qualité acceptable. 

Avant de créer Match2Lists.com, nous passions beaucoup de temps à valider des correspondances floues. Dans Match2Lists, nous avons incorporé un puissant outil de visualisation nous permettant de passer en revue les correspondances non exactes, ce qui a vraiment changé la donne en termes de validation des correspondances, réduisant nos coûts et nous permettant de produire des résultats beaucoup plus rapidement.

Bonne chance!!

8
Derren

Voici un lien vers la discussion php des fonctions soundex dans mysql et php. Je commencerais par là, puis développerais vos autres exigences moins bien définies.

Votre référence fait référence à la méthodologie de mise en correspondance de Levenshtein. Deux problèmes. 1. C'est plus approprié pour mesurer la différence entre deux mots connus, pas pour chercher. 2. Il aborde une solution conçue davantage pour détecter des erreurs telles que la vérification des erreurs (en utilisant "Levenshtien" pour "Levenshtein") plutôt que des fautes d'orthographe (où l'utilisateur ne sait pas épeler, dites "Levenshtein" et dactylographié en "Levinstein" Je l’associe généralement à la recherche d’une phrase dans un livre plutôt que d’une valeur clé dans une base de données.

EDIT: En réponse à comment--

  1. Pouvez-vous au moins amener les utilisateurs à mettre les noms de sociétés dans plusieurs zones de texte; 2. ou utilisez un séparateur de nom sans ambiguïté (dites barre oblique inversée); 3. omettez les articles ("Le") et les abréviations génériques (ou vous pouvez filtrer pour ceux-ci); 4. Éclatez les espaces et comparez-les également (donc Soft Soft => Microsoft, Bare Essentials => bareessentials); 5. filtrer la ponctuation; 6. Faites une recherche "OU" sur des mots ("nue" OR "de base") - les gens laisseront inévitablement l’une ou l’autre de temps en temps.

Testez comme un fou et utilisez la boucle de rétroaction des utilisateurs.

4
dkretz

levenshtein est la meilleure fonction pour l’appariement flou. il est traditionnellement utilisé par les correcteurs orthographiques, alors cela pourrait être la voie à suivre. il existe un fichier UDF disponible ici: http://joshdrew.com/

l'utilisation de levenshtein présente l'inconvénient de ne pas être très évolutive. une meilleure idée pourrait être de vider la table entière dans un fichier de dictionnaire personnalisé du correcteur orthographique et de faire la suggestion à partir de votre niveau application au lieu du niveau base de données.

1
longneck

Cette réponse résulte en une recherche indexée de presque toutes les entités en utilisant une entrée de 2 ou 3 caractères ou plus.

Fondamentalement, créez une nouvelle table avec 2 colonnes, Word et clé. Exécutez un processus sur la table d'origine contenant la colonne à rechercher. Ce processus extrait chaque mot de la colonne d'origine et les écrit dans le tableau Word avec la clé d'origine. Au cours de ce processus, les mots courants tels que "le", "et", etc. doivent être ignorés. 

Nous créons ensuite plusieurs index sur la table Word, comme suit ...

  • Un index normal et minuscule sur Word + key 
  • Un index sur le 2ème au 5ème caractère + touche
  • Un index sur le 3ème au 6ème caractère + touche

    Vous pouvez également créer un index SOUNDEX () sur la colonne Word.

Une fois que cela est en place, nous prenons n'importe quelle entrée d'utilisateur et recherchons en utilisant le mot normal = entrée ou l'entrée LIKE%. Nous ne faisons jamais une entrée LIKE% car nous recherchons toujours une correspondance sur l’un des 3 premiers caractères, qui sont tous indexés. 

Si votre table d'origine est volumineuse, vous pouvez la partitionner en morceaux de l'alphabet pour vous assurer que l'entrée de l'utilisateur est immédiatement réduite aux lignes candidates. 

0