Closed urdvr closed 8 years ago
Ei õnnestunud probleemi korrata -- muidugi sellele lõigatud-kleebitud tekstil on kadunud vormistus. input.txt
timo@vm-silicon ~/estnltktest $ time python3.4 -c "import estnltk; estnltk.analyze(open('input.txt').read())"
real 0m1.362s
user 0m1.216s
sys 0m0.140s
timo@vm-silicon ~/estnltktest $ time python2.7 -c "import estnltk; estnltk.analyze(open('input.txt').read())"
real 0m1.135s
user 0m0.928s
sys 0m0.200s
Aga huvitav, kuidas see probleem tekib, sest estnltk-ga on õnnestunud läbi analüüsida terve koondkorpus kui ka eestikeelne vikipeedia. Kasutasin siis estnltk versiooni 1.3 .
Ma kinnitan, et sinu näide töötab. Aga proovi näiteks
time python -c "import estnltk; estnltk.Text(open('./input.txt').read()).lemmas"
Raul testis ja leidis, et probleem on liiga pikas reas. Aga seni ei ole kellelgi olnud aega seda pikemalt uurida.
Okei, viga, nagu ikka, on keerukam kui esialgu tundus.
estnltk.analyze võtab argumendina kas tokenite listi või tokeniseerimata stringi. Kui ta saab tokeniseerimata stringi, ei kasuta ta mitte estnltk vaiketokeniseerijat vaid teeb words.split()
ehk tokeniseerib whitespace -i järgi.
Seega kui sõne meie (mina ja sina).
tokeniseeritaks reeglina tükkideks "meie", "(", "mina", "ja", "sina", ")"
, siis Timo näites hoopis tükkideks "meie", "(mina", "ja", "sina)"
Põhjus, miks Timo näites patoloogilist juhtu ei ilmnenud, on, et probleemiks pole mitte pikk sõnalist vaid pikk sõnalist, mis sisaldab tokenitena lõpetavaid sulge. Mu hüpotees siinkohal oleks, et vabamorf püüab neid millegipärast matchida ja kasutab selleks ebaefektiivset algoritmi. Mul puudub hetkel aeg/pädevus/kogemus et probleemi juuri vabamorfi koodist edasi otsida ja minust jääb see hetkel ilmselt siiapaika.
Ma arvan küll, et estnltk.analyze
peaks kasutama vaiketokeniseerijat, sest see vastaks paremini kasutajate ootustele.
Jätan siia ka näiteprogrammi, mis demonstreerib minu arvutis vähemalt kümnekordset kiirusevahet 1000 elemendilise sõnalisti peal sõltuvalt sellest kas kümnendik neist on lõpetavad sulud või mitte.
import random
import string
def generate_word(n):
return ''.join([random.choice(string.ascii_letters) for i in range(n)])
vec_len = 1000
words = [generate_word(5) for i in range(vec_len)]
import time
from estnltk.vabamorf.morf import Vabamorf
from estnltk.vabamorf import vabamorf as vm
t = time.time()
v = Vabamorf()
morfresults = v._morf.analyze( vm.StringVector(words), True, True, True, True)
print('Aeg ilma sulgudeta', time.time() - t)
for i in range(vec_len):
if i % 10 == 0:
words[i] = ')'
from estnltk.vabamorf.morf import Vabamorf
from estnltk.vabamorf import vabamorf as vm
t = time.time()
v = Vabamorf()
morfresults = v._morf.analyze( vm.StringVector(words), True, True, True, True)
print('Aeg lõpetavate sulgudega', time.time() - t)
Ja väljund
Aeg ilma sulgudeta 0.41082334518432617 Aeg lõpetavate sulgudega 10.071750164031982
Tundub, et probleem avaldub pärisnimede tuvastamisega (postag H)
$ python3.4 test.py
Aeg ilma sulgudeta 0.44490551948547363
Aeg lõpetavate sulgudega 13.82964301109314
Aeg lõpetavate sulgudega ja propername==False 0.3258984088897705
Halb uudis on see, et probleem tekib ka etanaga.
$ time ./etana analyze -guess -propername -phonetic -lex et.dct -in sulgudeta.json -out sulgudeta_out.json
real 0m0.146s
user 0m0.120s
sys 0m0.004s
$ time ./etana analyze -guess -propername -phonetic -lex et.dct -in sulgudega.json -out sulgudega_out.json
real 0m14.278s
user 0m14.216s
sys 0m0.008s
$ time ./etana analyze -guess -phonetic -lex et.dct -in sulgudega.json -out sulgudega_out.json
real 0m0.201s
user 0m0.144s
sys 0m0.008s
Eelmise kirjas oleva näitega:
$ time python -c "import estnltk; estnltk.Text(open('./input.txt').read(), propername=False).lemmas"
real 0m1.254s
user 0m1.064s
sys 0m0.184s
NB Pidin failidele panema .txt laiendi, sest Github ei lubanud neid muidu üles laadida: sulgudega.json.txt sulgudeta.json.txt test.py.txt
Tundub, et viga sai parandatud/leevendatud järgmise commitiga vabamorfis: https://github.com/Filosoft/vabamorf/commit/f52365944f206d0e614174986bfb1cca001c582b
Vastav muudatus tuleks mergeda estnltk vabamorfi liidesesse ja siis uuesti lauseid benchmarkida.
Mergesin vastava vabamorfi commiti ja probleem minu masinas taandus:
$ python test.py
Aeg ilma sulgudeta 0.3941187858581543
Aeg lõpetavate sulgudega 0.36653900146484375
Aeg lõpetavate sulgudega ja propername==False 0.35704803466796875
Palun kotrollige ja positiivse tulemuse korral v6ib pileti kinni panna.
Lemmatiseerimine jääb ebamõistlikult pikaks ajaks jooksma (mul pole alust väita, et ebaõnnestub, aga ka mitte kannatust oodata, et töö lõppeks) näiteks järgmise reaalelulise teksti korral:
Hüpoteese: