Difference between revisions of "Crearea unui dictionar folosind HFST"
Line 9: | Line 9: | ||
==Introducere== |
==Introducere== |
||
Un analizator morfologic HFST are două fişiere cu reguli, unul dintre ele este <code>lexc</code>. Acesta defineşte modul în care sunt formate cuvintele din |
Un analizator morfologic HFST are două fişiere cu reguli, unul dintre ele este <code>lexc</code>. Acesta defineşte modul în care sunt formate cuvintele din [http://ro.wikipedia.org/wiki/Morfem morfeme]. De exemplu, cuvântul <code>lup + i</code> devine <code>lupi</code>. |
||
Cel de-al doilea fişier poate fi unul <code>twol</code> (two-level rules) sau unul <code>xfst</code> (reguli de rescriere secvenţiale). Acestea prezintă ce se întâmplă când morfemele formează cuvântul. Ca exemplu poate fi folosit <code>lup<n><pl></code> → <code>lup + i</code>. |
Cel de-al doilea fişier poate fi unul <code>twol</code> (two-level rules) sau unul <code>xfst</code> (reguli de rescriere secvenţiale). Acestea prezintă ce se întâmplă când morfemele formează cuvântul. Ca exemplu poate fi folosit <code>lup<n><pl></code> → <code>lup + i</code>. |
||
Noi vom lucra pe această pagină cu tipul <code>twol</code>, cel cu reguli pe două nivele. Dacă sunteţi interesat de <code>xfst</code>, puteţi găsi un [http://foma.sourceforge.net/dokuwiki/doku.php?id=wiki:morphtutorial tutorial] pe |
Noi vom lucra pe această pagină cu tipul <code>twol</code>, cel cu reguli pe două nivele. Dacă sunteţi interesat de <code>xfst</code>, puteţi găsi un [http://foma.sourceforge.net/dokuwiki/doku.php?id=wiki:morphtutorial tutorial] pe [Foma această pagină]. |
||
În următoarele secţiuni vom începe cu vocabularul (fişierul <code>lexc</code>), iar apoi vom trece la fişierul <code>twol</code>. |
În următoarele secţiuni vom începe cu vocabularul (fişierul <code>lexc</code>), iar apoi vom trece la fişierul <code>twol</code>. |
||
Mai întâi este necesar să compilaţi [[Hfst#Compiling_HFST3 |
Mai întâi este necesar să compilaţi [[Hfst#Compiling_HFST3 HFST3]]. |
||
==Limba== |
==Limba== |
||
Line 24: | Line 24: | ||
===Armonia vocalică=== |
===Armonia vocalică=== |
||
Simplificând mult, deoarece <ref>Acest subiect este foarte complicat, dar pentru un exemplu didactic, este de ajuns</ref>, se poate spune că în limba turkmenistană cuvintele de bază pot fi de două tipuri: cu |
Simplificând mult, deoarece <ref>Acest subiect este foarte complicat, dar pentru un exemplu didactic, este de ajuns</ref>, se poate spune că în limba turkmenistană cuvintele de bază pot fi de două tipuri: cu [http://ro.wikipedia.org/wiki/Vocal%C4%83_posterioar%C4%83 vocale superioare] sau cu [[http://ro.wikipedia.org/wiki/Vocal%C4%83_anterioar%C4%83|vocale anterioare]]. De exemplu ''mugallym'' "profesor" are doar vocale anterioare, iar ''kädi'' "dovleac" are doar vocale posterioare. Vocalele anterioare sunt: ''a, y, o,'' şi ''u''. Cele posterioare sunt: '' ä, e, i, ö,'' şi ''ü''. |
||
Deci, când adăugam unui cuvânt de bază un sufix, trebuie să ştim ce tip de vocale conţine cuvântul pentru a alege vocala potrivită pentru sufix. |
Deci, când adăugam unui cuvânt de bază un sufix, trebuie să ştim ce tip de vocale conţine cuvântul pentru a alege vocala potrivită pentru sufix. |
Revision as of 16:21, 23 November 2011
- Pentru mai multe informaţii despre instalarea formatului HFST, apăsaţi aici.
Această pagină vă va prezenta cum să creaţi un nou dicţionar folosind HFST. Se pot găsi şi referinţe foarte utile cu privire la formalismele lexc şi twol, precum FSMBook, dar majoritatea lor folosesc implementaţia Xerox, nu cea gratuită oferită de HFST.
Deşi formalismele actuale sunt mai mult sau mai puţin asemănătoare, comenzile folosite pentru compilarea lor nu sunt tot timpul aceleași. HFST este bazat pe compatibilitatea cu sistemele de operare Unix. Noi vom profita de acest avantaj. Deoarece la majoritatea limbilor indo-europene şi cele simpliste pot fi tratate cu uşurinţă de lttoolbox, noi vom încerca să abordăm o limbă care nu face parte din această familie, una care are o morfologie complexă şi nu poate fi tratată cu uşurinţă de lttoolbox.
Introducere
Un analizator morfologic HFST are două fişiere cu reguli, unul dintre ele este lexc
. Acesta defineşte modul în care sunt formate cuvintele din morfeme. De exemplu, cuvântul lup + i
devine lupi
.
Cel de-al doilea fişier poate fi unul twol
(two-level rules) sau unul xfst
(reguli de rescriere secvenţiale). Acestea prezintă ce se întâmplă când morfemele formează cuvântul. Ca exemplu poate fi folosit lup<n><pl>
→ lup + i
.
Noi vom lucra pe această pagină cu tipul twol
, cel cu reguli pe două nivele. Dacă sunteţi interesat de xfst
, puteţi găsi un tutorial pe [Foma această pagină].
În următoarele secţiuni vom începe cu vocabularul (fişierul lexc
), iar apoi vom trece la fişierul twol
.
Mai întâi este necesar să compilaţi Hfst#Compiling_HFST3 HFST3.
Limba
Limba pe care o vom folosi este cea vorbită în Turkmenistan, o limbă derivată din cea turcă. Vom lucra pe perechea de limbi turcă-turkmenistană. Vom încerca să schimbăm numărul şi cazul substantivelor. Substantivul în turkmenistană poate avea şase cazuri, 2 genuri şi posesiv. Sufixele pot avea forme diferite în funcţie de sfârşitul cuvântului de bază: dacă e vocală sau consoană.
Armonia vocalică
Simplificând mult, deoarece [1], se poate spune că în limba turkmenistană cuvintele de bază pot fi de două tipuri: cu vocale superioare sau cu [anterioare]. De exemplu mugallym "profesor" are doar vocale anterioare, iar kädi "dovleac" are doar vocale posterioare. Vocalele anterioare sunt: a, y, o, şi u. Cele posterioare sunt: ä, e, i, ö, şi ü.
Deci, când adăugam unui cuvânt de bază un sufix, trebuie să ştim ce tip de vocale conţine cuvântul pentru a alege vocala potrivită pentru sufix.
Number
Number in Turkmen can either be undefined (where there is no suffix) or plural, where the suffix is -lar or -ler. The first is used with back vowels, and the second with front vowels.
Case
We use a more compact representation below to show the suffixes for case. In between { and } are vowel alternations in the suffixes, and in between ( and ) are epentheses.
Case | Suffix | Usage | Example | ||
---|---|---|---|---|---|
V | C | V | C | ||
Nominative | Indicates the subject of the sentence | pagta | gazan | ||
Genitive | -n{y,i,u,ü}ň | -{y,i,u,ü}ň | Indicates possession | pagtanyň | gazanyň |
Dative | -{a,ä} , -n{a,e} | -{a,e} | Indirect object (directed action) | pagta | gazana |
Accusative | -n{y,i} | -{y,i} | Direct object | pagtany | gazany |
Inessive | -(n)d{a,e} | -d{a,e} | Time/place | pagtada | gazanda |
Instrumental | -(n)d{a,e}n | -d{a,e}n | Origin | pagtadan | gazandan |
Full paradigm
Note: This does not include the possessive.
maşgala "family" | ||
---|---|---|
Case | Singular | Plural |
Nominative | maşgala | maşgalalar |
Genitive | maşgalanyň | maşgalalaryň |
Dative | maşgala | maşgalalara |
Accusative | maşgalany | maşgalalary |
Inessive | maşgalada | maşgalalarda |
Instrumental | maşgaladan | maşgalalardan |
esger "soldier" | ||
---|---|---|
Case | Singular | Plural |
Nominative | esger | esgerler |
Genitive | esgeriň | esgerleriň |
Dative | esgere | esgerlere |
Accusative | esgeri | esgerleri |
Inessive | esgerde | esgerlerde |
Instrumental | esgerden | esgerlerden |
Lexicon
So, after going through the little description above, let's start with the lexicon. The file we're going to make is called apertium-tr-tk.tk.lexc
, and it will contain the lexicon of the transducer. So open up your text editor.
The basics
The first thing we need to define are the tags that we want to produce. In lttoolbox, this is done through the <sdefs>
section of the .dix
file.
Multichar_Symbols %<n%> ! Noun %<nom%> ! Nominative %<pl%> ! Plural
The symbols <
and >
are reserved in lexc
, so we need to escape them with %
We also need to define a Root
lexicon, which is going to point to a list of stems in the lexicon NounStems
. The Root
lexicon is analagous to the <section id="main" type="standard">
in lttoolbox:
LEXICON Root NounStems ;
Now let's add our two words:
LEXICON NounStems maşgala Ninfl ; ! "family" esger Ninfl ; ! "soldier"
First we put the stem, then we put the paradigm (or continuation class) that it belongs to, in this case Ninfl
, and finally, in a comment (the comment symbol is !
) we put the translation.
And define the most basic of inflection, that is, tagging the bare stem with <n>
to indicate a noun:
LEXICON Ninfl %<n%>: # ;
This LEXICON
should go before the NounStems
lexicon. The #
symbol is the end-of-word boundary. It is very important to have this, as it tells the transducer where to stop.
Compiling
So, now we've got our basic lexicon, let's compile it and test it. We compile with hfst-lexc
:
$ hfst-lexc apertium-tr-tk.tk.lexc > tk-tr.lexc.hfst
And we can test it both with hfst-fst2strings
:
$ hfst-fst2strings tk-tr.lexc.hfst maşgala<n>:maşgala esger<n>:esger
Continuation lexica
So, we've managed to describe that maşgala and esger are nouns, but what about the inflection. This is where continuation lexica come in. These are like paradigms in lttoolbox.
The basic morphotactics of the Turkmen noun is:
- stem plural? possessive? case copula?
Where ?
denotes optionality. We're just working with number and case here, so let's describe the inflection, first we can start with number. In the section of the file LEXICON Ninfl
, add the following line:
%<n%>%<pl%>:%>l%{A%}r # ;
Phew, that looks pretty complicated!! Well, perhaps, but each part has it's reason, let's describe them:
Part | Description |
---|---|
%<n%>%<pl%> |
The part on the left side defines the analysis, in this case noun, plural. Note, this is in contrast to lttoolbox, where the analysis is usually on the right side. |
: |
The symbol : delimits the left and right sides (or surface side, and lexical side)
|
%>%>l%{A%}r |
This is the surface form, which is split into: |
%> |
The morpheme boundary delimiter (we'll talk about this later, but you put it in between morphemes where changes might happen. |
l%{A%}r |
The surface morpheme, in this case -lar or -ler |
%{A%} |
An "archivowel"... a placeholder for a vowel that can be either a or e |
# |
The end of word boundary |
; |
End of line |
Part of the reason it looks complicated is all of the %
symbols. If we remove them it looks far more readable:
<n><pl>:>l{A}r # ;
(You need to have them though)
For comparison, in lttoolbox (using · for morpheme boundary and for the {A}) for , this would look something like:
<e><p><l>·l<s n="A"/>r</l><r><s n="n"/><s n="pl"/></e>
So, we've added the first of our inflections, the plural. We need to do two things before we can test it. First we need to add %{A%}
to the Multichar_Symbols
section of the file, so scroll to the top and add it, you should get something like:
Multichar_Symbols %<n%> ! Noun %<nom%> ! Nominative %<pl%> ! Plural %{A%} ! Archivowel 'a' or 'e'
Now save the file. The next thing we need to do is compile again:
$ hfst-lexc apertium-tr-tk.tk.lexc > tk-tr.lexc.hfst
And then we can test:
$ hfst-fst2strings tk-tr.lexc.hfst maşgala<n><pl>:maşgala>l{A}r maşgala<n>:maşgala esger<n><pl>:esger>l{A}r esger<n>:esger
Ok, so this is cool, but it also kind of sucks, these aren't real surface forms. We'll never see esger>l{A}r in any text. The surface form we're looking for is esgerler. So how do we get that ?
Enter twol
The idea of twol
is to take the surface forms produced by lexc and apply rules to them to change them into real surface forms. So, this is where we change -l{A}r into -lar or -ler.
What we basically want to say is "if the stem contains front vowels, then we want the front vowel alternation, if it contains back vowels then we want the back vowel alternation". And at the same time, remove the morpheme boundary. So let's give it a shot.
We're going to make a new file apertium-tr-tk.tk.twol
.
First we need to define the alphabet:
Alphabet A B Ç D E Ä F G H I J Ž K L M N Ň O Ö P R S Ş T U Ü W Y Ý Z a b ç d e ä f g h i j ž k l m n ň o ö p r s ş t u ü w y ý z %{A%}:a ;
You don't have to define the upper and lower case on separate lines, but it can help make it clearer.
We also want to define at this point, that whatever happens, we want to remove the morpheme boundaries %>
from the surface forms, so add the following line just below the last line of lower case letters, and before the ;
:
%>:0
Here, the left side is the morphotactic form, and the right side is the surface form. Doing %>:0
changes %>
into 0
, which is the same as deleting it. The 0
symbol is not output.
So, the final alphabet section will look like this:
Alphabet A B Ç D E Ä F G H I J Ž K L M N Ň O Ö P R S Ş T U Ü W Y Ý Z a b ç d e ä f g h i j ž k l m n ň o ö p r s ş t u ü w y ý z %{A%}:a %>:0 ;
Next we need to define some "sets" to work with, these are basically for giving mnemonics to features, like "front vowel" and "back vowel" which we want to refer to later in the rules:
Sets Consonant = B Ç D F G H J Ž K L M N Ň P R S Ş T W Z b ç d f g h j ž k l m n ň p r s ş t w z ; Vowel = A E Ä I O Ö U Ü Y Ý a e ä i o ö u ü y ý ; FrontVowel = Ä E I Ö Ü ä e i ö ü ; BackVowel = A Y O U a y o u ; NonBack = Consonant FrontVowel %> ; NonFront = Consonant BackVowel %> ;
So now we've got everything set up, to add the rule, there is a new section, Rules
:
Rules "Front harmony in suffixes" %{A%}:e <=> FrontVowel: NonBack:* %>: NonBack:* _ ;
The rule is basically saying: "Substitute {A} with e if the previous letters are anything except back vowels, then there is a morpheme boundary, then there are no back vowels, and at some point there is a front vowel"
Next up, to compile the rule and test it:
$ hfst-twolc -R -i apertium-tr-tk.tk.twol -o tk-tr.twol.hfst Reading input from tk.twol. Writing output to tk.twol.hfst. Reading alphabet. Reading sets. Reading rules and compiling their contexts and centers. Compiling and storing rules. Compiling rules. Storing rules.
With the power of intersecting composition!
In order to get the final transducer, what we need to do is combine the morphotactic model (lexc
) with the morphographemic model (twol
). There is a way of doing this called "intersecting composition" which is fairly efficient. There is also a tool in HFST called hfst-compose-intersect
which is what we'll be using.
$ hfst-compose-intersect -1 tr-tk.lexc.hfst -2 tr-tk.twol.hfst -o tr-tk.autogen.hfst
Now we can test the final transducer:
$ hfst-fst2strings tr-tk.autogen.hfst maşgala<n>:maşgala maşgala<n><pl>:maşgalalar esger<n>:esger esger<n><pl>:esgerler
Great!! We have the desired forms.
Analysis and generation
The transducer we made above was for generation, but we can't yet use it with hfst-proc
because of the format. If we want to use it with hfst-proc
, all we need to do is change the format, with the following command:
$ hfst-fst2fst -O -i tr-tk.autogen.hfst -o tr-tk.autogen.hfst.ol
Now we should be able to generate both of our plurals:
$ echo "^maşgala<n><pl>$" | hfst-proc -g tr-tk.autogen.hfst.ol maşgalalar
and
$ echo "^esger<n><pl>$" | hfst-proc -g tr-tk.autogen.hfst.ol esgerler
But what if we want to analyse some words ? Well, then we need to invert the transducer. This is changing the left side to the right side, and the right side to the left side, let's do it in two stages so we can see the results:
$ hfst-invert -i tr-tk.autogen.hfst -o tk-tr.automorf.hfst $ hfst-fst2strings tk-mor.hfst maşgala:maşgala<n> maşgalalar:maşgala<n><pl> esger:esger<n> esgerler:esger<n><pl>
As we can see, now the left side is the surface form, and the right side the analysis. Now just to convert the analyser to optimised lookup format:
$ hfst-fst2fst -O -i tk-tr.automorf.hfst -o tk-tr.automorf.hfst.ol
And do some analysis:
$ echo "maşgalalar" | hfst-proc tk-tr.automorf.hfst.ol ^maşgalalar/maşgala<n><pl>$ $ echo "esgerler" | hfst-proc tk-tr.automorf.hfst.ol ^esgerler/esger<n><pl>$
Troubleshooting
Here is a brief troubleshooting checklist for when you do something, but it isn't working:
- Are all your multicharacter symbols defined ? Including archivowels/consonants. If you think you added them, triple check. This goes for problems in
twol
as well as inlexc
.
Notes
- ↑ Acest subiect este foarte complicat, dar pentru un exemplu didactic, este de ajuns