Les embeddings pour améliorer la correction orthographique

La correction orthographique automatique, même si elle fait l'objet de travaux depuis les années 70, reste difficile à résoudre en l'absence de données en contexte significatives.

DANS CET ARTICLE

Prêt à extraire l'or de vos données ?

Le texte bruité est problématique pour de nombreuses tâches de TAL car il entraîne une réduction de la précision des techniques d'apprentissage automatique et augmente le nombre de mots hors du vocabulaire (OOV) qui ne peuvent pas être traités par des techniques populaires telles que Word2Vec ou GloVe.

C'est pourquoi, dans le cadre du prétraitement de notre pipeline, nous avons exploré plusieurs approches de correction orthographique proactive de nos données d'entrée afin d'augmenter la précision des tâches en aval. Nous nous concentrerons ici sur la résolution de ce problème par l'intégration au niveau des caractères. Notre travail, qui permet l'entraînement à partir de zéro, l'utilisation et la visualisation, est disponible pour téléchargement et expérimentation en suivant ce lien[1].

Introduction

Les erreurs orthographiques peuvent être divisées en trois groupes qui nécessitent des approches différentes :

  1. Erreurs de mots réels : 'voix' orthographié comme 'voie'.Les erreurs de mots réels sont les plus difficiles à corriger car elles dépendent du contexte. Pour les corriger, nous devons analyser l'ensemble des données afin de vérifier la cohérence sémantique et la grammaire. Selon l'algorithme utilisé, nous introduisons la possibilité de corriger à tort des phrases exactes et d'ajouter un temps de traitement important. La manière la plus fréquente de traiter ce problème est le modèle seq2seq ou l'utilisation de données statistiques telles que le token ngram.
  2. Formes courtes : 'désolé' orthographié comme 'dsl'Les formes courtes ont la caractéristique de partager quelques lettres avec le mot prévu. En ce qui concerne la [distance d'édition] (https://en.wikipedia.org/wiki/Edit_distance#targetText=In computational linguistics and computer,one string into the other.), 'désolé' est plus proche de 'daI' que de 'désolé', et l'approche basée sur les dictionnaires est donc moins efficace.
  3. Erreurs de non-mots : 'merci' orthographié comme 'mecri'Les erreurs non verbales sont les plus fréquentes et résultent principalement de fautes de frappe. Nous nous concentrons sur celles-ci dans cet article.

La correction orthographique peut être divisée en trois tâches principales :

  • En prenant en entrée une phrase, déterminer quels mots sont mal orthographiés.
  • A partir du mot mal orthographié, trouver une liste de candidats pour le remplacer.
  • Choisir le candidat approprié dans la liste. (En cas de correction automatique)

Puisque nous ne nous intéressons qu'aux erreurs non liées aux mots, il suffit de comparer les mots mal orthographiés à ceux du dictionnaire pour déterminer quels sont les mots mal orthographiés.

Sélection des candidats

Il existe plusieurs façons de sélectionner les candidats :

  • L'approche la plus naïve consiste à calculer la distance d'édition que vous avez choisie entre votre mot et l'ensemble de votre dictionnaire. Bien que précise, cette approche est excessivement coûteuse.
  • Algorithmes phonétiques[2] tels que Soundex, Phonex ou Metaphone. Ces algorithmes codent n'importe quelle chaîne de caractères en une courte séquence qui permet d'indexer les chaînes par leur prononciation. Ainsi, "hurry" et "hirry" renverront tous deux "H600". En prétraitant l'ensemble de votre dictionnaire et en l'indexant par code phonétique, vous pouvez facilement trouver des candidats phonétiquement similaires. C'est rapide à l'exécution mais cela ne corrige que les erreurs phonétiques.
  • Calculer une liste de fautes d'orthographe possibles (insertion, suppression, transposition ou remplacement) pour votre mot et la faire correspondre avec votre dictionnaire. Bien que cette méthode soit meilleure que l'approche naïve, elle est assez lente car la taille de la liste des fautes d'orthographe augmente à un rythme de 54 * longueur+25. Voir l'excellent article de Peter Norvig[3] pour plus d'explications.
  • Correction orthographique symétrique qui reprend l'idée précédente et l'étend en calculant les fautes d'orthographe à la fois pour le dictionnaire et pour le mot mal orthographié. Voir Symspell[4] pour plus de détails. Cette technique est à la fois précise et très rapide, mais au prix d'un pré-calcul et d'un espace disque importants, et nécessite une liste de fréquences de votre dictionnaire.

Embedding au niveau des caractères

Nous avons exploré une autre approche de ce problème en utilisant les vecteurs de mots (ou embeddings) pour représenter les mots au niveau des caractères. Les approches populaires d'incorporation de mots, telles que Word2Vec, cherchent à représenter les mots par leur sémantique, ce qui s'avère très utile pour une variété de tâches. Cependant, en utilisant des modèles basés sur les caractères, il est possible de construire un vecteur de mots basé sur l'orthographe des mots.

L'idée est similaire à l'algorithme phonétique qui vise à représenter des mots similaires sous la même métrique unique (une chaîne ou un nombre à virgule flottante) mais nous étendons l'idée en utilisant un vecteur à n dimensions.

Notre approche est la suivante :

  • Entraîner un modèle pour produire des encastrements de mots au niveau des caractères.
  • Vectoriser notre dictionnaire entier et construire un index pour une recherche efficace.
  • Vectoriser les mots mal orthographiés et rechercher les plus proches voisins.

Le modèle utilise deux couches de LSTM pour construire un vecteur d'une taille choisie. Une dimension plus élevée fournit des résultats plus précis au prix d'un temps de calcul plus long, pour notre usage nous avons choisi la dimension 150. Le modèle est entraîné en lui passant un tuple de mots qui sont soit deux mots complètement différents, soit un mot et une faute d'orthographe de celui-ci. L'objectif de l'apprentissage est de minimiser la norme de la différence entre les deux enchâssements pour un tuple similaire et de la maximiser pour des mots différents.

Les données d'entraînement ont été générées en utilisant un dictionnaire de 600 000 mots et en générant plusieurs fautes d'orthographe de distance d'édition 1 ou 2 pour chaque mot. Nous avons attribué des probabilités plus élevées aux fautes d'orthographe proches des caractères originaux sur un clavier AZERTY (puisque nous travaillons en français) afin que le modèle les favorise. En raison de l'absence de mesures d'entraînement claires, il est difficile de savoir exactement quand arrêter l'entraînement, mais après avoir parcouru quelques millions d'exemples d'entraînement, nous étions satisfaits des résultats.

Une fois entraîné, le modèle peut être utilisé pour vectoriser les mots. En les projetant sur un plan 2D avec PCA, nous pouvons obtenir la visualisation suivante :

The original model we used was developed by IntuitionEngineering.
Le modèle original utilisé a été développé par IntuitionEngineering.

Succès ! Les mots similaires semblent être regroupés dans l'espace vectoriel.

Ce n'est pas très utile en soi, donc nous allons maintenant vectoriser l'ensemble de notre dictionnaire de 600k mots. Ce processus prend environ 10 minutes sur un processeur moderne.

L'étape finale consiste à construire un index qui permet de rechercher efficacement les vecteurs les plus proches. Puisque nous n'avons pas besoin d'une précision de 100% et que nous sommes plus concernés par la vitesse de calcul, nous allons utiliser nmslib[5], une bibliothèque spécialisée dans la recherche ANN (Approximate nearest neighbor).

Cette bibliothèque nous permet de lancer une recherche dans l'index pour un nombre k de plus proches voisins d'un vecteur donné. Nous pouvons ajuster le nombre k de plus proches voisins afin de trouver un équilibre entre la précision et le temps de calcul. Une fois que nous obtenons la liste des plus proches voisins, nous pouvons encore filtrer avec la distance d'édition pour ne garder que les suggestions pertinentes.Ceci nous donne le résultat suivant :

python usage_correction.py 'langqge' (en anglais)

Distance d'édition 1:langqge : ['langage']Edit distance 2:langqge : ['langages', 'lange', 'langé', 'langage']

Résultats

Nous avons testé notre modèle sur un corpus qui a été généré par notre générateur de fautes d'orthographe (environ 4k phrases). Notre métrique sera la précision que nous définissons comme le % de fois où nous attrapons le bon mot dans notre liste de candidats.

Sur l'ensemble du corpus, le modèle chars2vec nous donne une précision de 85% alors que l'algorithme phonétique standard se situe autour de 40%. La combinaison des deux approches nous donne une précision de 90%. Le principal goulot d'étranglement se situe autour des mots de 4 caractères ou moins qui ne sont pas très performants.

Il fallait s'y attendre car :

  • Les mots de cette taille ont beaucoup de voisins à courte distance d'édition.
  • Une faute de frappe dans un mot de 3 lettres a beaucoup plus d'impact que dans un mot de 10 lettres, ce qui rend beaucoup plus difficile pour le modèle de faire correspondre correctement les mots les uns à côté des autres dans l'espace vectoriel.

Choix de correction

Alors que notre exemple précédent nous donne directement la réponse souhaitée, il y a souvent plusieurs candidats à distance de correction et un choix doit être fait.

Nous avons essayé deux approches différentes :

  • Probabiliste : Utiliser une liste de fréquence construite sur un grand corpus et choisir le mot le plus fréquent. L'inconvénient évident est que certains mots peu fréquents peuvent ne jamais être choisis, bien qu'extrêmement simple, cette approche fournit une bonne précision.
  • Sémantique : classer les candidats en fonction de leur similarité sémantique avec les mots environnants dans la phrase. En prenant un saut de gramme pré-entraîné Word2Vec et en calculant la distance moyenne entre l'enchâssement du candidat et les mots environnants (ou la phrase entière). Le calcul de la distance moyenne donne de très bons résultats pour les mots ayant une bonne signification sémantique, mais il n'est pas très efficace pour les mots tels que "there", "I", "are" qui peuvent être utilisés dans n'importe quel contexte.

Empiriquement, nous avons constaté que l'approche sémantique fonctionne assez bien pour les mots longs et moins fréquents et que l'approche probabiliste est meilleure pour les mots plus courts. En combinant les deux approches avec des règles artisanales, nous obtenons un taux de correction d'environ 70 % sur notre corpus généré aléatoirement.

Travaux futurs : N-grams token

Au lieu de choisir entre sémantique et fréquence, l'approche idéale serait de combiner les deux. Ceci peut être réalisé en utilisant des tables de fréquence de mots N-grams.

Pour construire ces tableaux, les séquences consécutives de N mots sont comptées et compilées sur un très grand corpus. La meilleure ressource disponible pour cela est Google Books N-gram[6] qui a été construit en analysant environ 5 millions de livres dans différentes langues.

‘Spelling Correction’ bi-gram occurrences
"Correction orthographique" occurrences bi-gram*.

Les données brutes sont disponibles sur ce lien[7] bien qu'en raison de l'énorme quantité de texte, il faille beaucoup de temps pour les télécharger et les compiler dans un état utilisable.

Conclusion

L'utilisation d'enchâssements au niveau des caractères donne de bonnes performances générales et est particulièrement efficace avec les mots longs. Avec des règles de prétraitement faites à la main et une sélection adéquate des candidats, cela fournit une alternative décente aux solutions existantes pour la correction orthographique.

Les travaux futurs incluront une comparaison avec les solutions populaires existantes et l'utilisation de jetons n-gram. En attendant, ce paquet est libre d'être expérimenté : char2vec[1].

[1] https://github.com/Lettria/Char2Vec

[2] https://en.wikipedia.org/wiki/Phonetic_algorithm

[3] https://norvig.com/spell-correct.html

[4] https://github.com/wolfgarbe/SymSpell

[5] https://github.com/nmslib/nmslib

[6] https://books.google.com/ngrams/

[7] http://storage.googleapis.com/books/ngrams/books/datasetsv2.html

Callout

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere.

This is some text inside of a div block.
This is some text inside of a div block.
This is some text inside of a div block.
This is some text inside of a div block.

Continuer à lire

Voir tous les articles ->
Créez votre pipeline NLP en 2 minutes
Démarrez ->