Fabriquer des dictionnaires
Certains d'entre vous ont été assez braves pour commencer à écrire de nouvelles paires de langues pour Apertium. Ça me rend (et toute l'équipe d'Apertium) très content et reconnaissant, mais plus important encore, ça rend Apertium utile pour davantage de monde.
Je veux partager quelques leçons que j'ai tirées de la construction de plusieurs dictionnaires : l'importance des estimations de fréquence. Pour les nouvelles paires pour avoir la couverture la meilleure possible avec un minimum d'effort, il est très important de rajouter les mots et les règles par ordre décroissant de fréquence,, en commençant par les mots et les phénomènes les plus fréquents.
La raison pour laquelle les mots devraient être rajoutés par ordre de fréquence est assez intuitive : plus la fréquence est élevée, plus le mot a des chances d'apparaître dans le texte que vous essayez de traduire (voir ci-dessous pour la loi de Zipf).
Par exemple, en anglais vous pouvez être pratiquement sûr que les mots "the" ou "a" apparaîtront partout même dans les phrases les plus simples; par contre, combien de fois avez-vous vu "hypothyroidism" ou "obelisk" écrit ? Plus la fréquence du mot est élevée, plus vous "gagnez" à l'ajouter.
Contents
Fréquence
L'intuition d'une personne pour laquelle les mots sont importants ou fréquents peut être très décevante. Par conséquent, le mieux qu'on puisse faire est de récupérer beaucoup de texte (des millions de mots, si possible) qui sont représentatifs de ce que l'on veut traduire, et d'étudier la fréquence des mots et des phénomènes. Récupérez les de Wikipedia ou d'une archive de journal, ou écrivez un robot qui les récupère sur le Web.
Il est assez facile de faire un "hit parade" brut des mots en utilisant une séquence de commandes Unix simple (une seule ligne) :
$ cat monfichierrepresentatif.txt | tr ' ' '\012' | sort -f | uniq -c | sort -nr > hitparade.txt
[J'ai tiré ça de Unix for Poets, je pense.]
Bien sûr, ça peut être bien amélioré mais ça sert à des buts d'illustration.
Vous allez trouver d'intéressantes propriétés à cette liste. L'une d'elle c'est qu'en multipliant le rang d'un mot par sa fréquence, vous obtenez un nombre qui est à peu près constant. On appelle ça la loi de Zipf.
Une autre est que la moitié de la liste est hapax legomena (des mots qui n'apparaissent qu'une fois).
Troisièmement, avec environ 1,000 mots vous devriez avoir 75% du texte couvert.
Donc utilisez les listes comme celles-ci quand vous construisez des dictionnaires.
Si l'une de vos langues est l'anglais, il y a des listes intéressantes :
Gardez à l'esprit, bien sûr, que ces listes sont également basées sur un modèle particulier d'utilisation de l'anglais, qui n'est pas l'anglais "qui vient naturellement".
La même chose s'applique aux autres phénomènes linguistiques. Les linguistes ont tendance à se focaliser sur des phénomènes très rares qui sont les clés de l'identité d'une langue, ou sur ce qui est différent entre les langues. Mais ces "bijoux" ne sont généralement pas les "blocs de construction" que vous utiliseriez pour créer des règles de traduction. Donc, ne vous emballez pas. Faites seulement confiance aux fréquences et à la grande quantité de vrai texte.
Récupérateur de corpus
Dumps Wikipedia
Pour de l'aide pour les traiter, voir :
The dumps need cleaning up (removing Wiki syntax and XML etc.), but can provide a substantial amount of text — both for fréquence analysis and as a source of sentences for POS tagger training. It can take some work, and isn't as easy as getting a nice corpus, but on the other hand they're available in some 275 languages with at least 100 articles written in each.
You'll want the one entitled "Articles, templates, image descriptions, and primary meta-pages. -- This contains current versions of article content, and is the archive most mirror sites will probably want."
Something like (for Afrikaans):
$ bzcat afwiki-20070508-pages-articles.xml.bz2 | grep '^[A-Z]' | sed 's/$/\n/g' | sed 's/\[\[.*|//g' | sed 's/\]\]//g' | sed 's/\[\[//g' | sed 's/&.*;/ /g'
This will give you approximately useful lists of one sentence per line (stripping out most of the extraneous formatting). Note, this presumes that your language uses the Latin alphabet; if it uses another writing system, you'll need to change that.
Try something like (for Afrikaans):
$ bzcat afwiki-20070508-pages-articles.xml.bz2 | grep '^[A-Z]' | sed 's/$/\n/g' | sed 's/\[\[.*|//g' | sed 's/\]\]//g' | sed 's/\[\[//g' | sed 's/&.*;/ /g' | tr ' ' '\012' | sort -f | uniq -c | sort -nr > hitparade.txt
Once you have this 'hitparade' of words, it is first probably best to skim off the top 20,000–30,000 into a separate file.
$ cat hitparade.txt | head -20000 > top.lista.20000.txt
Now, if you already have been working on a dictionary, chances are that there will exist in this 'top list' words you have already added. You can remove word forms you are already able to analyse using (for example Afrikaans):
$ cat top.lista.20000.txt | apertium-destxt | lt-proc af-en.automorf.bin | apertium-retxt | grep '\/\*' > words_to_be_added.txt
(here lt-proc af-en.automorf.bin
will analyse the input stream of Afrikaans words and put an asterisk * on those it doesn't recognise)
For every 10 words or so you add, it's probably worth going back and repeating this step, especially for highly inflected languages — as one lemma can produce many word forms, and the wordlist is not lemmatised.
Getting cheap bilingual dictionary entries
A cheap way of getting bilingual dictionary entries between a pair of languages is as follows:
First grab yourself a wordlist of nouns in language x; for example, grab them out of the Apertium dictionary you are using:
$ cat <monolingual dictionary> | grep '<i>' | grep '__n\"' | awk -F'"' '{print $2}'
Next, write a basic script, something like:
#!/bin/sh #language to translate from LANGF=$2 #language to translate to LANGT=$3 #filename of wordlist LIST=$1 for LWORD in `cat $LIST`; do TEXT=`wget -q http://$LANGF.wikipedia.org/wiki/$LWORD -O - | grep 'interwiki-'$LANGT`; if [ $? -eq '0' ]; then RWORD=`echo $TEXT | cut -f4 -d'"' | cut -f5 -d'/' | python -c 'import urllib, sys; print urllib.unquote(sys.stdin.read());' | sed 's/(\w*)//g'`; echo '<e><p><l>'$LWORD'<s n="n"/></l><r>'$RWORD'<s n="n"/></r></p></e>'; fi; sleep 8; done
Note: The "sleep 8" is so that we don't put undue strain on the Wikimedia servers.
If you save this as iw-word.sh
, then you can use it at the command line:
$ sh iw-word.sh <wordlist> <language code from> <language code to>
Fr example, to retrieve a bilingual wordlist from English to Afrikaans, use:
$ sh iw-word.sh en-af.wordlist en af
The method is of variable reliability. Reports of between 70% and 80% accuracy are common. It is best for unambiguous terms, but works all right where terms retain ambiguity through languages.
Any correspondences produced by this method must be checked by native or fluent speakers of the language pairs in question.
Monodix
- Main article: Monodix
If the language you're working with is fairly regular, and noun inflection is quite easy (for example English or Afrikaans), then the following script may be useful:
You'll need a large wordlist (of all forms, not just lemmata) and some existing paradigms. It works by first taking all singular forms out of the list, then looking for plural forms, then printing out those which have both singular and plural forms in Apertium format.
Note: These will need to be checked, as no language except Esperanto is that regular.
# set this to the location of your wordlist WORDLIST=/home/spectre/corpora/afrikaans-meester-utf8.txt # set the paradigm, and the singular and plural endings. PARADIGM=sa/ak__n SINGULAR=aak PLURAL=ake # set this to the number of characters that need to be kept from the singular form. # e.g. [0:-1] means 'cut off one character', [0:-2] means 'cut off two characters' etc. ECHAR=`echo -n $SINGULAR | python -c 'import sys; print sys.stdin.read().decode("utf8")[0:-1];' PLURALS=`cat $WORDLIST | grep $PLURAL$` SINGULARS=`cat $WORDLIST | grep $SINGULAR$` CROSSOVER="" for word in $PLURALS; do SFORM=`echo $word | sed "s/$PLURAL/$SINGULAR/g"` cat $WORDLIST | grep ^$SFORM$ > /dev/null # if the form is found then append it to the list if [ $? -eq 0 ]; then CROSSOVER=$CROSSOVER" "$SFORM fi done # print out the list for pair in $CROSSOVER; do echo ' <e lm="'$pair'"><i>'`echo $pair | sed "s/$SINGULAR/$ECHAR/g"`'</i><par n="'$PARADIGM'"/></e>'; done
Voir aussi
Further reading
- Mark Pagel, Quentin D. Atkinson & Andrew Meade (2007) "fréquence of word-use predicts rates of lexical evolution throughout Indo-European history". Nature 449, 665
- "Across all 200 meanings, frequently used words evolve at slower rates and infrequently used words evolve more rapidly. This relationship holds separately and identically across parts of speech for each of the four language corpora, and accounts for approximately 50% of the variation in historical rates of lexical replacement. We propose that the fréquence with which specific words are used in everyday language exerts a general and law-like influence on their rates of evolution."