Génération de règles de sélection lexicale depuis un corpus parallèle

From Apertium
Revision as of 14:05, 7 October 2014 by Bech (talk | contribs) (Lien page anglaise)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

In English

Si vous avez un corpus parallèle, une des choses que vous pouvez faire est de générer quelques règles de sélection lexicale à partir de lui, pour améliorer la traduction des mots avec plus d'une traduction possible.

Vous aurez besoin

Voici une liste de logiciels que vous aurez besoin d'installer :

Plus tard vous aurez besoin :

  • d'une paire de langues Apertium
  • d'un corpus parallèle (voir Corpora)

Pour démarrer

Nous alors faire l'exemple avec EuroParl et la paire anglais vers espagnol d'Apertium.

En supposant que vous avez installé tout le nécessaire, le travail sera le suivant :

Préparer le corpus

Pour générer les règles, on a besoin de trois fichiers,

  • Le corpus source balisé et marqué
  • Le corpus cible balisé et marqué
  • La sortie du module de transfert lexical dans la direction source→cible, marquée

Ces trois fichiers devraient avoir leur phrases alignées.

La première chose que vous avez besoin de faire est de nettoyer le corpus, supprimer les longues phrases.

$ perl /home/fran/local/bin/scripts-20120109-1229/training/clean-corpus-n.perl europarl-v6.es-en es en europarl.clean 1 40
clean-corpus.perl: processing europarl-v6.es-en.es & .en to europarl.clean, cutoff 1-40
..........(100000)...

Input sentences: 1786594  Output sentences:  1467708

(Remplacez le chemin /home/fran/local/bin/scripts-20120109-1229/training/ avec celui où vous avez mis les scripts de Moses)

La prochaine chose qu'on a besoin de faire est de baliser les deux cotés du corpus :

$ nohup cat europarl.clean.en | apertium-destxt |\
 apertium -f none -d /home/fran/source/apertium-en-es en-es-pretransfer > europarl.tagged.en &
$ nohup cat europarl.clean.es | apertium-destxt |\
 apertium -f none -d /home/fran/source/apertium-en-es es-en-pretransfer > europarl.tagged.es &

Ensuite on a besoin de supprimer les lignes sans analyse... mais on veut aussi être capable de garder une trace des lignes qu'on a sélectionné du corpus original.

$ seq 1 1467708 > europarl.lines
$ paste europarl.lines europarl.tagged.en europarl.tagged.es | grep '<' | cut -f1 > europarl.lines.new
$ paste europarl.lines europarl.tagged.en europarl.tagged.es | grep '<' | cut -f2 > europarl.tagged.en.new
$ paste europarl.lines europarl.tagged.en europarl.tagged.es | grep '<' | cut -f3 > europarl.tagged.es.new
$ mv europarl.lines.new europarl.lines
$ mv europarl.tagged.en.new europarl.tagged.en
$ mv europarl.tagged.es.new europarl.tagged.es

Ensuite lancer le transfert lexical sur le coté anglais :

$ nohup cat europarl.tagged.en | lt-proc -b ~/source/apertium-en-es/en-es.autobil.bin > europarl.biltrans.en-es &

On va couper le bas (67 658 lignes) pour tester (également parce que Giza++ fait un segfault quelque part autour ce ça).

$ mkdir testing
$ tail -67658 europarl.lines > testing/europarl.67658.lines
$ tail -67658 europarl.tagged.en > testing/europarl.tagged.67658.en
$ tail -67658 europarl.tagged.es > testing/europarl.tagged.67658.es
$  head -1400000 europarl.lines > europarl.lines.new
$  head -1400000 europarl.tagged.en > europarl.tagged.en.new
$  head -1400000 europarl.tagged.es > europarl.tagged.es.new
$  head -1400000 europarl.biltrans.en-es > europarl.biltrans.en-es.new
$  mv europarl.lines.new europarl.lines
$  mv europarl.tagged.en.new europarl.tagged.en
$  mv europarl.tagged.es.new europarl.tagged.es
$  mv europarl.biltrans.en-es.new europarl.biltrans.en-es

Ces fichiers sont :

  • europarl.lines: La liste des lignes incluses dans le corpus à partir du corpus original nettoyé.
  • europarl.tagged.en: Le coté langue source balisé du corpus
  • europarl.tagged.es: Le coté langue cible balisé du corpus
  • europarl.biltrans.en-es: La sortie du transfert lexical langue source → langue cible

Vérifiez qu'ils ont la même longueur :

$ wc -l europarl.*
   1400000 europarl.biltrans.en-es
   1400000 europarl.lines
   1400000 europarl.tagged.en
   1400000 europarl.tagged.es
   5600000 total

La prochaine étape est de les tokeniser(?) dans un format approprié pour Moses, on peut aussi également y mette des balises de replacements. Il y a un couple de scripts dans le répertoire apertium-lex-tools qui fera ça. Note : Si vous ne travaillez pas avec la paire espagnol et anglais vous aurez besoin d'éditer le script process-tagger-output.py pour inclure une table de traduction de toutes les combinaisons de balises qu'on trouve dans votre corpus.

$ nohup cat europarl.tagged.en | python ~/source/apertium-lex-tools/scripts/process-tagger-output.py en > europarl.tag-tok.en&
$ nohup cat europarl.tagged.es | python ~/source/apertium-lex-tools/scripts/process-tagger-output.py es > europarl.tag-tok.es&
$ nohup cat europarl.biltrans.en-es | python ~/source/apertium-lex-tools/scripts/process-biltrans-output.py > europarl.biltrans-tok.en-es &

Aligner le corpus

Maintenant les fichiers de corpus sont prêts, on peut aligner le corpus en utilisant les scripts Moses :

nohup perl ~/local/bin/scripts-20120109-1229/training/train-model.perl -scripts-root-dir \
 /home/fran/local/bin/scripts-20120109-1229/ -root-dir . -corpus europarl.tag-tok \
 -f en -e es -alignment grow-diag-final-and -reordering msd-bidirectional-fe \
 -lm 0:5:/home/fran/corpora/europarl/europarl.lm:0 >log 2>&1 &

Note : N'oubliez pas de changer tous les chemins de la commande ci-dessus !

Vous aurez besoin d'un fichier LM (Note du traducteur : je pense qu'il s'agit du fichier europarl.lm de la commande ci-dessus), mais vous pouvez le copier d'une précédente installation de Moses. Si vous n'en avez pas, faites un fichier vide et mettez quelques mots dedans. On ne va pas utiliser le LM de toutes façon.

Ça prend du temps, probablement autour d'une journée. Donc laissez tourner et allez faire un soufflé, ou coupez du bois ou autre-chose.

Extraire les phrases

La première chose à faire une fois que Moses a fini l'entraînement est de convertir les alignements Giza++ dans un format moins hostile aux humains (et machines) :

$ zcat giza.en-es/en-es.A3.final.gz | ~/source/apertium-lex-tools/scripts/giza-to-moses.awk > europarl.phrasetable.en-es

Ensuite on veut s'assurer de nouveau que notre fichier a le bon nombre de lignes :

$ wc -l europarl.phrasetable.en-es
1400000 europarl.phrasetable.en-es

Puis on veut extraire les phrases où le mot de la langue cible aligné avec un mot de la langue source est une traduction possible dans le dictionnaire bilingue :

$ ~/source/apertium-lex-tools/scripts/extract-sentences.py europarl.phrasetable.en-es europarl.biltrans-tok.en-es \
  > europarl.candidates.en-es

Il y a fondamentalement des phrases dont on peut espérer qu'Apertium sera capable de générer.

Extraire le lexique des fréquences

L'étape suivante consiste à extraire le lexique des fréquences.

$ python ~/source/apertium-lex-tools/scripts/extract-freq-lexicon.py europarl.candidates.en-es > europarl.lex.en-es

Ce fichier devrait ressembler à :

$ cat europarl.lex.en-es  | head 
31381 union<n> unión<n> @
101 union<n> sindicato<n>
1 union<n> situación<n>
1 union<n> monetario<adj>
4 slope<n> pendiente<n> @
1 slope<n> ladera<n>

Où la plus forte fréquence de traduction est marquée avec une @.

Note: Ce lexique des fréquences peut être utilisé comme substitut pour "choisir la traduction la plus générale" dans votre dictionnaire bilingue.

Générer les modèles

Maintenant on génère les ngrammes qu'on va générer depuis les règles.

$ python ~/source/apertium-lex-tools/scripts/ngram-count-patterns.py europarl.lex.en-es europarl.candidates.en-es 2>/dev/null > europarl.ngrams.en-es

Ce script émet des lignes dans le format suivant :

-language<n>	and<cnjcoo> language<n> ,<cm>	lengua<n>	2
+language<n>	plain<adj> language<n> ,<cm>	lenguaje<n>	3
-language<n>	language<n> knowledge<n>	lengua<n>	4
-language<n>	language<n> of<pr> communication<n>	lengua<n>	3
-language<n>	Community<adj> language<n> .<sent>	lengua<n>	5
-language<n>	language<n> in~addition~to<pr> their<det><pos>	lengua<n>	2
-language<n>	every<det><ind> language<n>	lengua<n>	2
+language<n>	and<cnjcoo> *understandable language<n>	lenguaje<n>	2
-language<n>	two<num> language<n>	lengua<n>	8
-language<n>	only<adj> official<adj> language<n>	lengua<n>	2

Les + et - indique si cette ligne choisit la traduction la plus fréquente (-) ou une traduction qui n'est pas la plus fréquente (+). Le modèle sélectionnant la traduction est alors montré, suivi par la traduction et ensuite la fréquence.

Filtrer les règles

Vous pouvez maintenant filtrer les règles, par exemple en supprimant les règles avec conjonctions, ou en supprimant les règles avec mots inconnus.

Générer les règles

L'étape finale consiste à générer les règles,

$ cat europarl.ngrams.en-es| python ~/source/apertium-lex-tools/scripts/ngrams-to-rules.py  > europarl.ngrams.en-es.lrx