Upload
dangminh
View
256
Download
8
Embed Size (px)
Citation preview
TALLINNA ÜLIKOOL
Haapsalu Kolledž
Rakendusinformaatika õppekava
Kätlin Jõgisalu
EESTI VAHEKEELE KORPUSE SÕNADE GRUPEERIMISVAHENDITE LOOMINE
Diplomitöö
Juhendajad: MSc Jaagup Kippar
PhD Pille Eslon
Haapsalu 2014
TALLINNA ÜLIKOOL
Haapsalu Kolledž Õppekava:
Rakendusinformaatika
Töö pealkiri: Eesti vahekeele korpuse sõnade grupeerimisvahendite loomine
Teadusvaldkond: Arvutiteadused
Uurimuse tasand: Diplomitöö Kuu ja aasta: Juuni, 2014 Lehekülgede arv: 46 lk
Referaat:
Käesoleva diplomitöö eesmärgiks oli luua Eesti vahekeele korpusele pöördsõnastik koos
automaatse silpide otsingu võimalusega. Lisaks loodi kasutaja sisestatud teksti analüüsi ja
silbitamise lehed. Tutvustada keelekorpuseid ja nende kasutusala. Tutvustada välja
olemasolevaid vahendeid silbitamise, pöördsõnastike ja teksti analüüsi juures.
Loodud rakendusi on vaja selleks, et oleks võimalik õppijakeele vigaseid vorme
automaatselt grupeerida paradigmadesse ja õppijakeele lemmatiseerimiseks.
Eesmärgist lähtuvalt tuli leida Eesti vahekeele korpuse jaoks parimad võimalused
pöördsõnastiku, silbitajalehe ja teksti analüüsi loomiseks.
Töö meetodiks oli praktiliste lahenduste loomine Eesti vahekeele korpuse pöördsõnastiku,
silbitajalehe ja teksti analüüsi lehe näol. Püstitatud eesmärk sai täidetud. Praktilise
lahendusena valmis Eesti vahekeele korpuse pöördsõnastik koos automaatse
silbiotsinguga, silbitaja leht ja teksti analüüsi leht.
Võtmesõnad: Eesti vahekeele korpus, pöördsõnastik, silbitamine, teksti analüüs
Säilitamise koht:
TLÜ Haapsalu Kolledži raamatukogu
Töö autor: Kätlin Jõgisalu allkiri:
Kaitsmisele lubatud:
Juhendajad: MSc Jaagup Kippar allkiri:
PhD Pille Eslon allkiri:
TALLINN UNIVERSITY
Haapsalu College Curriculum: Applied Computer Science
Title: Creating word grouping applications for Estonian Interlanguage Corpus
Science area: Computer Sciences
Level: Diploma Thesis Year and month: June, 2014 Number of pages: 46 p
Summary:
This Diploma thesis was to create a reverse dictionary with automatic syllable search, text
analysis page and syllabication page for Estonian Interlanguage Corpus. To give an
overview about language corpuses and their usage. Also to introduce applications that
have already been created.
Created applications are needed for grouping inaccurate word forms into paradigms and
to lemmatize learner language.
According to thesis I had to find the best solution for creating reverse dictionary, text
analysis and syllabication page.
The goal arised in the thesis was completed. As a practical solution reverse dictionary
with automatic syllable search, text analysis and syllabication pages were created.
Key words: estonian interlanguage corpus, reverse dictionary, syllabication, text analysis
Deposition
The Library of Haapsalu College of Tallinn University
Author of the thesis: Kätlin Jõgisalu signature:
Approved for dissertation:
Academic advisors: MSc Jaagup Kippar signature:
PhD Pille Eslon signature:
Eesti vahekeele korpuse sõnade grupeerimisvahendite loomine
Diplomitöö 2014
TLÜ Haapsalu Kolledž 2 Kätlin Jõgisalu
SISUKORD
Sissejuhatus ........................................................................................................................... 3
1. TÖÖ TEOREETILINE OSA .......................................................................................... 4
1.1. Keelekorpused ja Eesti vahekeele korpus ............................................................... 4
1.2. Pöördsõnastikud ...................................................................................................... 6
1.3. Silbitamine ............................................................................................................... 7
1.4. Teksti analüüs .......................................................................................................... 8
1.5. Teksti töötlemine Python programmeerimiskeeles .................................................. 8
2. PRAKTILINE OSA ........................................................................................................ 9
2.1. Eesti vahekeele korpuse tehniline kirjeldus ............................................................ 9
2.2. Arendustöö ............................................................................................................ 12
2.3. Pöördsõnastiku arendus ......................................................................................... 13
2.4. Silbitajalehe arendus .............................................................................................. 17
2.5. Kasutaja teksti analüüsilehe arendus ..................................................................... 21
2.6. Lahenduse tõstmine avalikku serverisse ja ületõstmisega seotud probleemid ...... 25
2.7. Silbitajalehe ületõstmine ....................................................................................... 26
2.8. Kasutajateksti analüüsi ületõstmine ...................................................................... 27
2.9. Testimine ................................................................................................................ 27
Kokkuvõte ........................................................................................................................... 29
Allikad ................................................................................................................................. 30
Lisa 1. search.py faili lisatud funktsioonid .......................................................................... 32
Lisa 2. WordTree.py faili lisatud funktsioonid .................................................................... 33
Lisa 3. reverselist.pt ............................................................................................................. 35
Lisa 4. syllableslist.pt .......................................................................................................... 38
Lisa 5. usertext.pt ................................................................................................................ 39
Lisa 6. SQL päringud ........................................................................................................... 41
Lisa 7. Pöördsõnastik ........................................................................................................... 42
Lisa 8. Silbitajaleht .............................................................................................................. 43
Lisa 9. Teksti analüüsi leht .................................................................................................. 44
Eesti vahekeele korpuse sõnade grupeerimisvahendite loomine
Diplomitöö 2014
TLÜ Haapsalu Kolledž 3 Kätlin Jõgisalu
SISSEJUHATUS
Praktika käigus sattusin tegelema Tallinna Ülikooli Eesti vahekeele korpusega
(http://evkk.tlu.ee). Kuna valmisid teoreetilisest küljest piisavalt keerukad lahendused, siis
otsustasime juhendajaga, et loodavate lahenduste põhjal sobib kirjutada diplomitöö.
Uurimistöö on vajalik, kuna tegemist on reaalselt kasutatava ja areneva keskkonnaga.
Diplomitöö eesmärgiks oli koostada Eesti vahekeele korpusele pöördsõnastik koos
automaatse silpide otsingu võimalusega. Lisaks loodi kasutaja sisestatud teksti analüüsi ja
silbitamise lehed.
Eesmärgist lähtuvalt tuli tutvuda Eesti vahekeele korpuse struktuuriga ning selgeks teha
kõik tööks vajalikud rakenduse komponendid ning selgitada välja kasutajate täpsemad
vajadused, kavandada ja luua rakenduselehed.
Diplomitöö koosneb keelekorpuste lühiülevaatest ning kasutusvaldkonna tutvustusest,
Eesti vahekeele korpuse arendusseisust diplomitöö algusfaasi ajal, planeeritavate
rakenduste vajalikkusest ja võrdlusest teiste samatüübiliste rakendustega, loodud
rakenduste ning nende arendusprotsessi kirjeldustest ja rakenduste testimisest.
Eesti vahekeele korpuse sõnade grupeerimisvahendite loomine
Diplomitöö 2014
TLÜ Haapsalu Kolledž 4 Kätlin Jõgisalu
1. TÖÖ TEOREETILINE OSA
Selles peatükis annan lühiülevaate keelekorpustest, toon välja grupeerimisvahendite
vajalikkuse Eesti vahekeele korpuses ning tutvustan olemasolevaid.
1.1. Keelekorpused ja Eesti vahekeele korpus
Korpus on elektroonne keeleainese kogu, mis koostatud kindlal uurimistöö eesmärgil.
Korpusesse on koondatud kirjalikud tekstid või suulise kõne näited. Selle alusel jagatakse
korpused kirjalike tekstide ja suulise kõne korpusteks. On olemas ükskeelseid ja
mitmekeelseid, diakroonilisi ja tänapäeva keelekasutusnäiteid sisaldavaid (sünkroonseid)
korpusi, normatiivse kirjakeele (standardkeele) ja mittenormatiivse keelekasutuse (nt
õppijakeele) korpused. Olenevalt sellest, kas korpuse mahtu saab pidevalt suurendada või
mitte eristatakse avatud ja suletud korpusi. (Vt Lehtinen jt 1995: 12–14, 16–30; Eslon,
Metslang 2007: 100–105)
Korpus kui kirjalike tekstide või suulise kõne transkribeeritud näidete kogu kajastab
autentset kirjalikku ja suulist keelekasutust. Korpuse koostamise kaks olulisemat nõuet on
valimi representatiivsus (tegelikku keelekasutust kajastav, tõeväärne) ja tasakaalustatus
(balanseeritus), mis tähendab, et erinevate tekstiliikide ja allkeelte valik peab olema hästi
läbi mõeldud. (Vt Biber 1993; Lehtinen jt 1995: 33–36) Korpus on tavaliselt lingvistiliselt
märgendatud (tagging): tähistatud on sõnaliigid, sõnad, vormid ja vormide funktsioonid.
Korpus sisaldab ka metainfot tähistavaid annoteerimismärgendeid (annotation), millega
tuuakse esile teksti liik, autor, pealkiri, tekstilõigud, laused, maht ehk sõnede ja lausete arv
tekstis jm. Tänapäeval kasutatakse standardkeele automaatset märgendamist ja
annoteerimist.
Elektroonilised keeleandmekogud ehk korpused hakkasid tekkima juba 1960-ndatel
aastatel, aga viimase paarikümne aastaga on nende mahud ja kasutusvõimalused tunduvalt
suurenenud. (Vt McEnery, Wilson 1996) Näiteks massiliselt on juurde tulnud õppijakeele
korpusi (vt http://www.uclouvain.be/en-cecl-lcworld.html), eriti seoses teise, kolmanda jne
keele omandamise ning tasemeoskuste (A-B-C või A1-A2-B1-B2-C1-C2) sidumisega
töökohtade ja kodakondsuse taotlemisega. EVKK on üks paljudest õppijakeele korpustest,
Eesti vahekeele korpuse sõnade grupeerimisvahendite loomine
Diplomitöö 2014
TLÜ Haapsalu Kolledž 5 Kätlin Jõgisalu
mis on koostatud lingvistilise uurimistöö ja pedagoogiliste rakenduste eesmärgil. (Vt Eslon
2014, ilmumas)
Aja jooksul on korpuse väliselt töötavatelt loomuliku keele analüüsivahenditelt üle mindud
korpuskeskkonnas automaatselt töötavatele vahenditele, tehnilised uuendused rakenduvad
keskmiselt iga 10-15 aasta möödudes (Anthony 2014: 151–157 ).
Tallinna Ülikooli eesti vahekeele korpus (EVKK) on õppurite kirjalike tööde kogu, mis on
koostatud ning elektrooniliselt töödeldud kindlal uurimistöö eesmärgil. Tegu on
monitorkorpusega, kuhu tuleb pidevalt lisada uusi tekste ning luua kasutajale uusi
võimalusi korpusvahendite kasutamiseks ja eesti õppijakeele analüüsiks võrdluses
standardkeelega.
EVKK struktuur sisaldab mitut alamkorpust. Nii koosneb tuumkorpus peamiselt Tallinnast
ja Ida-Virumaalt pärit inimeste, kelle emakeeleks on vene keel, eestikeele õpingute käigus
kirjutatud loovtekstidest. REKKi kogude alamkorpusesse on koondatud Innove arhiivi
eksami- ja tasemetööd. Vene koolide eesti keele olümpiaaditööd moodustavad kolmanda
alamkorpuse, akadeemilise eesti õppijakeele näidetest koosneb neljas alamkorpus, viiendas
on eesti teaduskeel. Lisaks sisaldab EVKK kahte vene keele referentskorpust: ühes neist
on gümnaasiumiõpilaste vene emakeele loovtööd ja teises eesti emakeelega õppijate vene
keele loovtööd (õpivad vene keelt tavaliselt kolmanda keelena).
EVKK-s on mitmetasandiline statistika, annoteerimine ja veataksonoomia; automaatse
analüüsi vahenditest töötab teksti morfo- ja süntaksianalüüs, leida saab vormi- ja
sõnasagedust jm. Õppijakeele puhul on üleminek automaatselt töötavatele süsteemidele
keerulisem, sest see on mittestandardne keel, samas kui märgendamise ja annoteerimise
vahendid on välja arendatud standardkeele alusel. (Vt Eslon 2014, ilmumas)
EVKK alamkorpuste tekstid ja muud ressursid (nt sagedussõnastik, morfosüntaktiliselt ja
morfoloogiliselt analüüsitud tekstid) on kasutajale vabalt kättesaadavad: korpuse tekste
saab eksportida ja analüüsida väljaspool korpuskeskkonda muud päritolu tarkvara abil või
kvalitatiivselt. Seetõttu on korpuse tekstidel tavaliselt kaks vaadet: lingvistiliselt
märgendatud ja märgendamata tekstid.
Soovi korral saab ta kasutada korpuse automaatanalüüsi vahendeid: teha kolmes keeles
(eesti, soome, vene) kirjutatud tekstide morfoanalüüsi (TreeTagger), kasutada eesti keele
süntaksianalüsaatorit, saada informatsiooni sõna- ja vormisageduse kohta jm. Probleemid
ja edasised tehnoloogilised arendused on kinni mittestandardse keeleanalüüsi vahendite
Eesti vahekeele korpuse sõnade grupeerimisvahendite loomine
Diplomitöö 2014
TLÜ Haapsalu Kolledž 6 Kätlin Jõgisalu
taga, mille lahendamisega järk-järgult tegeldakse. Osa vajalikest tegevustest on käesoleva
diplomitöö aluseks, fookuses mittestandardse õppijakeele sõnavormide automaatne
grupeerimine paradigmadesse ja õppijakeele lemmatiseerimine. Et selleni jõuda, on vaja
eelnevalt õpetada arvuti ära tundma vigaseid vorme ja neid ühestama. Käesoleva
diplomitöö raames on loodud õppijakeele automaattöötlusvahendid sõnade reastamiseks
sõnalõpu järgi, ühestamise hõlbustamiseks ka eesti keele silbitaja baasil (vabavara) loodud
vahend, mida on treenitud silbitama mittestandardseid sõnu ja mis võimaldab leida kõik
sõnaalgulised ja sõnalõpu silbid ning kesksilbid (tavaliselt 1-2 silpi), mille edasise
grupeerimise alusel (nt graafid) on võimalik leida tõenäosuslik mudel iga vigaselt
kirjutatud sõna automaatseks lemmatiseerimiseks. Avaramat perspektiivi silmas pidades on
see oluline ka eesti keele grammatikakorrektori väljatöötamiseks.
Korpuste koostamiseks on välja töötatud rida üldisi lingvistilisi ja tehnoloogilisi nõudeid,
mille eesmärk on luua keele uurimiseks audentne elektroonne andmebaas, millest kasutaja
saab talle vajalikku informatsiooni või mida on võimalik erineval viisil rakendada.
Seetõttu on tänapäeva korpused vabalt või teatud liiki piirangutega veebis kasutatavad.
Kasutajaliides võimaldab teha mitmesuguseid otsinguid, süsteemid töötavad kiiresti,
saadud tulemus on täpne (~ 98-99%) ja optimaalne – selles väljendub korpuse
kasutajasõbralikkus. (Vt Kopotev, Mustajoki 2003) Selles osas vajab EVKK
optimeerimist.
1.2. Pöördsõnastikud
Pöördsõnastik on niisugune sõnastik, kus sõnad on reastatud mittestandardses järjekorras –
sõnalõpu alusel, mis annab kasutajatele võimaluse saada sellist informatsiooni, mida oleks
raske kätte saada traditsioonilisest tähestikulisest sõnastikust. Pöördsõnastik on kasulik
lingvistidele ja luuletajatele, kes võiks otsida sõnade lõppe kindla järelliitega või näiteks
on antropoloogidele ja kohtuekspertiisile, kes uurivad kahjustatud tekste, milles sõnad on
säilinud vaid osaliselt, nt sõna lõpu-, kesk- või algussilbid. Sellist tüüpi pöördsõnastikke
oli raske luua enne vastavate tehnoloogiliste vahendite tulekut, esimene arvuti sorteeritud
pöördsõnastik ilmus 1974 aastal. (Vt Thanigaivel, Ramesh Kumar 2014).
Pöördsõnastike on välja antud nii inglise kui ka vene keele kohta. Üks esimesi
pöördsõnastikke koostati 1540ndal aastal Erasmus Alberuse poolt, selle eesmärk oli luua
riimsõnade sõnastik (Muthmann 1999).
Eesti vahekeele korpuse sõnade grupeerimisvahendite loomine
Diplomitöö 2014
TLÜ Haapsalu Kolledž 7 Kätlin Jõgisalu
Inglise keele pöördsõnastiku on välja andnud Gustav Muthmann 1999. aastal („Reverse
English Dictionary: Based on Phonological and Morphological Principles“). Selle asemel,
et esitada ümberpööratud sõnade nimistut lõputu jadana ja rangelt tähestikulises
järjekorras, arvestab inglise keele pöördsõnastik sõnade struktuuri ja nende moodustumist
ning grupeerib sõnad selle alusel lõikudesse ja alajaotustesse. Sõnade võrdlemine nende
lõpu alusel annab uusi võimalusi ja avab ebatavalisi aspekte sõnade struktuuri ja
moodustumise kohta, illustreerides laia kellelist varieerumist.
Vene keele esimese soliidse pöördsõnastiku on välja andnud Hans Holm Bielfeld 1965.
aastal („Rückläufiges Wörterbuch der russischen Sprache der Gegenwart“).
Tänapäeval on veebis väga palju erinevaid sõnastikke ja rakendusi, mille abil on võimalik
teha erinevaid otsinguid või näiteks sisestada oma sõnade nimekiri ja tulemuseks saada
nende pöördsõnastik.
Text Fixeri (http://www.textfixer.com/tools/alphabetize-text-words.php) ehk teksti
parandaja lehel on võimalik sisestada oma tekst ja kasutaja saab valida, kuidas talle tekst
tagastatakse. Sorteerimisel on kolm valikult: tähestikuliselt, arvuliselt ja vastupidiselt
tähestikulisele ehk siis z-a viisil.(TextFinder.com, s.a)
FindTheWord (http://www.findtheword.info/Search.aspx?stype=words-ending-
in&sword=EF) ehk „leia sõna“ on võimalik otsida ingliskeelseid sõnu selle järgi,
missugune on sõna lõpp, mille kasutaja saab ise sisestada ja valida ka sõna pikkuse.
(Gognitio Consulting AB, s.a).
1.3. Silbitamine
Meil on olemas Eesti Keele Instituudi (EKI) vabavaraline silbitaja, mida on võimalik
paigaldada oma arvutisse. Diplomitöö kirjutamise ajal on EKI kodulehele ilmunud ka selle
veebiversioon, nimelt teksti silbitaja(http://kn.eki.ee/tool/?m=silbitaja), mis leiab sisestatud
teksti sõnavormides kõik võimalikud silbituskohad. Teksti silbitaja väljundis tuuakse esile
mitme silbitusvariandiga sõnavormid, millele on joon alla tõmmatud ja neile klikkides
saab valida sobiva variandi.
Kairit Sirts ja Leo Võhandu (2009) on teinud uurimistööna silpidel baseeruva keelemudeli,
mis hõlmab endas eesti keele 500 kõige sagedamini esinevat silpi. See mudel on
kolmetasandiline, koosneb silpide, silbipaaride ja silbikolmikute järgnevuse
sagedustabelitest. Sagedustabel ise on oma olemuselt maatriks, mille ridadeks on kas
silbid, silbipaarid või silbikolmikud ja veergudeks silbid. Sagedustabeli veergude ja ridade
Eesti vahekeele korpuse sõnade grupeerimisvahendite loomine
Diplomitöö 2014
TLÜ Haapsalu Kolledž 8 Kätlin Jõgisalu
ristumispunktides olev arv näitab, mitu korda vastava veeru silp esines tekstikorpuses
vastava reaelemendi järel.
Artiklis välja toodud tulemuste kättesaamiseks pidid autorid oma teksti töötlema, et saada
tekstist kätte silbid. Silbitamiseks kasutasid autorid samuti EKI silbitamise tarkvara. Kui
silbitaja oli oma töö ära teinud, hakkasid nad kõik korpuses esinenud silpide esinemise
arvu kokku lugema ja silpe nende järgnemise-eelnemise ning sageduse järgi järjestama.
Nagu minu diplomitöö tegemise käigus nii ka neil esines samu probleeme, mis seotud
täpitähtede valede kodeeringutega. (Sirts, Võhandu 2009).
1.4. Teksti analüüs
EKI-s on loodud ka morfoanalüsaator, mida kasutab ka EVKK. Lisaks on vabakasutuses
EKI reeglipõhise morfoloogia demo, kus saab teksti uurida ja millel on ka juures
silbitamine, vt http://artur.eki.ee/morf/mf.aspx.
1.5. Teksti töötlemine Python programmeerimiskeeles
EVKK on üles ehitatud Python programmeerimiskeeles, mis tähendas minu jaoks seda, et
pidin tutvuma Pythoni võimalustega teksti töötlemises. Samuti olid mulle abiks mitmed
Python programmeerimiskeele juhendid.
Python programmeerimiskeel on konservatiivne. Peaaegu iga Python skript, mis kirjutati
10 aastat tagasi Python 1.0 versiooni jaoks, töötab hästi Python 2.3 ja uuemates
versioonides. Versioonide arendamisel lisatakse uusi funktsioone ja võimalusi. Kõige
silmapaistvamad muudatused on toimunud siis kui tuli välja Python 2.0 versioon
tutvustades loendite arusaamist, laiendatud ülesanded, Unicode – märkide kodeerimise
standard tugi ja standard XML pakett. Paljud skriptid, mis on kirjutatud kõige tõhusamal ja
loomulikumal viisil kasutades Python 2.0+ verisooni, ei tööta varasemates Python
versioonides ilma muutusteta. (Vt Mertz 2003)
Eesti vahekeele korpuse sõnade grupeerimisvahendite loomine
Diplomitöö 2014
TLÜ Haapsalu Kolledž 9 Kätlin Jõgisalu
2. PRAKTILINE OSA
Selle peatüki esimeses pooles kirjeldan EVKK tehnilist poolt – millist andmebaasi ja
serverit kasutatakse ning milline on programmi- ja kujundusfailide struktuur. Teises pooles
annan ülevaate arendustööst ja kuidas jõudsin eesmärgini luua pöördsõnastik koos
automaatse silbi otsinguga, silbitajaleht ja teksti analüüsi leht.
2.1. Eesti vahekeele korpuse tehniline kirjeldus
Selles peatükis tutvustatakse EVKK toimimise jaoks tähtsamaid tehnilisi vahendeid: Zope
rakendusserveri ülesehitust ja otstarvet, Postgres andmebaasi ja tema kasutusvaldkondi
ning olemasoleva lähtekoodi struktuuri.
2.1.1. Zope
Zope on avatud lähtekoodiga objektorienteeritud veebirakendusserver ja raamistik, mis on
kirjutatud Python programmeerimiskeeles. Selle juurde käivad nii veebi- kui ka FTP-File
Transfer Protocol serverid ning seda on võimalik ka laiendada teistele protokollidele. Zope
platvormi on sisse ehitatud objektidel põhinev andme baas ja samas on sellele suhteliselt
lihtne juurde integreerida teisi andmebaase. Zope töötab peaaegu kõigil UNIX'i
platvormide ja ka Windows NT-ga. Zopes kasutatakse veebilehestiku jaoks HTMLi ning
DTMLi – Document Template Markup Language, DTML on Zope märgenduskeel.
2.1.2. PostgreSQL
PostgreSQL on postgres andmebaasi vabavaraline edasiarendus. PostgreSQL on
relatsiooniline andmebaasihaldur objektiorienteeritud kallakuga. Postgres on vabavaraline
ja avatud lähtekoodiga tarkvara. PostgreSQL ei kuulu ühelegi kindlale ettevõttele.
Programmi arendusega tegeleb globaalne kogukond, mis koosneb erinevatest arendajatest
ja firmadest. Oma tehnilise ja funktsionaalse poole pealt on see suur konkurent
kommertsanaloogidele. PostgreSQL oli üks esimesi andmebaase, mille funktsionaalsuse
hulka kuulus multiversioon-konkurentsjuhtimine (MVCC, Multi-Version Concurrency
Control). MVCC on meetod ühiskasutusega andmebaaside jõudluse tõstmiseks, et loobuda
rea- ja tabelilukustusest efektiivsuse parandamise eesmärgil. PostgreSQL toimib paljudel
erinevatel platvormidel ja PSQL andmebaas sisaldab liideseid erinevate
programmeerimiskeelte ja andmebaasi protokollide tarbeks.
PostgreSQL'i tugevad küljed on:
• Andmebaasi suurus praktiliselt piiramatu
Eesti vahekeele korpuse sõnade grupeerimisvahendite loomine
Diplomitöö 2014
TLÜ Haapsalu Kolledž 10 Kätlin Jõgisalu
• Võimsad ja usalduväärsed tehingute ja replikatsiooni mehhanismid
• Pärimine
• Lihtne tugi
(Barol, 2010)
2.1.3. Eesti vahekeele korpuse programmi- ja kujundusfailide struktuur
Zopes on võimalik lahus hoida kihte andmete näitamiseks, töötlemiseks ja salvestamiseks.
Veebilehtede koostamiseks ehk andmete näitamiseks on mõeldud Zope page template
tüüpi kujundusfailid (laiendiga .pt).
Page templates on veebilehe loomise tööriistad, mis aitavad programmeerijatel ja
disaineritel teha koostööd dünaamiliste veebilehtede loomisel Zope veebirakendusele
(Zope Developers Community, s.a).
Rakenduse tegevusloogika jaoks ehk andmete töötlemiseks kasutatakse Zopes Pythoni
faile, kus lisaks Pythoni standardkäskudele on võimalik kasutada Zope objektandmebaasi
andmeid ja käsklusi. Loetavuse huvideks jaotatakse kood mooduliteks ehk failideks, need
omakorda klassideks ja klassi sees tegevused meetoditeks.
Relatsioonilisse andmebaasi salvestamiseks ja sealt andmete lugemiseks kasutatakse Zopes
eelnevalt salvestatud SQL lauseid.
Failid on jagatud oma tüübi järgi gruppidesse. Esmalt on Python failid, millest kõige
tähtsam on Korpus.py, mille külge ühenduvad kõik teised .py failid.
Kõik veebilehega seotud failid on kaustas nimega browser ja seal omakorda jagunevad
need ära teemade järgi järgmiselt (vt joonis 1):
• Templates – Tähtsamad veebilehe kujundusfailid
• Styles – Veebilehe stiiliga seotud CSS failid
• Kupu – Graafiline tekstiredaktor
• Javascript – Veebilehele vajalikud javascript failid
• Images – Veebilehel kasutatavad pildid
Eesti vahekeele korpuse sõnade grupeerimisvahendite loomine
Diplomitöö 2014
TLÜ Haapsalu Kolledž 11 Kätlin Jõgisalu
Templates kaust jaguneb omakorda teemade järgi järgmiselt (vt joonis 2):
• WWW – Korpuse põhilehtede kujundusfailid
• Search – Otsingulehtedega seotud kujundusfailid
• Marks – Hindamisega seotud kujundusfailid
• Main – Lõikude kujundusfailid, mida kasutatakse teiste lehtede juures
• Documents – Dokumentidega seotud kujundusfailid
• Corpuses – Alamkorpustega seotud failid
Joonis 1: Ekraanitõmmis EVKK failide jagunemise struktuurist
Eesti vahekeele korpuse sõnade grupeerimisvahendite loomine
Diplomitöö 2014
TLÜ Haapsalu Kolledž 12 Kätlin Jõgisalu
2.2. Arendustöö
Selles diplomitöö peatükis saab teavet arendustöö kohta. Peatükis kirjeldatakse, mida tuli
teha selleks, et saaks arendustöid üldse teha, kirjeldatakse pöördsõnastiku, silbitajalehe ja
kasutajateksti analüüsilehe arendustöid ning töö käigus esinenud probleeme.
2.2.1. Arendusserveri ja rakendusserveri seadistamine
Ettevalmistuse käigus tuli luua testkeskkond, et arendamine ei häiriks põhiserveri tööd,
sättida paika töövahendid, et saaks mugavalt testkeskkonnas toimetada.
Arenduskeskkonna jaoks tuli teha koopia EVKK põhiserverist. Selleks tuli
arendusserverisse paigaldada Zope, PostgreSQL, kopeerida korpuse lähtekood, tõsta üle
Zope objektandmebaas, paigaldada korpuse tööks vajalikud Zope moodulid:
TextIndexNG3, ZpsycopgDA, Twisted, samuti paigaldada Pythonile korpuse tööks
vajalikud lisamoodulid.
Seadistamise käigus tekkis probleeme kasutajaõigustega, programmide ligipääsuga, need
sai lahendatud koostöös süsteemiadministraatoriga.
Nii avalik server kui ka testserver on muutmiseks ligipääsetavad ainult TLÜ sisevõrgust.
Seega tuli enne töö alustamist luua kohaliku masina ja testserveri vahele tunnel tudengitele
ligipääsetava serveri lin2.tlu.ee kaudu. Tunneli abil saab faile transportida FileZilla
rakendusega. Kuna ühendus käis tunneli kaudu, siis tuli FileZilla'le õpetada, et ühendus
tuleb võtta kohaliku masina selle pordiga, kus tunneli ühendus hakkab (vt. joonis 2).
FileZilla rakendus osutus valituks, kuna olen sellega varem kokku puutunud ning mul oli
kerge erinevatele failidele ligipääsu saada. Failide muutmiseks kasutati tekstiredaktorit
TextWrangler.
Joonis 2: Ekraanitõmmis kausta Templates jagunemise kohta
Eesti vahekeele korpuse sõnade grupeerimisvahendite loomine
Diplomitöö 2014
TLÜ Haapsalu Kolledž 13 Kätlin Jõgisalu
2.3. Pöördsõnastiku arendus
Enne pöördsõnastikuga töö alustamist pidin välja selgitama, kas andmebaasil on olemas
sõnade ümberpööramise funktsioon (reverse). Selle teadasaamiseks tuli uurida, mis
PostgreSQL'i versioon on kasutusel. Versiooniks osutus PostgreSQL 8.4.13 ja antud
versiooni kasutusjuhendit(vt http://www.postgresql.org/docs/8.4/static/) lugedes selgus, et
sõnade ümberpööramise funktsioon puudub. Hakkasin uurima, et ehk kellelgi on antud
funktsiooni vaja läinud, selle asemel, et kohe hakata pead vaevama funktsiooni loomisega.
Google otsingu abil sattusin PostgreSQL teadete tahvlile, kus Chris Browne oli kirjutanud
selle funktsiooni PostgreSQLiga tegelejatele (vt koodinäide 1).
CREATE OR REPLACE FUNCTION reverse(text) RETURNS text AS $$
SELECT array_to_string(
ARRAY(
SELECT substring($1, s.i,1) FROM
generate_series(length($1), 1, -1) AS s(i)
), '');
$$ LANGUAGE SQL IMMUTABLE STRICT;
Koodinäide 1. Sõnade ümberpööramise funktsioon (reverse). (Browne 2008)
Peale andmebaasi lisamist, tegin ühe katsetuse sõnaga „tere“ ja nagu järgmiselt pildilt näha
funktsioon töötas (vt joonis 3).
Peale funktsiooni toimimist katsetasin seda ka EVKK andmebaasis oleva tabeliga.
Tabeliga testimise juures lisasin SQL lausele juurde ka selle, et sõnad kuvatakse mulle ette
nii, et need on paigas lõpu järgi ehk nii nagu pöördsõnastikus olema peab (vt joonis 4 ).
Joonisel 4 on näha ekraanitõmmis testimisest andmebaasi tabeliga. Katsetuse tegin kogu
tabeli põhjal, mis tähendab, et tulemuseks sain kogu tabeli, mis on lõpu järgi sorteeritud, st
et numbrid tulevad enne tähti. Veebilehel saab valida tähe järgi, millega sõna lõpeb.
Joonis 3: Ekraanitõmmis reverse funktsiooni
katsetamisest sõnaga tere
Eesti vahekeele korpuse sõnade grupeerimisvahendite loomine
Diplomitöö 2014
TLÜ Haapsalu Kolledž 14 Kätlin Jõgisalu
Seejärel pidin tutvuma olemasoleva rakenduse struktuuriga ning leidma kohad, kuhu on
võimalik ja sobilik oma uuendusi lisada. Kujunduse puhul jälgisin sama joont, mis juba
EVKK-s olemas. Pöördsõnastiku aluseks võtsin sagedussõnastiku, mis tähendab seda, et
pöördsõnastiku välimus on sarnane sagedussõnastiku omale. Sagedussõnastiku
kujundusfailist wordlist.pt tegin koopia ja asendasin nimega reverselist.pt. Selles tegin
muudatusi, et faili ei jääks ebavajalikke asju. Koodifaili nimega Wordtree.py hakkasin
tegema uut funktsiooni pöördsõnastiku jaoks, ka selle puhul oli mulle abiks
sagedussõnastiku jaoks tehtud funktsioon, millele sai lisatud muudatused, et oleks
võimalik uut kujundusfaili teenindada. Funktsioonis jätsin alles need sagedussõnastiku
osad, kus kuvatakse sõna sagedus(freq.), sõna tüvi(prim) ja sõna algvorm(lemma). Selle
tulemusena sai kuvatud juba testserveris esimene pöördsõnastiku versioon, kus on
Joonis 4: Ekraanitõmmis reverse funktsiooni testimisest EVKK andmebaasis oleva
tabeliga
Eesti vahekeele korpuse sõnade grupeerimisvahendite loomine
Diplomitöö 2014
TLÜ Haapsalu Kolledž 15 Kätlin Jõgisalu
võimalik valida sõna viimase tähe järgi ja sõnad tulevad oma lõpu järgi tähestikulises
järjekorras.
Peale esimese versiooni valmimist näitasin seda EVKK koostanud filoloogile ja tema jäi
rahule. Siiski soovis filoloog, et pöördsõnastikus oleks võimalik teha otsinguid ka
sõnalõpu järgi.
Kuigi tegin EVKK-sse eraldi silbitajalehe, siis on ka pöördsõnastiku juures silpide tabel.
Silbitajalehel on võimalik ise otsida erinevate silpide ja nende asetuse järgi sõnas, kuid
pöördsõnastiku juurde on lisatud silpide tabel, kus on välja toodud andmebaasis esinevad
silbid. Antud tabelis saab silpe sorteerida kasvavalt või kahanevalt selle järgi, kui mitmes
erinevas sõnas see silp esineb, samuti tähestikulises järjekorras ja sorteerida
pöördsõnastiku järgi. Leida saab silpide üldsageduse (mitu korda silp esineb andmebaasis
olevates tabelites). Üldsagedust kuvatakse ainult lõpusipide puhul. Silbitabeli üheks
anomaaliaks on see, et sõnasageduse puhul kuvatakse ainult nende sõnade arv, mis on
andmebaasi tabelis nimega words. Selles tabelis on kõik nii-öelda puhtad sõnad, mis on ka
korrektselt lemmatiseeritud. Kui vajutada silbile, siis kuvatakse ette nii words tabeli kui ka
docrefs tabeli sõnavormid, mis tähendab seda, et antud silbiga lõppeb rohkem sõnu, kui
sõnasageduse number näitab. Lisaks on tehtud algelised tabelid algussilpide ja kesksilpide
kohta. Nende puhul on toiming sama nagu lõpusilpide puhul, aga nendele ei ole lisatud
üldsagedust. Nimetatud tabelite osas jäi arendus pooleli, kuna filoloog ei ole veel
otsustanud, mis nendest täpselt edasi saab. Olemas on ka tabel, kus näha kõik silbid, mis
esinevad andmebaasi tabelites docrefs ja words. Tabelid eksisteerivad vaid testserveris.
Selleks, et lõpusilpide silbisagedust kätte saada pidin tegema eraldi SQL päringu ja selle
välja kutsumiseks veel Python funktsiooni. Lisaks sai tehtud kujundusfaili javascripti
funktsioon, mille abil oli võimalik ükshaaval järjest kuvada lõpusipide silbisagedused.
SQL päring getSyllableGlobalCount saab andmebaasist kätte lõpusilbi sageduse (vt
Koodinäide 2).
select count(*) from docrefs where docrefs.docrefsyllables
like ('%-'|| <dtml-sqlvar syllable type="string"> );
Koodinäide 2. SQL päring andmebaasist, et kätte saada lõpusilbi sagedus.
Pythoni funktsioon getSyllableGlobalCount, kutsub välja samanimelise SQL päringu, et
saada kätte konkreetse silbi kohta esinemissageduse (vt koodinäide 3).
Eesti vahekeele korpuse sõnade grupeerimisvahendite loomine
Diplomitöö 2014
TLÜ Haapsalu Kolledž 16 Kätlin Jõgisalu
def getSyllableGlobalCount(self, syllable):
"syllablesglobalcount"
sqlres=self.sqls.getSyllableGlobalCount(syllable=syllable)
for r in sqlres:
return str(r[0])+";"+syllable
Koodinäide 3. Pythoni funktsioon konkreetse silbi esinemissageduse kätte saamise jaoks
Kujundusfaili on tehtud veel lisaks samanimeline Javascripti funktsioon (vt koodinäide 4),
mis käib serverist XMLHttpRequesti abil Pythoni funktsioonilt abi küsimas. Kui serverilt
on saadud vastus, siis käivitub funktsioon syllableRecieved. Kui saadud andmed on korras,
siis tükeldatakse tulemus semikooloni koha pealt ja saadakse silp ja kogus. Igal silbil on
HTML'is temaga sama nimega id, näiteks ga- silbil syllable_ga. Kättesaadud silbi juurde
kuuluvasse lahtrisse sisestatakse serverist küsitud üldsagedus. Kui üks silp on kätte
saadud, siis getNextTd võtab järgmise silbi ja nii lõpuni välja.
Üldkogust on võimalik kahel viisil kuvada. Esimene on see, et vajutades veebilehel „vali
kõik“, siis hakkavad kõik sagedused järjest tulema. Teiseks saab ka üksikult valida
soovitud silbi üldsagedus, selleks tuleb kursoriga üle soovitud silbi minna ja seejärel
kuvatakse silbi kõrvale tema üldsagedus.
var xhr=new XMLHttpRequest();
xhr.onreadystatechange=syllableReceived;
function getSyllableGlobalCount(syllable){
xhr.open("GET",
"getSyllableGlobalCount?syllable="+syllable, true);
xhr.send(true);
console.log(syllable);
}
function syllableReceived(){
console.log(xhr.readyState);
if(xhr.readyState==4){
var m = xhr.responseText.split(";");
try{
document.getElementById("syllable_"+m[1]).innerHTML=m[0];
} catch(err){
console.log(err);
}
getNextTd();
}
}
var tds=null;
var tdsplace=-1;
function getNextTd(){
if(tds!=null){
Eesti vahekeele korpuse sõnade grupeerimisvahendite loomine
Diplomitöö 2014
TLÜ Haapsalu Kolledž 17 Kätlin Jõgisalu
if(tdsplace<tds.length){
getSyllableGlobalCount(tds[tdsplace].id.substring(9));
tdsplace++;
}
}
}
function getAllCounts(){
tds=document.getElementsByClassName("syllable");
tdsplace=0;
for(var i=0; i<tds.length; i++){
console.log(tds[i].id);
}
getNextTd();
}
Koodinäide 4. JavaScripti funktsioon iga silbi üldsageduse kätte saamiseks
2.4. Silbitajalehe arendus
Peale pöördsõnastiku valmimist arvas filoloog, et EVKK-l võiks olla veebirakendusena
vabalt kasutatav silbitamine ja silpide järgi otsimine. Silpide jaoks sai kasutusele võetud
EKI silbitaja(http://www.eki.ee/tarkvara/silbitus/). Et silbitaja hakkaks EVKK serveris
tööle, tuli lähtekoodi kohandada, millest on eraldi peatükk (vt punkt 2.4.1). EKI silbitaja
võtsin kasutusele seetõttu, et see on vabavaraline tarkvara.
Kui olin kätte saanud erinevate asetustega silbid, siis sai loodud silbitajaleht. Silbitaja
lehele lisasin koha, kus kasutajad saavad kasutada silbitajat korpusse imporditud sõnade
analüüsiks, ilma et peaks oma arvutisse selle jaoks programmi tõmbama. Lisaks on
võimalik sellel lehel otsida andmebaasis olevaid sõnu erinevate silpide abil. Joonisel 5 on
näha ekraanitõmmis silbitajalehest, kus on tehtud otsing algussilbiga „ja“ (vt joonis 5 ).
Joonis 5: Ekraanitõmmis silbitajalehest ja selle tulemusest algussilbi “ja-“
otsingu puhul
Eesti vahekeele korpuse sõnade grupeerimisvahendite loomine
Diplomitöö 2014
TLÜ Haapsalu Kolledž 18 Kätlin Jõgisalu
2.4.1. Silbitaja programmi kirjeldus ja lähtekoodi kohandamine
Esmasel katsetusel Windowsi platvormil programm ei töötanud. Hilisemal uurimisel
selgus, et ma ei olnud alla laadinud programmi käivitamiseks kõiki vajalikke faile. Esmase
katsetamise ja hilisema uurimise vahel õnnestus mul silbitaja tööle saada EVKK serveris,
selleks pidin kohandama EKI silbitaja lähtekoodi.
Esmalt sai välja võetud koodiread, mis kontrollivad, kas tegu on Linuxi või Windowsi
platvormidega, kuna on teada, et server on Linuxi platvormil. Lisaks sai eemaldatud
kujundusega seotud osad, kuna EVKK serveri jaoks neid pole vaja.
EVKK serveri jaoks jätsin alles ainult silbitaja koodiga seotud failid, mida on kokku 8.
Põhifail, mille külge teised failid haakuvad, on silbitaja.cpp. Selles failis on kõik põhilised
funktsioonid ja välja toodud täpitähed ning täishäälikud. Selles failis on kõik tähtsamad
funktsioonid, mille põhjal silbitaja töötab.
Selleks, et oleks võimalik koodiga midagi peale hakata, tuli leida koht, kus töö pihta
hakkab(vt koodinäide 5). C programmeerimiskeeles on selleks main() käsklus. Funktsioon
valmistab ette andmete struktuuri, et oleks võimalik silbitada. Edasi luuakse mälupuhver
50-le tähele ja silbitatakse ainult juhul, kui sisestatud tekst ei alga sidekriipsuga. Kogu
silbitamise teeb ära käsklus syllabify ning lõpuks tuleb väljatrükk silbitatud kujul.
main(){
init_syllabification();
char buf[50];
fgets(buf, sizeof(buf), stdin);
if(*buf!='-'){
SyllabificationResult *pFirst=syllabify(buf);
printf("%s\n", pFirst->word);
}
}
Koodinäide 5. Eesti Keele Instituudi silbitaja funktsioon, mis valmistab ette andmete struktuuri, et oleks võimalik
silbitada.
Silbitaja.cpp külge haakuvad failid on syll_exp.h, sylltrie.hpp ja openfile.h. Failis
syll_exp.h failis defineeritakse vastuse vorming. Sylltrie.hpp failis on rakenduse tööks
vajaliku andmepuu loomise andmetüübid ja openfile.h failis on vajalikud käsklused
andmefaili mugavaks avamiseks.
Kui lähtekood oli kohandatud EVKK serveri jaoks, siis hakkasin katsetama esialgu
käsureal (vt koodinäide 6) erinevate sõnade silbitamist ning seejärel tulid katsetused
veebis.
Eesti vahekeele korpuse sõnade grupeerimisvahendite loomine
Diplomitöö 2014
TLÜ Haapsalu Kolledž 19 Kätlin Jõgisalu
[katlinj@greeny silbitaja]$ ./a.out silbitaja.bin
Tere
Te-re
Koodinäide 6. Silbitaja katsetus käsureal sõnaga tere
2.4.2. Sidumine EVKK-ga
Selleks, et saaks veebis katsetada, pidin välja mõtlema Python funktsiooni, mis sai lisatud
Search.py faili (vt koodinäide 7). Antud funktsioon silbitab sellele ette antud sõna ära.
def kysiSilbid(self, sona):
"silbitulemus"
MORFO_PROGS="/home/katlinj/silbitaja"
cmd = "./a.out"
import subprocess
a = subprocess.Popen(cmd, cwd=MORFO_PROGS, shell=True,
stderr=subprocess.PIPE, stdin=subprocess.PIPE,
stdout=subprocess.PIPE)
stdo, stde = a.communicate(sona)
return stdo.rstrip()
Koodinäide 7. Pythoni funktsioon, mis silbitab sellele ette antud sõna ära.
Enne andmebaasis olevate sõnade silbitamise juurde asumist katsetasin seda, kuidas
silbitaja saab hakkama täpitähtedega. Selgus, et see oli silbitaja jaoks suur probleem. Kuna
kysiSilbid funktsiooni kutsusid välja mitmed erinevad funktsioonid, siis pidin igas
funktsioonis lisama kysiSilbid järele kodeerimise jupi (vt koodinäide 8). Seda on
sellepärast vaja, kuna Pythoni kodeering on utf-8 ja silbitaja oma on iso-8859-13. Selle
abil siis kodeeritakse sõna kõige pealt utf-8'st iso-8859-13'ks ja siis jälle vastupidi tagasi.
(word.decode("utf-8").encode("iso-8859-13")).decode("iso-
8859-13").encode("utf-8")
Koodinäide 8. Täpitähtede kodeerimiseks mõeldud osa.
Veendunud, et silbitaja töötab korralikult, sain hakata tegelema andmebaasis olevate
sõnade silbitamisega. Et üldse saaks sõnu silbitama hakata, tuli esmalt teha
andmebaasitabelitesse vastav tabelikoht silbitatud sõnade jaoks. Esialgu võtsin
silbitamiseks andmebaasist words tabeli, kus on ~26000 sõna. Silbitamist teostasin 5000
sõna kaupa ja lõpus hakkasin järk-järgult seda numbrit vähendama, et kõik sõnad saaks
silbitatud.
Eesti vahekeele korpuse sõnade grupeerimisvahendite loomine
Diplomitöö 2014
TLÜ Haapsalu Kolledž 20 Kätlin Jõgisalu
Kui andmebaasis olevad sõnad olid silbitatud, siis sai hakata uurima, kuidas kätte saada
lõpusilpe, hiljem ka algus- ja kesksilpe. Lõpusilpide kättesaamiseks oli mul vaja taaskord
andmebaasi lisada uus funktsioon. Siinkohal oli mulle jälle suureks abiks Google: vajaliku
funktsiooni leidsin stackoverflow lehelt, kus kasutaja leonbloy, kodanikunimega Hernan J.
Gonzalez oli selle sinna postitanud. Selle funktsiooni abil saab kätte tähe asukoha
etteantud tekstis, tagantpoolt otsides (vt koodinäide 9).
CREATE FUNCTION last_post(text,char) RETURNS integer AS $$
select length($1)- length(regexp_replace($1, '.*' ||
$2,''));
$$ LANGUAGE SQL IMMUTABLE;
Koodinäide 9. Funktsioon last_post tähe asukoha kätte saamiseks, tagantpoolt otsides. (Gonzalez, 2010).
Kui uus funktsioon oli lisatud andmebaasi, pidin hakkama taaskord välja mõtlema Python
funktsiooni selleks, et kätte saada lõpusilpe. Erinevate silpide kättesaamiseks loodud
funktsioonid lisasin WordTree.py faili. Nii algus-, kesk- kui ka lõpusilpide jaoks tuli eraldi
luua ka SQL laused (vt koodinäide 10), mida kutsuvad välja Pythonis tehtud funktsioonid
(vt koodinäide 11).
select count(*), substr(docrefsyllables,
last_post(docrefsyllables,'-')) as ots from docrefs group by
ots order by count(*) desc;
Koodinäide 10. Lõpusilpide kätte saamiseks tehtud SQL päring nimega groupBySyllableEnd
def getSyllableEnds(self, orderby="count"):
"endsyllables"
sqlres = self.sqls.groupBySyllableEnd()
res =[]
for r in sqlres:
abi = r[1].strip()
if abi:
if abi[0] =="-":abi = abi[1:]
abi2=abi[::-1]
res.append([r[0], r[1].strip(), abi, abi2])
from operator import itemgetter
if orderby=='count':
res.sort(key=itemgetter(0))
if orderby=='countreverse':
res.sort(key=itemgetter(0))
res.reverse()
if orderby=='syllable':
res.sort(key=itemgetter(1))
if orderby=='syllablereverse':
res.sort(key=itemgetter(3))
return res
Koodinäide 11. Python funktsioon, mis annab kätte lõpusilbid koos sagedusega.
Eesti vahekeele korpuse sõnade grupeerimisvahendite loomine
Diplomitöö 2014
TLÜ Haapsalu Kolledž 21 Kätlin Jõgisalu
2.5. Kasutaja teksti analüüsilehe arendus
Selleks, et ka EVKK kasutajad saaksid oma korpusväliseid tekste uurida, telliti minult
kasutaja teksti analüüsileht. Sellel lehel saab sisestada oma teksti ja tulemustena saab
vaadata üldtabelit, mis sisaldab kõiki tekstis esinevaid sõnavorme, nende sagedust ja seost
algvormiga. Eraldi on lemmade ja silpide tabelid. Igas tabelis on võimalik sorteerida
sageduse järgi, tähestikuliselt või sõnalõpu järgi.
Teksti analüüsimiseks sisestatud teksti hoitakse sessioonis, et mitte koormata serverit.
Lisaks tuli hakata kõiki funktsioone, mis olid tehtud pöördsõnastiku ja silbitaja jaoks,
kohandama ka teksti analüüsi jaoks. Selleks pidin looma olemasolevate funktsioonide
põhjal ka kõik uued Python funktsioonid, kuna teksti hoitakse mälus ja andmebaasist ei käi
teksti analüüsi leht midagi küsimas.
2.5.1. Andmete ajutine hoidmine
Et mitte koormata EVKK serverit, otsustasime koos juhendajatega hoida kasutaja
sisestatud teksti sessioonis. Teisitisõnu: kui kasutaja avab veebilehitseja ja sisestab oma
teksti ning vajutab nuppu „salvesta“, siis salvestatakse tekst sessiooni ajaks, kuni
veebilehitseja suletakse või sisestatakse uus tekst. Kui tekst on salvestatud ja kasutaja
soovib näha oma tekstis leiduvate lõpusilpide loendit, siis võtab see tabeli esmasel
vaatamisel kauem aega, aga kui tabelit vaadatakse teistkordselt, siis on andmed mällu
salvestatud ja info kuvatakse kiiremini.
Funktsiooniga textToSession (vt koodinäide 12) küsitakse kasutajalt tekst, mis
salvestatakse sessiooni ja käsuga self.REQUEST.SESSION.set antakse korraldus,
et tekst, mida uuritakse salvestatakse sessiooni ja kui sisestatakse uus tekst, siis kustuvad
kõik vanad andmed. Sama käsklus hakkab hiljem tööle ka uuritava info puhul, kui on
vajutatud kindlale tabelile, mida soovitakse kuvada.
def textToSession(self):
"texttosession"
text = self.REQUEST.get('tekst', "")
if text:
self.REQUEST.SESSION.set('usertext', text)
self.REQUEST.SESSION.set('lemmas', None)
self.REQUEST.SESSION.set('syllables', None)
Koodinäide 12. Python funktsioon, mis küsib kasutajalt teksti ja see salvestatakse sessiooni.
Eesti vahekeele korpuse sõnade grupeerimisvahendite loomine
Diplomitöö 2014
TLÜ Haapsalu Kolledž 22 Kätlin Jõgisalu
Funktsiooni textFromSession (vt koodinäide 13) kutsutakse välja teistes funktsioonides,
kus on vaja kätte saada sisestatud teksti. Üks funktsioonidest, mis selle välja kutsub on see,
kus on vaja saada kätte kõik tekstis olevad sõnad ja teine funktsioon on see, kus saadakse
kätte teksti lemmad ehk algvormid. Viimase funktsiooni puhul kutsutakse textFromSession
välja seetõttu, et ESTMORF saab kätte terve teksti pealt lemmad.
def textFromSession(self):
"textfromsession"
return self.REQUEST.SESSION.get('usertext', "Lorem
ipsum")
Koodinäide 13. Kasutaja sisestatud teksti kättesaamiseks mõeldud funktsioon.
2.5.2. Kasutatud algoritmid
Teksti analüüsi lehe puhul võtsin kasutusele eelnevalt valminud funktsioonid, mida
kasutab nii pöördsõnastik kui ka silbitaja. Teksti analüüsiks pidin funktsioone kohandama,
et kõik andmed, mis tulevad on võetud kasutaja sisestatud tekstist ja mis ei ole kuidagi
seotud EVKK serveris oleva andmebaasiga ja samas ei salvestata ka midagi andmebaasi.
Funktsioon getUserTextWordsReverse (vt koodinäide 14) käib küsimas funktsioonilt
getUserTextWords kasutaja sisestatud tekstis olevaid sõnu pöördsõnastiku järgi. Seda
funktsiooni kasutatakse sorteerimisel, et kas kasutaja soovib näha sõnu tähestikuliselt või
pöördsõnastiku järgi, mis tähendab seda, et tähestikuliselt sorteerimise jaoks on ka eraldi
funktsioon olemas.
def getUserTextWordsReverse(self):
"usertextwordsinreversealpha"
m=[w[::-1] for w in self.getUserTextWords()]
m.sort()
return [w[::-1] for w in m]
Koodinäide 14. Python funktsioon, mis saab kasutaja sisestatud tekstist kätte kõik sõnad pöördsõnastiku järgi.
Funktsioon getUserTextSyllables(vt koodinäide 15) tagastab kasutaja sisestatud teksti
silbid. Juhul, kui tekst on juba silbitatud, tagastatakse sessioonis olevad silbid, muul juhul
võetakse kasutaja tekst sõnadena, proovitakse neist igaüks ära silbitada, tulemused
talletatakse sessiooni tulevase kasutamise tarbeks ning ühtlasi tagastatakse funktsioonist.
def getUserTextSyllables(self):
"usertextsyllables"
if self.REQUEST.SESSION.get("syllables", None):
return self.REQUEST.SESSION.get("syllables")
words = self.getUserTextWords()
Eesti vahekeele korpuse sõnade grupeerimisvahendite loomine
Diplomitöö 2014
TLÜ Haapsalu Kolledž 23 Kätlin Jõgisalu
res= []
for r in words:
try:
res.append([r, self.Search.katse20(r).strip()])
except:
res.append([r, "error"])
self.REQUEST.SESSION.set("syllables", res)
return res
Koodinäide 15. Python funktsioon, mis saab kasutaja sisestatud teksti sõnadest kätte silbid.
Funktsioon getUserTextEndSyllables(vt Koodinäide 16) tagastab kasutaja sisestatud teksti
sõnade kõik lõpusilbid.
def getUserTextEndSyllables(self):
"usertextendsyllables"
res=[]
for r in self.getUserTextSyllables():
res.append(r[1].split('-')[-1])
return res
Koodinäide 16. Funktsioon, mis annab kätte kasutaja sisestatud tekstis olevad lõpusilbid
Funktsioon getUserTextEndSyllableCounts (vt koodinäide 17) tagastab kasutaja sisestatud
teksti lõpusilpide esinemissageduse, sorteerides neid vastavalt etteantud parameetrile –
tähestikulises, pöördsõnastikulises ja silbi esinemissageduse järgi.
def getUserTextEndSyllableCounts(self,
syllablekey='syllablecount', desc=0):
"usertextendsyllablecounts"
syllables = self.getUserTextEndSyllables()
res =[]
m=self.getGroupCounts(syllables)
for r in m.keys():
abi=r.strip()
if abi[0]=="-":
abi=abi[1:]
abi2=abi[::-1]
res.append([r, m[r], abi, abi2])
from operator import itemgetter
if syllablekey=='syllablealpha':
res.sort(key=itemgetter(0))
if syllablekey=='syllablereverse':
res.sort(key=itemgetter(3))
if syllablekey=='syllablecount':
res.sort(key=itemgetter(1))
if desc:
res.reverse()
return res
Koodinäide 17. Funktsioon kasutaja sisestatud teksti lõpusilpide esinemissageduse kätte saamise jaoks.
Eesti vahekeele korpuse sõnade grupeerimisvahendite loomine
Diplomitöö 2014
TLÜ Haapsalu Kolledž 24 Kätlin Jõgisalu
2.5.3. Estmorfiga sidumie
Morfoloogiline analüsaator on programm, mis sõna vormist lähtudes määrab selle sõna
struktuuri (nt. tüvi, järelliide, lõpp), sõnaliigi ja käände või pöörde.
ESTMORF-i on võimalik veebis kasutada umbes samamoodi nagu ka kasutaja teksti
analüsaatorit, kuid tulemused on erinevad. Veebis saab kasutaja sisestada teksti või
veebilehe aadressi, kus soovitud tekst asub. Tulemuseks saadakse tekstis olevate sõnade
erinevad näitajad – tüvi, liide, käände- ja pöördelõpp.
EVKK-l on lokaalne eksemplar ESTMORF-ist, mida varasemalt on kasutatud lause
levinud sõnajärjereeglite leidmiseks.
Teksti analüüsi jaoks on ESTMORF-i kasutatud ainult selleks, et kätte saada sõna
algvorme ehk lemmasid.
Kuna varasemalt on tehtud ESTMORF-ile ligipääsuks vajalikud funktsioonid, siis oli minu
ülesanne teha funktsioon, mis saaks ESTMORF-i väljundi sisestatud teksti kohta ning
eraldaks lemmad.
Näide: Juku tuli kooli.
ESTMORF-i väljund:
"<s>"
"<Juku>"
"Juku" L0 S prop sg nom cap @SUBJ #1->2
"<tuli>"
"tule" Li V main indic impf ps3 sg ps af cap <FinV> <Intr> @FMV
#2->2
"<kooli>"
"kool" L0 S com sg adit cap @ADVL #3->2
"<.>"
"." Z Fst #4->4
"</s>"
Funktsioon getTextLemmas(vt koodinäide 18) saab kätte eelmisest näitest tuleva teksti ja
eraldab sellest lemmad (Juku, tule, kool).
def getTextLemmas(self, text=""):
"lemmad"
if text=="" and self.REQUEST.SESSION.get("lemmas",
None):
return self.REQUEST.SESSION.get("lemmas")
if text=="": text=self.textFromSession()
s=self.getMorfo(text)
m=s.strip().split("\n")
Eesti vahekeele korpuse sõnade grupeerimisvahendite loomine
Diplomitöö 2014
TLÜ Haapsalu Kolledž 25 Kätlin Jõgisalu
t={}
abi=[]
i=0
while i<len(m):
if len(m[i])>0:
if m[i][0]=='"' and i>0 and i<len(m)-1:
t[m[i][2:-2].lower()] = m[i+1].split('"')[1]
abi.append(m[i][2:-2])
i=i+1
self.REQUEST.SESSION.set("lemmas", t)
return t
Koodinäide 18. Funktsioon, mis saab kasutaja sisestatud tekstist kätte lemmad ehk algvormid.
2.6. Lahenduse tõstmine avalikku serverisse ja ületõstmisega seotud probleemid
Avalikku serverisse tõstsin tehtud lahendused koos juhendajaga, kuna minule polnud selle
jaoks õiguseid antud.
Avalikku serverisse tõsteti pöördsõnastik koos selle juurde kuuluva zopest väljaspool
töötava silbitajaga. Üle sai tõstetud ka teksti analüüsi ja silbitaja leht. Enne avalikku
serverisse tõstmist eemaldasin koodist mittevajalikud koodiread. Samuti muutsin filoloogi
soovide järgi kasutajaliidest, et see oleks kasutajasõbralikum.
Ületõstmisel pidin hakkama muutma funktsioonide nimesid, kuna testserveris omistasin
neile näiteks katse20-laadsed nimed, mis avaliku serveri jaoks ei ole sobilikud.
Muudatused pidin tegema nii Pythoni funktsioonides, kui ka kujundusfailides, mis
kutsuvad välja Pythoni funktsioone. Lisaks tekkis probleem samuti funktsioonide
nimedega, et ühte kohta olin kirjutanud nime nii ja kujundusfailis olin nime valesti
kirjutanud. Silbitaja ületõstmisel unustasin üle tõsta selle, mille abil silbitaja ei jää hätta
täpitähtedega.
2.6.1. Pöördsõnastiku ületõstmine
Pöördsõnastiku toimimise jaoks pidin esmalt ka avaliku serveri andmebaasile lisama
sõnade ümberpööramise funktsiooni, mida sai ka kohe katsetatud, et see ikka töötab.
Seejärel tõstsin üle SQL päringu, et pöördsõnastik toimiks nii nagu peab, WordTree.py-sse
lisasin Python funktsiooni ja lõpuks sai üle tõstetud ka kujundusfail.
Eesti vahekeele korpuse sõnade grupeerimisvahendite loomine
Diplomitöö 2014
TLÜ Haapsalu Kolledž 26 Kätlin Jõgisalu
Hilisemas faasis, kui pöördsõnastiku lehele sai lisatud lõpusilpide osa, tuli kujundusfailis
teha vastavad muudatused ja ka SQL päringule lisada andmebaasis juurde tehtud silpide
tulp.
Avalikku serverisse lisasin selle versioon pöördsõnastikust
(http://evkk.tlu.ee/wordtree/reverselist.html), kus on silpide tabel ainult lõpusilpide
jaoks(vt Lisa 7), samas kui testserveris on kõikide asetustega silpidetabelid. Eelneva
versiooni ületõstmise põhjuseks on see, et ületõstmise ajal ei olnud avaliku serveri
andmebaasis kõik sõnad silbitatud.
2.7. Silbitajalehe ületõstmine
Enne silbitaja ületõstmist eraldasin silbitaja jaoks vajalikud failid, et avalikku serverisse ei
satuks üleliigseid asju. Kuna failid olid minu arvutis ja ka testserveri baasis, siis pidin need
failid kuidagi avalikku serverisse saama. Selleks laadisin need üles lin2.tlu.ee serverisse ja
selle kaudu oli juhendajal mugav need tõsta EVKK serverisse.
Peale EVKK serverisse üle tõstmist pidin silbitajat katsetama. Esmalt pidin silbitaja
kompileerima ja seejärel tööle panema. Esines väike tõrge, kuna kompileerides teeb
silbitaja automaatselt väljundiks a.out, kuid katsetanud olin silbitaja.bin'iga. Lõpuks
kasutasin peale kompileerimist esmalt a.out väljundit, mis töötas. Katsetamiseks andsin
silbitajale ette sõna „tere“ ja silbitaja tulemuseks sain „te-re“, mis tähendab seda, et
käsureal silbitaja töötab. Peale testimist andsin a.out'ile viisaka nime silbitaja.bin.
Edasi tuli juba hakata tegelema koodijuppide ja SQL lausete lisamisega EVKK serverisse.
Testserveris olid asjadel teised nimetused ja neid tuli muutma hakata. SQL lausete puhul
oli asi veidi lihtsam, sest testserveris sai neile kohe õiged nimetused antud, paar üksikut
said avalikus serveris omale uue nime.
Kuna silbitajaleht (http://evkk.tlu.ee/wordtree/syllableslist.html) oli üks viimaseid asju,
mis tegin, siis selle puhul sai kujundusfail kohe korralikult tehtud, ilma et seal oleks
üleliigseid koodiridasid jms. Nii nagu ka pöördsõnastikul on ka silbitajalehel testserveris
teine versioon. Ületõstetud versioonis kuvatakse peale silbiotsingut ette selle silbiga sõnad,
sõna silbitatuna ja lemma (vt Lisa 8). Testserveris on veel lisatud juurde lahtrid, kus on
olemas ka sõna sagedus ja lemma vasted koos sagedusega. Hetkel otsustas filoloog, et seda
suuremat versiooni avalikku serverisse ei pane enne, kui on saadud EVKK-le juurde
korralik lemmatiseerija, kuna ESTMORF-i abil saadud mittestandardse õppijakeele
lemmad pole täpsed.
Eesti vahekeele korpuse sõnade grupeerimisvahendite loomine
Diplomitöö 2014
TLÜ Haapsalu Kolledž 27 Kätlin Jõgisalu
2.8. Kasutajateksti analüüsi ületõstmine
Teksti analüüsi lehe (http://evkk.tlu.ee/wordtree/usertext.html) puhul oli ületõstmine päris
muretu, kuna varasemast oli juba üle tõstetud silbitaja ja ESTMORF oli EVKK avalikus
serveris olemas. Üle pidin tõstma vaid Python funktsioonid ja kujundusfaili. Funktsioonide
puhul ei pidanud seekord ka muudatusi tegema, kuna olin teinud korrektsete nimedega
funktsioonid, mis enam muutmist ei vajanud.
2.9. Testimine
Testimise käigus jälgisin ühe filoloogi tööd, kes kasutas pöördsõnastikku ja teksti analüüsi.
Filoloogi huvitas, kuidas õppijad moodustavad sõnu ja missuguseid vorme kasutatakse
sagedamini. Selleks kasutas filoloog pöördsõnastikku ja sagedussõnastikku.
Sagedussõnastiku puhul oleks töö liiga suur, sest laadivahelduslikke sõnu tuleks käsitsi
lemmatiseerida. Pöördsõnastiku juurde on tehtud lõpusilpide tabel, milles on kohe näha,
missuguse lõpuga sõnu esineb, mis neist sagedamad. Silbitabelist tuli välja, et kõige
sagedasem lõpusilp on -ga, teisel kohal on -se ja kolmandal -le. Filoloogi arvates, on
pöördsõnastik ja sinna juurde kuuluv silbitabel kasutajasõbralik. Filoloog soovib teada,
millised on 5 kõige sagedasemat-ga lõpusilbiga sõna. Selleks vajutab ta silbitabelis -ga
silbile ja tulemuseks saab, et selleks sõnaks on väga, mida EVKK-s esineb 12714 korda,
teisel kohal on sõna aga (11624 korda), kolmas on sõna kaasaütleva käände ainsuse vorm
sõnaga (4920 korda), neljas sõna on iga (2385 korda) ning viies sõna on aeg ainsuse
osastava käände vormis aega (2235 korda). Filoloog märgib, et väga, aga, sõna ja aeg
kuuluvad õppijakeele 10 sagedama nimisõna hulka.
Selleks, et vorme ja sõnu täpsemalt otsida, kasutaks filoloog silbitajat, sest see võimaldab
ühesuguste alg-, kesk- ja lõpusilpidega sõnade grupeerimist. Tänu silbitajale saab
täiendada eelnevat otsingut ning ühendada vormi- ja sõnamoodustuse kindlate tüvede
kasutamise sagedusega.
Filoloogi arvates on üks mugavamaid ja lihtsamaid teid tekstist erinevate silpide ja
vormide kättesaamiseks teksti analüüs, kuna sellest saab teksti kohta kogu vajaliku info.
Filoloog võttis EVKK eesti keele olümpiaadi tööde alamkorpusest teksti pealkirjaga
„Igaüks on oma õnne sepp“, kopeeris selle teksti analüüsi aknasse ja salvestas. Seejärel
vajutas ta „Üldtabel“ peale ja sai tulemuseks, et sagedasem tekstisõna on sidesõna „ning“,
tegusõnadest on sagedam kindla kõneviisi oleviku vorm „on“, järgnevad sidesõna „ja“
ning eituspartikkel „ei“.
Eesti vahekeele korpuse sõnade grupeerimisvahendite loomine
Diplomitöö 2014
TLÜ Haapsalu Kolledž 28 Kätlin Jõgisalu
Testimise käigus ilmnes ka probleem: ei saanud kätte algvorme ja lemmade tabel ei
töötanud, mahuka teksti puhul on silpide kättesaamine aeglane.
Testimise käigus tegi filoloog ettepanekuid, mida võiks arendama hakata. Filoloog soovis,
et teksti analüüsi oleks võimalik kasutada ka korpuses olevate tekstide juures. Mina
pakkusin välja, et iga teksti juurde tuleks nupp „Teksti analüüs“ ja sellele vajutades viiks
teksti analüüsi lehele, kus siis tekst on juba salvestatud ja on võimalik uurida kõiki asju,
mis teksti analüüsi lehel olemas. Lisaks peaks teksti analüüsi optimeerima, et see ei
muutuks mahukate tekstide puhul liiga aeglaseks.
Eesti vahekeele korpuse sõnade grupeerimisvahendite loomine
Diplomitöö 2014
TLÜ Haapsalu Kolledž 29 Kätlin Jõgisalu
KOKKUVÕTE
Diplomitöö käigus loodi pöördsõnastik koos automaatse silbiotsingu võimalusega ja
nendest sõltuvalt ka kasutaja sisestatud teksti analüüsi leht ja silbitaja leht. Loodud
rakendused on kättesaadavaks tehtud EVKK avalikul lehel.
Pöördsõnastiku lehel on võimalik valida sõna viimase tähe järgi ja sõnad tulevad oma lõpu
järgi tähestikulises järjekorras. Lisaks on võimalik otsida ka sõna lõpu järgi, eraldi on
tehtud automaatne tabel lõpusilpide kohta, kus on olemas sõna sagedus ja silbisagedus,
mida saab ka vastavalt vajadusele järjestada.
Silbitaja lehel on võimalik kasutajal sisestada sõna ja selle tulemusena saab vastu silbitatud
sõna ning lehel on võimalik otsida EVKK-s esinevate sõnavormide hulgast silpide järgi
olenevalt nende asetusest (sõna alguses, keskel, lõpus).
Teksti analüüsi lehel on kasutajal võimalik sisestada oma tekst ja tulemuseks saab teksti
kohta käivad üldandmed: tekstis esinevad sõnad ja vormid koos sageduse ja algvormiga,
lemmade tabel, kus on samuti välja toodud sõna sagedus ja lemmale vastavad vormid ning
lõpuks ka silpide tabelid koos silpide sagedusega.
Diplomitöö käigus sain väga palju uusi teadmisi Python programmeerimiskeelest ja
õppisin tundma PostgreSQL andmebaasi ja ka Zope rakendusserverit. Üks keerukamaid
ülesandeid oli see, kui tuli hoolimata andmete suurest mahust tingitud serveri aeglusest
luua kasutajale mugava kiirusega kasutatav veebileht. Ühe näitena tooks välja
pöördsõnastiku juures olev lõpusilpide tabel, kus silpide üldsagedust on võimalik mitmel
viisil kuvada. Selle jaoks sai tehtud Javascripti funktsioon, mis näitab kasutajale vaid selle
rea andmed, mida kasutaja parajasti küsib või saab automaatselt järjest silpide üldsagedusi.
Loodud rakendused on nüüd korpuse ametlikud osad ja annavad võimaluse vaadata EVKK
arenduse järgmiste ettappide poole, mille hulka kuulub automaatne vigastele sõnadele
õigete vastete pakkumine.
Eesti vahekeele korpuse sõnade grupeerimisvahendite loomine
Diplomitöö 2014
TLÜ Haapsalu Kolledž 30 Kätlin Jõgisalu
ALLIKAD
Anthony, L. (2013). A critical look at software tools in corpus linguistics. Linguistic
Research, Vol. 30, No 2, 141–161.
Biber, D. (1993). Representativeness in Corpus Design. Literary and Linguistic
Computing, Vol. 8, No 4, pp. 243–257.
http://jan.ucc.nau.edu/biber/Biber/Biber_1993.pdf [2014, mai 15].
Browne, C. (2008). Fast reverse() function. PostgreSQL. [2014 jaanuar 15].
http://www.postgresql.org/message-id/[email protected]
Gonzalez, H.J.(2010).How to find the first and last occurrences of a specific character
inside a string in PostgreSQL.[2014, jaanuar 30].
http://stackoverflow.com/questions/2965655/how-to-find-the-first-and-last-occurrences-of-
a-specific-character-inside-a-stri
Eslon, P. (2014, ilmumas). Eesti vahekeele korpus. Keel ja Kirjandus 6.
Eslon, P., Metslang, H. (2007). Õppijakeel ja eesti vahekeele korpus. Eesti
Rakenduslingvistika Ühingu aastaraamat 3. Tallinn: EKS, 99–116.
Kopotev, Mustajoki 2003 = Копотев, М., Мустайоки, А. (2003). Принципы создания
Хельсинкского аннотированного корпуса русских текстов (ХАНКО) в сети
Интернет. – Научно-техническая информация. Серия 2, № 6, 33–37.
Lehtinen jt 1995 = Lehtinen, M., Karvonen, P., Rahikainen, T. (1995). Tekstikorpukset.
Helsinki: Kotimaisten kielten tutkimuskeskuksen julkaisuja 81.
McEnery, A.M., Wilson, A. (1996). Corpus Linguistics. Edinburgh: Edinburgh University
Press.
Muthmann, G. (1999). Reverse English Dictionary: Based on Phonological and
Morphological Principles. Walter de Gruyter.
Put Text in Alphabetical Order.(s.a). TextFinder.com.
http://www.textfixer.com/tools/alphabetize-text-words.php [2014, aprill 15].
Eesti vahekeele korpuse sõnade grupeerimisvahendite loomine
Diplomitöö 2014
TLÜ Haapsalu Kolledž 31 Kätlin Jõgisalu
Thanigaivel jt 2014 = Thanigaivel, R., Ramesh Kumar, S. A. (2014). Intelligent Database
Driven Reverse Dictionary. Journal of Computer Engineering, Vol.16, Issue:2, PP 40–
44.
http://iosrjournals.org/iosr-jce/papers/Vol16-issue2/Version-7/I016274044.pdf
Sirts, K., Võhandu, L. (2009). Korpuste tükeldamine:rakendusi silpide ning allkeeltega.
Eesti Rakenduslingvistika aastaraamat.Tallinn: Eesti Keele Sihtasutus.
http://rakenduslingvistika.ee/ajakirjad/index.php/aastaraamat/article/view/ERYa5.17/101
Morfoloogilise analüsaatori ESTMORF kasutamine.
http://www.filosoft.ee/html_morf_et/morfoutinfo.html [2014, aprill 30].
Eesti Keele Instituut: Silbitaja programm. http://www.eki.ee/tarkvara/silbitus/ [2014
jaanuar 21]
Eesti Keele Instituut: Reeglipõhise morfoloogia demo. http://artur.eki.ee/morf/mf.aspx
Eesti keele Instituut: Teksti silbitaja. http://kn.eki.ee/tool/?m=silbitaja
PostgreSQL.org – About.[2014, veebruar 26]. http://www.postgresql.org/about/
Barol, S.(2010).PostgreSQL.[2014, veebruar 26].
https://wiki.itcollege.ee/index.php/PostgreSQL
The PostgreSQL Global Developement Group.(s.a).PostgreSQL 8.4.21
Documentation.[2014, jaanuar 15]. http://www.postgresql.org/docs/8.4/static/
Zope.org – The world of Zope.[2014, märts 03]. http://www.zope.org/the-world-of-zope
LISA 1. SEARCH.PY FAILI LISATUD FUNKTSIOONID
Selles failis on koondatud tekstidest reeglite otsimise funktsioonid ning ühendused
eraldiseisvate programmidega. Mina lisasin sellesse faili EVKK andmebaasis olevate
sõnade silbitamisega seotud funktsioonid.
def replaceSyllables(self, count=1000): "replacesyllablesinwordtable"
sqlres = self.sqls.getWordsWithoutSyllables()
res = []
for r in sqlres:
res.append([r[0], r[1]])
if count>len(res):
count=len(res)
errors=[]
itsokay=[]
itsokay.append('k')
for i in range(int(count)):
r=res[i]
if r[1] is None:
try:
self.replaceSyllable(r[0])
itsokay.append(r[0])
except:
errors.append(r[0])
return errors + itsokay
def replaceSyllable(self, word):
"replacesyllablecolumninwordstable"
a=self.getSyllables(word)
self.sqls.wordUpdateSyllable(word=word, syllable=a)
return a
def getSyllables(self, word):
"getsyllablefromword"
MORFO_PROGS="/home/jaagup/silbitaja"
cmd = "./silbitaja.bin"
import subprocess
a = subprocess.Popen(cmd, cwd=MORFO_PROGS, shell=True, stderr=subprocess.PIPE,
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
stdo, stde = a.communicate(word.decode("utf-8").encode("iso-8859-13"))
return stdo.decode("iso-8859-13").encode("utf-8")
def setDocrefsSyllable(self, word):
"setdocrefssyllables"
try:
help=self.getSyllables(word)
self.sqls.wordUpdateDocrefsSyllable(word=word, syllable=help)
except:
self.sqls.wordUpdateDocrefsSyllable(word=word, syllable='')
return "error"
def replaceDocrefsSyllables(self, limit=1000):
"silbitasonad"
sqlres = self.sqls.getDocrefsWordsWithoutSyllables()
res = []
for r in sqlres:
res.append(r[0])
errors=[]
itsokay=[]
itsokay.append('k')
# for r in res:
for i in range(int(limit)):
r=res[i]
try:
# self.sqls.wordUpdateSyllable(word=r[0], syllable=self.kysiSilbid2(r[0]))
self.setDocrefsSyllable(r)
itsokay.append(r)
except:
errors.append(r)
return errors + itsokay
LISA 2. WORDTREE.PY FAILI LISATUD FUNKTSIOONID
Selles failis on otsingutega seotud failid, mida nt kasutab sagedussõnastik. Mina lisasin
siia juurde nii pöördsõnastiku, silbitaja- ja teksti analüüsi lehega seotud funktsioonid.
def getWordsReverseBy(self):
s = self.REQUEST.get('char', '')
so = self.REQUEST.get('by', 'alpha')
cfrom=self.REQUEST.get('cfrom', '1')
cto=self.REQUEST.get('cto', '1000000')
s = unicode(s, 'utf-8')
sortorder = 'alpha'
if so == 'alpha': sortorder = 'reverse(word)'
if so == 'word': sortorder = 'word'
if so == 'freq': sortorder = 'count DESC'
if so == 'prim': sortorder = 'prim'
if so == 'lemma': sortorder = 'lemma'
sqlres = self.sqls.getWordsReverse(char='%'+s, order=sortorder, cfrom=cfrom,
cto=cto)
res = []
for r in sqlres:
res.append([r[0], r[1], r[3], r[2]])
return res
def getGroupCounts(self, m):
"grouping"
t={}
n=list(set(m)) #erinevad
for x in n:
t[x]=0
for w in m:
t[w]+=1
return t
def getUserTextWordsAlpha(self):
"usertextwordsinalphabeticalorder"
words= self.getUserTextWords()
words.sort()
return words
def getUserTextStartSyllables(self):
"usertextstartsyllables"
res=[]
for r in self.getUserTextSyllables():
res.append(r[1].split('-')[0])
return res
def getUserTextMiddleSyllables(self):
"usertextmiddlesyllables"
res=[]
for r in self.getUserTextSyllables():
m=r[1].split('-')
if len(m)>2:
for syllable in m[1:-1]:
res.append(syllable)
return res
def getDistinctLemmas(self):
"getdistinctlemmas"
# return "Tere"
return list(set(self.getTextLemmas().values()))
def getDistinctLemmas(self):
"getdistinctlemmas"
# return "Tere"
return list(set(self.getTextLemmas().values()))
def getUserWordsByLemma(self, lemma):
"lemmawords"
words= self.getUserTextWords()
lemmad= self.getTextLemmas()
res=[]
for word in lemmad.keys():
if lemmad[word]==lemma:
res.append(word)
return res
def getUserTextWordsCounts(self):
"usertextwordscounts"
return self.getGroupCounts(self.getUserTextWordsAlpha())
def getUserSortedWordsCounts(self, key='word', desc=0):
"sortedwordsandcounts"
m=self.getUserTextWordsCounts()
n=list(set(m))
if key=='word': n.sort()
if key=='reverseword':
help=[w[::-1] for w in n]
help.sort()
n=[w[::-1] for w in help]
t=[]
for w in n:
t.append([w, m[w]])
if key=='count':
from operator import itemgetter
t.sort(key=itemgetter(1))
if desc:
t.reverse()
return t
LISA 3. REVERSELIST.PT
Pöördsõnastiku kujundusfail.
<html metal:use-macro="container/page_macro/master_page" i18n:domain="korpus">
<title metal:fill-slot="title">Korpus: reverselist</title>
<span tal:omit-tag="" metal:fill-slot="body">
<fieldset style="width:60%">
<legend>Pöördsõnastik</legend>
<a href="?char=a">a</a>
<a href="?char=b">b</a>
<a href="?char=c">c</a>
<a href="?char=d">d</a>
<a href="?char=e">e</a>
<a href="?char=f">f</a>
<a href="?char=g">g</a>
<a href="?char=h">h</a>
<a href="?char=i">i</a>
<a href="?char=j">j</a>
<a href="?char=k">k</a>
<a href="?char=l">l</a>
<a href="?char=m">m</a>
<a href="?char=n">n</a>
<a href="?char=o">o</a>
<a href="?char=p">p</a>
<a href="?char=q">q</a>
<a href="?char=r">r</a>
<a href="?char=s">s</a>
<a href="?char=š">š</a>
<a href="?char=z">z</a>
<a href="?char=ž">ž</a>
<a href="?char=t">t</a>
<a href="?char=u">u</a>
<a href="?char=v">v</a>
<a href="?char=w">w</a>
<a href="?char=õ">õ</a>
<a href="?char=ä">ä</a>
<a href="?char=ö">ö</a>
<a href="?char=ü">ü</a>
<a href="?char=x">x</a>
<a href="?char=y">y</a>
<a href="?char=z">z</a>
</fieldset>
Sisesta sõna lõpp tühikute ja märkideta:
<form action="?">
<input type="text" name="char"/>
<input type="submit" value="Otsi">
</form>
<fieldset style="width:60%">
<legend>Silbi tabel</legend>
<a href="?syllables=yes">Silbid</a>
</fieldset>
<tal:cond condition=" exists:request/syllables">
<script>
var xhr=new XMLHttpRequest();
xhr.onreadystatechange=syllableReceived;
function getSyllableGlobalCount(syllable){
xhr.open("GET", "getSyllableGlobalCount?syllable="+syllable, true);
xhr.send(true);
console.log(syllable);
}
function syllableReceived(){
console.log(xhr.readyState);
if(xhr.readyState==4){
var m = xhr.responseText.split(";");
try{
document.getElementById("syllable_"+m[1]).innerHTML=m[0];
} catch(err){
console.log(err);
}
getNextTd();
}
}
var tds=null;
var tdsplace=-1;
function getNextTd(){
if(tds!=null){
if(tdsplace<tds.length){
getSyllableGlobalCount(tds[tdsplace].id.substring(9));
tdsplace++;
}
}
}
function getAllCounts(){
tds=document.getElementsByClassName("syllable");
tdsplace=0;
for(var i=0; i<tds.length; i++){
console.log(tds[i].id);
}
getNextTd();
}
</script>
<table border="1" >
<tr>
<th>Sõna sagedus</th>
<th>Lõpusilp</th>
<th>Silbi sagedus</th>
</tr>
<tr>
<td><a href='?orderby=count&syllables=jah'>Kasvav</a>|<a
href='?orderby=countreverse&syllables=jah'>Kahanev</a></td>
<td><a href='?orderby=syllable&syllables=jah'>Kasvav</a>|<a
href='?orderby=syllablereverse&syllables=jah'>Kahanev</a></td>
<td><a href='#' onclick='getAllCounts()'>Vali kõik</a></td>
</tr>
<tr tal:repeat="w
python:context.getSyllableEnds(orderby=request.get('orderby','countreverse'))">
<td tal:content="python:w[0]"></td>
<td>
<a tal:attributes="href python:'?char='+w[2]; onmouseover
python:'getSyllableGlobalCount(\''+w[2]+'\')'" tal:content="python:w[1]"></a>
</td>
<td tal:attributes="id python:'syllable_'+w[2]; class python:'syllable'"></td>
</tr>
</table>
</tal:cond>
<tal:cond condition="exists:request/char">
<table border="0">
<tr tal:define="cc request/char">
<th><a href="" tal:attributes="href
string:?char=${cc}&by=alpha">Pöördsõnastik</a> <a href="" tal:attributes="href
string:?char=${cc}&by=word">Tähestikuline</a></th>
<th><a href="" tal:attributes="href
string:?char=${cc}&by=freq">Sagedus</a></th>
<th><a href="" tal:attributes="href
string:?char=${cc}&by=lemma">Lemma</a></th>
</tr>
<tr tal:repeat="w context/getWordsReverseBy">
<td tal:define="word python:w[0]">
<a href="wordinfo.html" tal:attributes="href
string:wordinfo.html?word=${word}" tal:content="word"></a>
</td>
<td tal:content="python:w[1]"></td>
<td tal:define="word python:w[3]">
<a href="" tal:attributes="href string:wordinfo.html?word=${word}"
tal:content="python:word"></a>
</td>
</tr>
</table>
</tal:cond>
<tal:cond condition="exists:request/nomatch">
<span tal:content="context/nOfZeros"></span>
<tal:z repeat="word context/getZeros">
<div>
<a href="wordinfo.html" tal:attributes="href string:wordinfo.html?word=${word}"
tal:content="word"></a>
</div>
</tal:z>
</tal:cond>
</span>
</html>
LISA 4. SYLLABLESLIST.PT
Silbitajalehe kujundusfail.
<html metal:use-macro="container/page_macro/master_page" i18n:domain="korpus">
<title metal:fill-slot="title">Korpus: wordlist</title>
<span tal:omit-tag="" metal:fill-slot="body">
Sisesta sõna:
<form action="?">
<input type="text" name="word"/>
<input type="submit" value="Silbita">
<tal:cond condition="exists:request/word">
<table border="1" >
<tr>
<th>Sõna</th>
<th>Silbitatud sõna </th>
</tr>
<tr>
<td tal:content="python:request.get('word')"></td>
<td tal:content="python:context.Search.getSyllables(word=request.get('word'))"></td>
</tr>
</table>
</tal:cond>
</form>
Sisesta silp kujul %-ga (lõpusilp ga) , ja-% (algussilp ja) või %-lik-%
(kesksilp lik):
<form action="?">
<input type="text" name="syllable"/>
<input type="submit" value="Otsi">
</form>
<table border="1" >
<tr>
<th>Sõna</th>
<th>Silbitatud sõna </th>
<th>Lemma</th>
</tr>
<tr tal:repeat="w
python:context.getWordsBySyllable(syllable=request.get('syllable','').strip())">
<td> <a tal:attributes="href python:'wordinfo.html?word='+w[0]"
tal:content="python:w[0]"></a></td>
<td tal:content="python:w[1]"></td>
<td tal:content="python:w[2]"></td>
</tr>
</table>
</span>
</html>
LISA 5. USERTEXT.PT
Teksti analüüsi lehe kujundusfail.
<html metal:use-macro="container/page_macro/master_page" i18n:domain="korpus">
<title metal:fill-slot="title">Korpus: wordlist</title>
<span tal:omit-tag="" metal:fill-slot="body">
<td id="main_td">
<div class="main">
<h3>Sisesta uuritav tekst</h3>
<form action="?" method="post" tal:define="x context/textToSession">
<textarea name="tekst" rows="30" cols="100"
tal:content="context/textFromSession"></textarea>
<input type="submit" value="Salvesta" />
<br/>
<a href="?normalwords">Sõnad</a>
<a href="?defaulttable">Üldtabel</a>
<a href="?lemmatable">Lemmad</a>
<a href="?Startsyllabletable">Algussilbid</a>
<a href="?Middlesyllabletable">Kesksilbid</a>
<a href="?Syllableendtable">Lõpusilbid</a>
<tal:cond condition="exists:request/normalwords">
<table border="1" >
<tr>
<th><p align="center">Sõnad</p></th>
</tr>
<tr tal:repeat="w context/getUserTextWordsAlpha">
<td tal:content="python:w"></td>
</tr>
</table>
</tal:cond>
<tal:cond condition="exists:request/defaulttable">
<table border="1" >
<tr>
<th><p align="center">Sõna</p></th>
<th><p align="center">Sõna sagedus</p></th>
<th><p align="center">Algvorm</p></th>
</tr>
<tr>
<td><a href='?key=word&defaulttable=jah'>Kasvav</a>|<a
href='?key=reverseword&defaulttable=jah'>Kahanev</a></td>
<td><a href='?key=count&defaulttable=jah'>Kasvav</a>|<a
href='?key=count&desccount=1&defaulttable=jah'>Kahanev</a></td>
<td></td>
</tr>
<tr tal:define="lemma python:context.getTextLemmas()" tal:repeat="w
python:context.getUserSortedWordsCounts(key=request.get('key','count'),
desc=request.get('desccount', 0))">
<td tal:content="python:w[0]"></td>
<td tal:content="python:w[1]"></td>
<td tal:content="python:lemma.get(w[0], 'pole')"></td>
</tr>
</table>
</tal:cond>
<tal:cond condition="exists:request/Startsyllabletable">
<table border="1" >
<tr>
<th><p align="center">Algussilbid</p></th>
<th><p align="center">Silbi sagedus</p></th>
</tr>
<tr>
<td><a href='?syllablekey=syllablealpha&Startsyllabletable=jah'>Kasvav</a>|<a
href='?syllablekey=syllablereverse&Startsyllabletable=jah'>Kahanev</a></td>
<td><a href='?syllablekey=syllablecount&Startsyllabletable=jah'>Kasvav</a> <a
href='?key=count&descsyllable=1&Startsyllabletable=jah'>Kahanev</a></td>
</tr>
<tr tal:repeat="w
python:context.getUserTextSyllableCounts(syllablekey=request.get('syllablekey',
'syllablecount'), desc=request.get('descsyllable', 0), location='start')">
<td tal:content="python:w[0]"></td>
<td tal:content="python:w[1]"></td>
</tr>
</table>
</tal:cond>
<tal:cond condition="exists:request/Middlesyllabletable">
<table border="1" >
<tr>
<th><p align="center">Kesksilbid</p></th>
<th><p align="center">Silbi sagedus</p></th>
</tr>
<tr>
<td><a href='?syllablekey=syllablealpha&Middlesyllabletable=jah'>Kasvav</a>|<a
href='?syllablekey=syllablereverse&Middlesyllabletable=jah'>Kahanev</a></td>
<td><a href='?syllablekey=syllablecount&Middlesyllabletable=jah'>Kasvav</a>|<a
href='?key=count&descsyllable=1&Middlesyllabletable=jah'>Kahanev</a></td>
</tr>
<tr tal:repeat="w
python:context.getUserTextSyllableCounts(syllablekey=request.get('syllablekey',
'syllablecount'), desc=request.get('descsyllable', 0), location='middle')">
<td tal:content="python:w[0]"></td>
<td tal:content="python:w[1]"></td>
</tr>
</table>
</tal:cond>
<tal:cond condition="exists:request/Syllableendtable">
<table border="1" >
<tr>
<th><p align="center">Lõpusilbid</p></th>
<th><p align="center">Silbi sagedus</p></th>
</tr>
<tr>
<td><a href='?syllablekey=syllablealpha&Syllableendtable=jah'>Kasvav</a>|<a
href='?syllablekey=syllablereverse&Syllableendtable=jah'>Kahanev</a></td>
<td><a href='?syllablekey=syllablecount&Syllableendtable=jah'>Kasvav</a>|<a
href='?key=count&descsyllable=1&Syllableendtable=jah'>Kahanev</a></td>
</tr>
<tr tal:repeat="w
python:context.getUserTextSyllableCounts(syllablekey=request.get('syllablekey',
'syllablecount'), desc=request.get('descsyllable', 0), location='end')">
<td tal:content="python:w[0]"></td>
<td tal:content="python:w[1]"></td>
</tr>
</table>
</tal:cond>
<tal:cond condition="exists:request/lemmatable">
<table border="1" >
<tr>
<th><p align="center">Algvorm</p></th>
<th><p align="center">Sagedus</p></th>
<th><p align="center">Vormid</p></th>
</tr>
<tr>
<td><a href='?lemmakey=lemma&lemmatable=jah'>Kasvav</a>|<a
href='?lemmakey=lemma&desclemma=1&lemmatable=jah'>Kahanev</a></td>
<td><a href='?lemmakey=lemmacount&lemmatable=jah'>Kasvav</a>|<a
href='?lemmakey=lemmacount&desclemma=1&lemmatable=jah'>Kahanev</a></td>
<td></td>
</tr>
<tr tal:repeat="w python:context.getLemmasCounts(lemmakey=request.get('lemmakey',
'lemmacount'), desc=request.get('desclemma', 0))">
<td tal:content="python:w[0]"></td>
<td tal:content="python:w[1]"></td>
<td tal:content="python:', '.join(context.getUserWordsByLemma(w[0]))"></td>
</tr>
</table>
</tal:cond>
</form>
</div>
</td>
</span>
</html>
LISA 6. SQL PÄRINGUD
SQL päringud, mille abil Python funktsioonid suhtlevad serveriga.
getSyllableGlobalCount - select count(*) from docrefs where docrefs.word like
('%'|| <dtml-sqlvar syllable type="string"> );
getWordsReverse - SELECT word, count('word'), words.lemma, prim, words.syllables
FROM docrefs
LEFT JOIN words USING(word)
WHERE word LIKE <dtml-sqlvar char type="string">
GROUP BY word, words.lemma, prim, words.syllableswo
HAVING count('word') BETWEEN <dtml-sqlvar cfrom type="int"> and
<dtml-sqlvar cto type="int">
ORDER BY <dtml-var order>, reverse(word);
groupBySyllableEnd - select count(*), substr(syllables, last_post(syllables,'-'))
as ots from words group by ots order by count(*) desc;
wordsBySyllable - SELECT word, syllables, prim, lemma, category, gram FROM words
WHERE syllables like <dtml-sqlvar syllable type="string">;
LISA 7. PÖÖRDSÕNASTIK
Pildil on ekraanitõmmis avalikus serveris olevast pöördsõnastikust koos lõpusilpide
tabeliga.
LISA 8. SILBITAJALEHT
Pildil on silbitajaleht, kus saab kasutaja ise soovitud sõna silbitada ja ka EVKK
andmebaasist otsida soovitud silpi vastavalt selle asukohale.
LISA 9. TEKSTI ANALÜÜSI LEHT
Pildil on teksti analüüsi leht, kus kasutaja saab oma teksti sisestada ja seda uurida.