Tronquer automatiquement un dictionnaire morphologique

From Apertium
Revision as of 00:29, 11 November 2012 by Bech (talk | contribs) (Création page)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

En ce moment nous avons un problème dans Apertium concernant les copies. Quand on commence à créer une nouvelle paire de langues qui est basée sur quelque ressource existant dans Apertium (ex : un Dictionnaire unilingue), alors habituellement on fait une copie de cette ressource, et ensuite on la change selon nos besoins. Ce n'est pas idéal parce que :

  • ça signifie que les améliorations qu'on faites ne sont pas automatiquement transférées vers le dictionnaire qu'on a copié,
  • ça signifie que les améliorations dans le dictionnaire qu'on a copié ne sont pas transférées dans notre nouveau dictionnaire.

Donc pourquoi faisons-nous ça ? -- Test de vocabulaire. Si nous avons des entrées dans notre monodix qui ne sont pas dans notre bidix, alors on obtient beaucoup de @ sur notre sortie. C'est mauvais.

Une façon de contourner le problème est d'utiliser des scripts ad hoc pour tronquer les dictionnaires (voir par exemple : apertium-af-nl, apertium-sme-nob et le script trim-lexc.py dans trunk/apertium-tools), mais ils ne sont pas idéaux car habituellement ils doivent inclure des hacks spécifiques pour des différences dans le format des dictionnaires.

Une autre solution serait de prendre l'intersection de notre monodix et notre bidix, et d'utiliser ça pour l'analyse. C'est ce qui est décrit plus bas.

Note: Cela ne prend pas en compte la totalité du problème de test de vocabulaire. Il resterait encore nécessaire de se débarrasser des symboles #.

Exemple

Supposons que nous avons le dictionnaire unilingue :


<dictionary>
  <alphabet>abcdefghijklmnopqrstuvwxyz</alphabet>
  <sdefs>
    <sdef n="n"/>
    <sdef n="sg"/>
    <sdef n="pl"/>
  </sdefs>
  <pardefs>
    <pardef n="beer__n">
      <e><p><l></l><r><s n="n"/><s n="sg"/></r></p></e>
      <e><p><l>s</l><r><s n="n"/><s n="pl"/></r></p></e>
    </pardef>
  </pardefs>
  <section id="main" type="standard">
    <e lm="beer"><i>beer</i><par n="beer__n"/></e>
    <e lm="school"><i>school</i><par n="beer__n"/></e>
    <e lm="computer"><i>computer</i><par n="beer__n"/></e>
    <e lm="house"><i>house</i><par n="beer__n"/></e>
  </section>
</dictionary>

Il génère les chaînes suivantes :

$ lt-expand test-en.dix
beer:beer<n><sg>
beers:beer<n><pl>
school:school<n><sg>
schools:school<n><pl>
computer:computer<n><sg>
computers:computer<n><pl>
house:house<n><sg>
houses:house<n><pl>

Mais notre bidix contient seulement :

<dictionary>
  <alphabet>abcdefghijklmnopqrstuvwxyz</alphabet>
  <sdefs>
    <sdef n="n"/>
    <sdef n="sg"/>
    <sdef n="pl"/>
  </sdefs>
  <pardefs>
  </pardefs>
  <section id="main" type="standard">
    <e><p><l>beer<s n="n"/></l><r>garagardo<s n="n"/></r></p></e>
    <e><p><l>house<s n="n"/></l><r>etxe<s n="n"/></r></p></e>
  </section>
</dictionary>

On ne veut pas mettre les entrées pour "computer" et "school", parce qu'alors on pourrait obtenir des @ sur notre sortie.

Voici un Makefile qui étant donné deux dictionnaires test-en.dix (le monodix) et test-en-eu.dix (le bidix), va produire un transducteur binaire du monodix (dans le format HFST pour l'instant) qui contient seulement les chaînes correspondant aux préfixes dans le bidix.

all:
	lt-comp lr test-en.dix test-en.bin
	lt-comp lr test-en-eu.dix test-en-eu.bin
	lt-print test-en.bin > test-en.att
	lt-print test-en-eu.bin > test-en-eu.att
	hfst-txt2fst -e ε <  test-en.att > test-en.fst
	hfst-txt2fst -e ε <  test-en-eu.att > test-en-eu.fst
	hfst-invert test-en.fst -o test-en.mor.fst
	hfst-project -p upper test-en-eu.fst > test-en-eu.en.fst
	echo " ?* " | hfst-regexp2fst > any.fst
	hfst-concatenate -1 test-en-eu.en.fst -2 any.fst -o test-en-eu.en-prefixes.fst
	hfst-compose-intersect -1 test-en-eu.en-prefixes.fst -2 test-en.mor.fst | hfst-invert -o test-en.trimmed.fst


clean:
	rm *.bin *.att *.fst

Si on lance hfst-fst2strings, on obtient :

$ hfst-fst2strings test-en.trimmed.fst
beer:beer<n><sg>
beers:beer<n><pl>
house:house<n><sg>
houses:house<n><pl>

Comment implémenter ça dans lttoolbox directement

Ça pourrait être bien de le voir comme :

$ lt-comp rl apertium-en-ca.en-ca.dix ca-en.autobil.bin

$ lt-comp lr apertium-en-ca.ca.dix ca-en.automorf.bin ca-en.autobil.bin

où le coté gauche du second transducteur (ca-en.autobil.bin) est converti en préfixes, et seulement les chaînes du premier transducteur qui correspondent aux préfixes dans le second transducteur sont inclues dans la compilation finale.

Voir aussi