Introduction
Lorsque vous travaillez avec des ensembles de données contenant des noms, qu'il s'agisse de noms de villes, de personnes ou d'autres entités, un problème courant se pose : de légères variations dans l'orthographe ou le formatage. Par exemple, vous pouvez rencontrer des noms comme "John Doe" et "John A. Doe" ou "New York" et "New York City" lors de la fusion de plusieurs ensembles de données. Ces petites différences peuvent poser des défis importants pour assurer une correspondance et une intégration des données précises.
C'est là que les métriques de similarité des chaînes de caractères interviennent, offrant des outils puissants pour comparer et faire correspondre des noms qui ne sont pas exactement identiques mais suffisamment proches en termes de signification. L'une de ces métriques, la similarité de Jaro-Winkler, est particulièrement efficace pour identifier et quantifier la similarité entre deux chaînes de caractères, ce qui la rend idéale pour comparer des noms avec de légères différences.
Dans cet article, nous allons explorer comment utiliser la métrique de similarité Jaro-Winkler en Python pour comparer une liste de noms. Nous utiliserons la bibliothèque textdistance, qui fournit une implémentation facile à utiliser de cette métrique. Que vous ayez affaire à de légères fautes d'orthographe, à des formats de noms différents ou à d'autres petites variations, cette approche peut vous aider à identifier les enregistrements correspondants avec une plus grande précision.
Table des matières
Qu'est-ce que la métrique de similarité Jaro-Winkler ?
La similarité de Jaro-Winkler est une métrique qui mesure la similarité entre deux chaînes de caractères. Elle est une extension de la métrique de distance de Jaro et est particulièrement utile pour comparer des chaînes courtes, comme des noms. L'idée clé derrière Jaro-Winkler est qu'elle attribue des notes plus favorables aux chaînes qui correspondent dès le début pour une longueur de préfixe définie, ce qui la rend plus efficace pour comparer des noms avec de petites différences.
Utilisation de la bibliothèque textdistance en Python
Installation de la bibliothèque nécessaire
Avant de plonger dans le code, vous devrez installer la bibliothèque textdistance, qui propose un large éventail de métriques de similarité des chaînes, y compris Jaro-Winkler.
Vous pouvez l'installer en utilisant pip :
1 | pip install textdistance |
Création d'une liste de noms
Commençons par créer une liste de noms que nous souhaitons comparer. Nous utiliserons ces noms pour démontrer comment calculer la similarité entre chaque paire en utilisant la métrique de Jaro-Winkler.
1 2 3 4 5 6 | import pandas as pd import textdistance # Create a pandas DataFrame with some names names = ['Martha', 'Marhta', 'Mark', 'Marta', 'Mathew', 'Matthew'] df = pd.DataFrame(names, columns=['Name']) |
Calcul de la similarité Jaro-Winkler
Maintenant que nous avons notre liste de noms, nous pouvons calculer la similarité Jaro-Winkler entre chaque paire. La bibliothèque textdistance rend ce processus simple.
Nous allons créer une fonction pour calculer la similarité entre un nom donné et tous les autres noms de la liste, puis appliquer cette fonction sur notre DataFrame pour générer une matrice de similarité.
1 2 3 4 5 6 7 8 9 10 11 12 | # Create a function to apply the Jaro-Winkler similarity to each pair of names def calculate_similarity(row, df): return df['Name'].apply(lambda x: textdistance.jaro_winkler(row['Name'], x)) # Apply the function to the DataFrame similarity_matrix = df.apply(lambda row: calculate_similarity(row, df), axis=1) # Set the index and columns names for better readability similarity_matrix.index = df['Name'] similarity_matrix.columns = df['Name'] print(similarity_matrix) |
La sortie du code ci-dessus est une matrice de similarité où chaque cellule représente le score de similarité Jaro-Winkler entre deux noms. Les valeurs varient de 0 à 1, où 1 indique une correspondance exacte et les valeurs proches de 0 indiquent une moindre similarité.
Voici un exemple de ce à quoi pourrait ressembler la sortie :
1 2 3 4 5 6 7 | Martha Marhta Mark Marta Mathew Matthew Martha 1.000000 0.961111 0.744444 0.961111 0.813333 0.813333 Marhta 0.961111 1.000000 0.716667 0.925556 0.787778 0.787778 Mark 0.744444 0.716667 1.000000 0.755556 0.744444 0.744444 Marta 0.961111 0.925556 0.755556 1.000000 0.813333 0.813333 Mathew 0.813333 0.787778 0.744444 0.813333 1.000000 0.975556 Matthew 0.813333 0.787778 0.744444 0.813333 0.975556 1.000000 |
Cette matrice de similarité peut être utilisée pour identifier les correspondances potentielles ou les doublons dans votre ensemble de données. Par exemple, vous pourriez considérer toute paire de noms avec un score de similarité supérieur à un certain seuil (par exemple, 0,9) comme une correspondance probable. Cette approche peut être particulièrement utile pour des tâches telles que le nettoyage des données, la liaison d'enregistrements et la fusion d'ensembles de données où les conventions de nommage ne sont pas garanties d'être cohérentes.
Implémentation de la similarité Jaro-Winkler
La similarité Jaro-Winkler est une extension de la métrique de similarité Jaro, qui attribue des notes plus favorables aux chaînes qui correspondent dès le début pour une longueur de préfixe définie.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | def jaro_distance(s1, s2): s1_len = len(s1) s2_len = len(s2) if s1_len == 0 or s2_len == 0: return 0.0 match_distance = max(s1_len, s2_len) // 2 - 1 s1_matches = [False] * s1_len s2_matches = [False] * s2_len matches = 0 transpositions = 0 # Finding matches for i in range(s1_len): start = max(0, i - match_distance) end = min(i + match_distance + 1, s2_len) for j in range(start, end): if s2_matches[j]: continue if s1[i] != s2[j]: continue s1_matches[i] = True s2_matches[j] = True matches += 1 break if matches == 0: return 0.0 k = 0 for i in range(s1_len): if not s1_matches[i]: continue while not s2_matches[k]: k += 1 if s1[i] != s2[k]: transpositions += 1 k += 1 transpositions /= 2 return (matches / s1_len + matches / s2_len + (matches - transpositions) / matches) / 3.0 def jaro_winkler(s1, s2, p=0.1, max_l=4): jaro_dist = jaro_distance(s1, s2) # Find the length of common prefix up to a max of max_l prefix_length = 0 for i in range(min(len(s1), len(s2))): if s1[i] == s2[i]: prefix_length += 1 else: break if prefix_length == max_l: break return jaro_dist + (prefix_length * p * (1 - jaro_dist)) # Example Usage: s1 = "MARTHA" s2 = "MARHTA" print(f"Jaro-Winkler Similarity: {jaro_winkler(s1, s2)}") |
Sortie :
1 | Jaro-Winkler Similarity: 0.9611111111111111 |
Vous pouvez créer un DataFrame pandas de noms, puis appliquer la fonction de similarité Jaro-Winkler pour calculer la similarité entre chaque paire de noms. Voici un exemple de comment faire :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | # Create a pandas DataFrame with some names names = ['Martha', 'Marhta', 'Mark', 'Marta', 'Mathew', 'Matthew'] df = pd.DataFrame(names, columns=['Name']) # Create a function to apply the Jaro-Winkler similarity to each pair of names def calculate_similarity(row, df): return df['Name'].apply(lambda x: jaro_winkler(row['Name'], x)) # Apply the function to the DataFrame similarity_matrix = df.apply(lambda row: calculate_similarity(row, df), axis=1) # Set the index and columns names for better readability similarity_matrix.index = df['Name'] similarity_matrix.columns = df['Name'] print(similarity_matrix) |
La sortie sera une matrice avec les noms en tant que lignes et colonnes, chaque cellule représentant la similarité Jaro-Winkler entre les noms :
1 2 3 4 5 6 7 | Martha Marhta Mark Marta Mathew Matthew Martha 1.000000 0.961111 0.744444 0.961111 0.813333 0.813333 Marhta 0.961111 1.000000 0.716667 0.925556 0.787778 0.787778 Mark 0.744444 0.716667 1.000000 0.755556 0.744444 0.744444 Marta 0.961111 0.925556 0.755556 1.000000 0.813333 0.813333 Mathew 0.813333 0.787778 0.744444 0.813333 1.000000 0.975556 Matthew 0.813333 0.787778 0.744444 0.813333 0.975556 1.000000 |
Cette matrice vous permet de voir la similarité entre n'importe quelle paire de noms dans le DataFrame.
Conclusion
La métrique de similarité Jaro-Winkler est un outil puissant pour comparer des noms qui peuvent présenter de légères variations dans l'orthographe ou le formatage. En utilisant la bibliothèque textdistance en Python, vous pouvez facilement implémenter cette métrique pour comparer une liste de noms, vous aidant à identifier les correspondances avec précision et à nettoyer vos données.
Que vous travailliez avec des noms de personnes, de villes ou d'autres entités, cette méthode peut grandement améliorer la précision de vos processus de fusion et de correspondance des données.
Références
Links | Source |
---|---|
Jaro–Winkler distance | en.wikipedia.org |
Jaro, M. A. (1989). "Advances in record linkage methodology as applied to matching the 1985 census of Tampa, Florida." Journal of the American Statistical Association, 84(406), 414-420. | American Statistical Association |
Winkler, W. E. (1990). "String Comparator Metrics and Enhanced Decision Rules in the Fellegi-Sunter Model of Record Linkage." Proceedings of the Section on Survey Research Methods (American Statistical Association), 354–359. | American Statistical Association |
Jurafsky, D., & Martin, J. H. (2008). Speech and Language Processing. (2nd Edition). Pearson Prentice Hall | Speech and Language Processing. (2nd Edition) |
textdistance | pypi.org |
textdistance conda-forge | anaconda.org |