I'm using an open source program called MElt which lemmatize (give the lemma example:giving-->give) of words. MElt works on Linux and it's programmed in Perl and Python. So far it's working good but it take way too much time to give the results. I looked into the code and located the loop responsible for this:
while (<LEFFF>) {
chomp;
s/ /_/g;
# s/(\S)-(\S)/\1_-_\2/g;
/^(.*?)\t(.*?)\t(.*?)(\t|$)/ || next;
$form = $1; $cats = $2; $lemma = $3;
#print "$form \n";
#print "$cats \n";
#print "$lemma \n";
if ($lower_case_lemmas) {
$lemma = lc($lemma);
}
if ($it_mapping) {
next if ($form =~ /^.+'$/);
next if ($form eq "dato" && $lemma eq "datare"); # bourrin
next if ($form eq "stato" && $lemma eq "stare"); # bourrin
next if ($form eq "stata" && $lemma eq "stare"); # bourrin
next if ($form eq "parti" && $lemma eq "parto"); # bourrin
if ($cats =~ /^(parentf|parento|poncts|ponctw)$/) {$cats = "PUNCT"}
if ($cats =~ /^(PRO)$/) {$cats = "PRON"}
if ($cats =~ /^(ARTPRE)$/) {$cats = "PREDET"}
if ($cats =~ /^(VER|ASP|AUX|CAU)$/) {$cats = "VERB"}
if ($cats =~ /^(CON)$/) {$cats = "CONJ"}
if ($cats =~ /^(PRE)$/) {$cats = "PREP"}
if ($cats =~ /^(DET)$/) {$cats = "ADJ"}
if ($cats =~ /^(WH)$/) {$cats = "PRON|CONJ"}
next if ($form =~ /^(una|la|le|gli|agli|ai|al|alla|alle|col|dagli|dai|dal|dalla|dalle|degli|dei|del|della|delle|dello|nei|nel|nella|nelle|nello|sul|sulla)$/ && $cats eq "ART");
next if ($form =~ /^quest[aei]$/ && $cats eq "ADJ");
next if ($form =~ /^quest[aei]$/ && $cats eq "PRON");
next if ($form =~ /^quell[aei]$/ && $cats eq "ADJ");
next if ($form =~ /^quell[aei]$/ && $cats eq "PRON");
next if ($form =~ /^ad$/ && $cats eq "PREP");
next if ($form =~ /^[oe]d$/ && $cats eq "CONJ");
}
$qmlemma = quotemeta ($lemma);
for $cat (split /\|/, $cats) {
if (defined ($cat_form2lemma{$cat}) && defined ($cat_form2lemma{$cat}{$form}) && $cat_form2lemma{$cat}{$form} !~ /(^|\|)$qmlemma(\||$)/) {
$cat_form2lemma{$cat}{$form} .= "|$lemma";
} else {
$cat_form2lemma{$cat}{$form} = "$lemma";
$form_lemma_suffs = "@".$form."###@".$lemma;
while ($form_lemma_suffs =~ s/^(.)(.+)###\1(.+)/\2###\3/) {
if (length($2) <= 8) {
$cat_formsuff_lemmasuff2count{$cat}{$2}{$3}++;
if ($multiple_lemmas) {
$cat_formsuff_lemmasuff2count{$cat}{$2}{__ALL__}++;
}
}
}
}
}
}
The variable LEFFF
is a dictionary composed of 490489 lines. So, the loop is comparing the words with all the dictionary lines one by one. This is too much. Any ideas how to optimize this?
Here's a preview of how LEFFF
is structured:
touant VPR touer 0
intimiste NC intimiste 1
intimiste ADJ intimiste 0
phonologiques ADJ phonologique 1
condescendirent V condescendre 1
enchaussez VIMP enchausser 1
enchaussez V enchausser 0
riotiez VS rioter 1
riotiez V rioter 0
Eyzin-Pinet NPP Eyzin-Pinet 1
dentaires NC dentaire 0
dentaires ADJ dentaire 1
classe VIMP classer 0
classe VS classer 1
seek
them. Ugh. You were thinking “database”, which would be better. \$\endgroup\$