• Aucun résultat trouvé

Apprentissage des règles de correction

5.2 Système proposé

5.2.1 Apprentissage des règles de correction

L’apprentissage de nos règles de correction s’appuie sur un corpus de fautes lexi- cales annotées, le corpus WiCoPaCo (Max et Wisniewski, 2010) sur lequel nous reviendrons à la section 5.3.1. Nous verrons notamment comment nous en avons extrait un ensemble de couples de tokens (token altéré, token bien orthographié) correspondant à des fautes lexicales. Un tel ensemble constitue l’entrée de notre système, et nous cherchons à en extraire automatiquement des règles pondérées de correction. Comme indiqué précédemment, nous faisons l’hypothèse que chaque altération est le résultat d’au plus une erreur « lourde ».

Ainsi, pour concevoir nos règles de correction, il nous suffit d’extraire automa- tiquement de chaque couple de tokens les informations suivantes : le contexte gauche complet précédant une altération, l’altération et sa correction, le contexte droit complet suivant l’altération. Précisons qu’afin de prendre en compte les

débuts et fins de tokens au sein du contexte, ces derniers seront marqués par les symboles ##. Ainsi les tokens exempel::exemple, par exemple, seront ici no- tés ##exempel##::##exemple##. L’altération ayant lieu en fin de token, son contexte droit pourra tout de même être pris en compte. Les contextes gauche et droit étant identiques dans le token altéré et dans sa forme bien orthogra- phiée, il est simple d’extraire les séquences de lettres constituant une chaîne de caractères altérée et représentant la correction de cette dernière. Pour le couple ##souevnt##::##souvent## par exemple, l’alignement se fera comme suit :

##sou | ev | nt##

l l l

##sou | ve | nt##

Cet alignement nous permet d’extraire de cette paire de tokens les informations suivantes :

• la zone altérée et sa contrepartie corrigée, c’est-à-dire la chaîne de ca- ractères concernée par la correction avant et après sa modification. Ce sont ces deux chaînes qui sont utilisées pour passer d’un token à un autre. Dans notre exemple, il s’agira de « ev → ve » ;

• le contexte dans lequel s’applique cette substitution. Dans notre exemple, on obtiendra pour contexte gauche « sou » et pour contexte droit « nt ». Une règle peut ensuite, à partir de ces données, être inférée comme suit : {##sou}{ev→ve}{nt##}. Il apparaît toutefois que cette règle est trop spécifique par le contexte qu’elle sélectionne. Elle ne s’appliquera à aucune autre altération. A contrario, une règle trop large, par exemple sans prise en compte du contexte, surcorrigerait. Afin d’éviter chacun de ces cas, nous avons construit plusieurs jeux de règles généralisant de façons différentes des règles individuelles directement extraites des altérations, ou règles de base.

Lorsque l’on souhaite généraliser une règle de correction, nous pouvons procéder de trois manières. En effet, nous pouvons choisir de :

1. privilégier la précision de notre système en choisissant de construire des règles spécifiques en généralisant faiblement les règles de base,

2. avantager le rappel de notre système en proposant des règles plus larges, en généralisant fortement les règles de base,

3. favoriser clairement le rappel de notre système en proposant des règles gé- nériques induites sans corpus d’apprentissage. Les candidats suggérés pour- raient alors être pondérés en fonction de leur fréquence en corpus.

On peut donc s’interroger ici sur les éléments à prendre en compte afin de généra- liser une règle. Dans ce travail, nous ne voulons pas généraliser la transformation

elle-même4. En effet, cela risquerait de rendre notre système de normalisation bruyant, car il serait alors trop permissif. C’est pourquoi il paraît plus fiable de se concentrer sur la généralisation du contexte dans lequel une transformation est possible. Une première question à se poser concerne alors la taille du contexte à prendre en compte. Un contexte très petit aurait tendance à généraliser la règle de correction mise en place. Un contexte trop long serait quant à lui trop restric- tif. En outre, on peut noter que plus les lettres appartenant au contexte d’une altération sont éloignées des caractères altérés, moins elles seront discriminantes et donc pertinentes. Dans le travail présenté ici, nous proposons de prendre en compte un contexte de longueur constante. Ce choix a notamment l’intérêt de nous permettre de traiter chaque token de manière équivalente.

Dans ce cadre, plusieurs procédés ont été appliqués afin de généraliser un contexte. Nous proposons ainsi de permettre la combinaison des contextes gauche et droit de manière plus tolérante. Par exemple, pour la création d’une même règle de base, nous pourrions parfaitement rassembler ses contextes gauches et ses contextes droits possibles. Une autre idée serait de se concentrer sur la généralisation du contexte en fonction de sa position, de sa distance de la chaîne altérée. Nous pourrions par exemple généraliser la lettre précédant et suivant la zone altérée, afin d’autoriser plusieurs lettres ou catégories de lettres. En effet, il serait possible de regrouper les lettres ou catégories de lettres pouvant être placées à une même position.

De manière plus générale, il est très complexe de proposer une généralisation propre à l’altération produite (proximité clavier, phonétique, autre). Tout d’abord parce que nous ne pouvons pas savoir quelle altération a été produite. Réaliser une ou plusieurs généralisations du contexte adaptées à un ou plusieurs types d’altérations serait alors complexe à mettre en place et à appliquer. De plus, si nous mettons l’accent sur un ou plusieurs types d’altérations, cela se fera forcé- ment au détriment d’autres. Nous pourrions par exemple nous concentrer sur les fautes typographiques (proximité clavier). Dans ce cas, on peut alors supposer que l’altération en question se fera la majorité du temps sur un seul caractère et son contexte, restreint à une lettre avant et après la zone altérée, et qu’elle sera généralisée en fonction du placement des touches sur un clavier. Ce procédé sera probablement efficace pour ce type d’erreur mais clairement pas pour tous les autres types d’altérations. Il en est de même pour les erreurs phonétiques qui, au contraire, n’auraient pas une taille fixe de contexte. Mettre en place un système trop précis ne serait ainsi pas concluant. Par ailleurs, généraliser le contexte en se concentrant à la fois sur les proximités clavier et phonétique serait complexe, car les informations à conserver ne seraient pas de taille régulière et donc diffici- lement positionnable. Par opposition, une solution possible est de généraliser les contextes en nous appuyant sur les notions de consonnes et de voyelles. Ces notions

4. Nous reviendrons toutefois sur le cas spécifique des accents et des cas de duplication de lettres.

se distinguent clairement, linguistiquement, l’une de l’autre de par leurs fonction- nements différents. C’est pourquoi nous avons opté pour cette méthode.

Avant de détailler ces deux jeux de règles, nous avons toutefois besoin de définir quelques termes. Étant donnée une zone altérée, nous appellerons contexte de niveau 1 le contexte formé des deux lettres encadrant immédiatement cette zone (la lettre à sa gauche et celle à sa droite). Nous nommerons contexte de niveau 2 les deux lettres situées à une distance de 2 de la chaîne de caractères altérée, c’est-à-dire les deux lettres encadrant immédiatement le contexte de niveau 1. Ainsi, si nous reprenons la paire de tokens ##souevnt##::##souvent##, qui a pour zone altérée : « ev → ve », le contexte de niveau 1 sera u et n et celui de niveau 2 sera o et n. Plus nous nous éloignons de l’altération réalisée, moins le contexte peut avoir un impact sur elle. Prendre en compte des contextes de niveau 3 ou plus ne serait donc pas réellement pertinent. C’est pour cette raison que nous ne prendrons pas en compte de contexte supérieur dans ce travail.

Nous avons ainsi fait le choix d’apprendre à partir d’un corpus d’entraînement deux jeux de règles dotés de différents niveaux de détail. Le premier, le jeu de règles spécifiques, contiendra des règles assez précises permettant ainsi de favoriser la précision de notre système, tandis que le second, le jeu de règles larges, sera constitué de règles plus générales optimisant ainsi le rappel de notre système. La confection de ces deux premiers jeux de règles est décrite ci-dessous.

• Règles spécifiques : Le premier jeu de règles est produit par une géné- ralisation limitée des règles de base. Ces règles ne conservent que le type (consonne (C), voyelle (V) ou #) des lettres de contexte de niveau 2 mais laisse inchangé le contexte de niveau 1. Ainsi, si l’on rencontre la paire souevnt::souvent lors de l’apprentissage, la règle spécifique qui sera extraite est : {Vu}{ev→ve}{nC}.

Lorsqu’une nouvelle règle spécifique ne diffère d’une autre déjà extraite que par son contexte de niveau 1, nous les fusionnons : leurs contextes droits et gauches sont unifiés. Ceci constitue une généralisation par rap- port aux deux règles prises isolément. Par exemple, si l’altération suivante à traiter est ##machiaevls##::##machiavels##, on obtient la règle de base {Va}{ev→ve}{lC} : la règle de substitution extraite et le contexte de niveau 2 sont identiques à ceux de la règle précédente. Seul le contexte de niveau 1 diffère. Nous fusionnons alors les contextes de niveau 1 par disjonction, la règle obtenue étant alors notée : {V[au]}{ev→ve}{[nl]C}. Cette fusion constitue une généralisation puisque cette règle couvre alors également les règles de base {Vu}{ev→ve}{lC} et {Va}{ev→ve}{nC}, pourtant non extraits. En revanche, dès lors que le contexte de niveau 2 ne correspond pas, nous créons une nouvelle règle. Ainsi, l’altération ##réserev##::##réserve## induira l’ajout d’une nouvelle règle à notre jeu de règles : {Vr}{ev→ve}{##}.

• Règles larges Le second jeu de règles est produit par une généralisation plus forte des règles de base : le contexte de niveau 2 est effacé, et seul le type des lettres du contexte de niveau 1 est conservé. Pour l’altération #souevnt#::#souvent#, la règle large induite sera donc : {V}{ev→ve}{C}. Dans le cas où la même règle de base réapparaît via une autre paire de tokens, le type des contextes concernés sera combiné. Par exemple, si nous avons la paire #evuillez#::#veuillez# alors notre règle précédemment extraite sera généralisée de la sorte {[#V]}{ev→ve}{[CV]}

Nous avons également appliqué certaines généralisations à ces deux jeux de règles, au niveau de la règle de substitution elle-même. Tout d’abord, nous avons géné- ralisé les erreurs de duplication d’une lettre (ex. : « fautte ») et de suppression d’une lettre doublée (ex. : « ereur »), en les représentant comme suit :

(2) fautte::faute : {Vt}{+_→_}{e#} (3) ereur::erreur : {Vr}{_→+_}{eV}

S’il s’agit d’une erreur de duplication de lettre ainsi que l’illustre l’exemple 2, la chaîne de caractères altérée sera réécrite dans notre règle de transformation comme la concaténation du symbole + et d’un tiret bas. Le symbole + étant à gauche de ce tiret bas, il signifiera que le contexte gauche de niveau 1 a été dupliqué. Si à présent, la chaîne de caractères +_ correspond à la chaîne de caractères normalisée, dans ce cas cela signifiera que le contexte gauche de niveau 1 doit être dupliqué comme le montre l’exemple 3. Ainsi, en fonction de si la chaîne « +_ » est à gauche ou à droite de la flèche, on couvre ainsi respectivement les cas de duplication manquante et de duplication erronée. Ce procédé nous permet de nous concentrer non pas sur la lettre impactée mais sur l’opération elle-même.

Enfin, nous avons généralisé les fautes d’accents et de cédille. Pour ce faire, nous représentons une lettre accentuée par la combinaison de deux caractères : l’accent en question suivi de la lettre concernée. Ainsi, nous noterons le token arrêt comme ceci : « arrˆet » et, pour l’altération arret, nous obtiendrons la règle large suivante : « {C}{_→ˆ}{V} », qui couvre le rajout d’un accent circonflexe sur toute voyelle, pour peu que les contextes correspondent.

Ainsi, pour construire ces deux jeux de règles, nous parcourons chaque couple (token mal orthographié, token corrigé) du corpus annoté et nous extrayons les règles spécifiques et larges comme décrit ci-dessus. Toutes ces règles sont pondérées comme suit. Dès qu’une règle est extraite ou modifiée par un couple, son nombre d’occurrences est incrémenté de 1. Nous prenons alors le logarithme de ce nombre d’occurrences, puis nous le normalisons par transformation affine entre 0 (règle au nombre d’occurrences minimal) et 1 (règle au nombre d’occurrences maximal). Le résultat constitue le poids de la règle. La table 5.1 illustre quelques exemples de règles de correction apprises par notre système.

Type Règle Poids Exemple Spécif. {V[pfnlmctbsredg]}{_→+_}{[aieuonyr]C} 0,970 atendre→attendre

{V[rmltdvcsnpyxg]}{a → e}{[nmilu]C} 0,660 ralantir→ralentir Large {C}{io → oi}{C} 0,298 tiole → toile

{´ → ` }{V} 0,738 éléve → élève

Table 5.1 – Exemples de règles de correction extraites