def synth(lemma, pos, form_ids): """ Do not allow entries where the lemma differs from the first form e.g. inimesed_N = mkN "inimene" ... """ forms1 = synthesize(lemma, form_ids[0], pos) if lemma == take_first(forms1): yield forms1 else: return for form_id in form_ids[1:]: yield synthesize(lemma, form_id, pos)
def get_forms(lemma, pos=wn.NOUN): """Get the relevant forms given the lemma and its POS. Note that synthesize also handles compounding and is smart about words like 'kuupalk'. (In the previous approaches we did compounding separately and applied form generation only to the last element of the compound.) """ if pos == wn.NOUN or pos == 'n': return [ merge(synthesize(lemma, form, 'S')) for form in NOUN_FORMS ] elif pos == wn.ADJ or pos == 'a': return [ merge(synthesize(lemma, form, 'S')) for form in NOUN_FORMS ] elif pos == wn.ADV or pos == 'b': return [ lemma ] else: return [ merge(synthesize(lemma, form, 'V')) for form in VERB_FORMS ]
def addToContent(word, content, casename, countid, nominative, sen_x,sg_pl,title,clitic,pos): info = SubElement(content,'info') #XML loomine info.set('id', str(countid)) s = SubElement(info,'s') nr = SubElement(info,'nr') case = SubElement(info,'case') n = SubElement(info,'n') synt = synthesize(nominative, sg_pl+' '+casename, pos) #kontorll kas leidub rohkem kui üks vastus if len(synt)>1: wordLower = word.lower() if wordLower in synt: for nom in synt: if nom != wordLower: answer = SubElement(info, 'answer') answer.text= nom answer = SubElement(info, 'word') answer.text = word n.text = nominative nr.text = case_dict[sg_pl] case.text = case_dict[casename] s.text = sen_x if clitic != "": cliticTag = SubElement(info,'clitic') cliticTag.text = clitic titleTag = SubElement(info,'title') titleTag.text = title return content
def change_tense(value_dict): morphed_distractors =[] morphed_word_pairs=[] ending = value_dict["ending"] if ending == "0": morphed_distractors = value_dict return morphed_distractors["synonyms"],morphed_word_pairs print ("ending ",ending) for val in value_dict["synonyms"]: if val.endswith(ending): morphed_distractors.append(val) else: text = Text(val) lemma_word = text.lemmas[0] lemma_word = lemma_word.split("|")[0] lemma_word=lemma_word.capitalize() transformed_word = synthesize(lemma_word, form=value_dict["form"],partofspeech=value_dict["POS"]) if len(transformed_word) ==0: morphed_distractors.append(val) else: if transformed_word[0].capitalize() not in morphed_distractors: morphed_distractors.append(transformed_word[0].capitalize()) if not val==lemma_word==transformed_word[0].capitalize(): morphed_word_pairs.append((val,lemma_word,transformed_word[0].capitalize())) return morphed_distractors,morphed_word_pairs
def synthesize_lemma(word_to_synthezise, original): synthesized = synthesize(word_to_synthezise, original[FORM]) # milleks see vajalik oli # if synthesized is None: # synthesized = word_to_synthezise if synthesized not in replacement_list and word_to_synthezise != original[ LEMMA]: # veendume, et me ei asenda halvema variandiga return synthesized
def add_lemma_to_result(word_to_add, replacement_list, similarity=MIN_SIMILARITY): # Kui sarnasus on alampiiris väiksem jätame sõna lõpptulemusse lisamata if get_word_similarity(word_to_add, word[LEMMA], similarity) < similarity: return # Sünteesime lemmale vastava muutevormi(d) lemma_synthesized = synthesize(word_to_add, word[FORM]) # Kui süntees tagastas mitu võimalikku muutevormi, lisame kõik lõpptulemusse for synthesized in lemma_synthesized: synthesized_lemmas[synthesized] = word_to_add print(synthesized_lemmas) replacement_list.append(synthesized)
def word_shapes(row): word = row["Estonian word"] postag = row["Estonian postag"] if postag == "S" or postag == "A" or postag == "N" or postag == "O" or postag == "P" or postag == "H" or postag == "C": shape1 = synthesize(word, "sg g") shape2 = synthesize(word, "sg p") shape3 = synthesize(word, "pl p") shape4 = synthesize(word, "adt") return shape1 + shape2 + shape3 + shape4 if postag == "V": verb_shape1 = synthesize(word, "ma") verb_shape2 = synthesize(word, "da") verb_shape3 = synthesize(word, "n") verb_shape4 = synthesize(word, "takse") return verb_shape1 + verb_shape2 + verb_shape3 + verb_shape4 else: return "-"
import xml.etree.ElementTree as ET from xml.etree.ElementTree import ElementTree from xml.etree.ElementTree import SubElement import glob import re import operator from pprint import pprint from estnltk.names import TEXT, ANALYSIS, ROOT, POSTAG, FORM, LEMMA, CLITIC from estnltk import Disambiguator from estnltk import synthesize from estnltk import Text from numpy import loadtxt from estnltk import Disambiguator pprint(Text('mina').analysis) pso = 'P' print(synthesize('mina', 'sg p', 'S'))
def lihtsusta(osalaused, pikk_lause): valjund_listina = [] eelmisest = None #vajadusel jäetakse meelde osa tekstist ja lisatakse järgmise lause algusesse o = 0 while o < len(osalaused): if osalaused[o]['text'] in [".", "!", "?", "***", "..."]: #antud juhud ei ole laused o += 1 if o >= len(osalaused): break osalause = uuenda_lause( osalaused[o]) #salvestab hetkel uuritava osalause muutujasse if eelmisest: #vajadusel lisab eelmise osalause antud lause algusesse if osalause['words'][0]['analysis'][0][ 'partofspeech'] == 'Z': #kirjavahemärgi ette tühik ei käi osalause = uuenda_lause(eelmisest['text'] + osalause['text']) else: osalause = uuenda_lause(eelmisest['text'] + ", " + osalause['text']) eelmisest = None #Muutused lause lõpuga seoses #kui osalause lõppeb sidesõnaga, mis ei ole 'või' ega 'ega', tuleb see kustutada if osalause['words'][-1]['analysis'][0]['partofspeech']=='J' and \ osalause['words'][-1]['text'] not in ['või', 'ega']: viimase_sona_algus = osalause['words'][-1]['start'] - 1 osalause = uuenda_lause(osalause['text'][:viimase_sona_algus]) #vajadusel muudab/lisab lauselõpumärgi if osalause['words'][-1]['analysis'][0]['partofspeech'] != 'Z': if osalause['text'][-1] != '.': osalause = uuenda_lause(osalause['text'] + ".") elif osalause['words'][-1]['text'] in [',', ':', ';', ')', '-', '–']: osalause = uuenda_lause((osalause['text'][:-1]).strip() + ".") #Muutused lause algusega seoses #kui osalause algab sidesõnaga (on 'ja' või 'ning' ega alga suurtähega), tuleb see välja jätta if osalause['words'][0]['analysis'][0]['partofspeech'] == 'J' and \ osalause['words'][0]['text'].lower() in ["ja", "ning"] and \ not osalause['words'][0]['text'][0].isupper(): esimese_sona_lopp = osalause['words'][0][ 'end'] + 1 #lauset alustatakse kohast, kus esimese sõna lõppeb + tühik osalause = uuenda_lause(osalause['text'][esimese_sona_lopp:]) #kui lause algab kirjavahemärgiga, jäetakse see ja tema järel olev tühik ära if osalause['words'][0]['analysis'][0]['partofspeech'] == 'Z': osalause = uuenda_lause(osalause['text'][1:].strip()) try: #võib juhtuda, et nüüdseks pole enam ühtki sõna osalauses, seega 'try' #kui osalause algab verbiga, otsitakse lausest subjekti või verbile vastavat kindlat pronoomenit if osalause['words'][0]['analysis'][0][ 'partofspeech'] == 'V' and not osalause['text'][0].isupper( ): # ainult verbist koosnev lause jäetakse puutumatuks if len(osalause.words) != 1 and not (len( osalause.words) == 2 and osalause['text'][-1] == "."): tegija = None #otsib tegijaks lauses olevat subjekti subjektiotsing = tuvasta_subjekt(osalause['text'], pikk_lause['text']) if subjektiotsing: #kui leiti subjekt: tegija = subjektiotsing[0] #määrab subjekti tegijaks osalause['text'] = osalause[ 'text'][:subjektiotsing[1]] + osalause['text'][ subjektiotsing[2] + 1:] #kustutab algsest osalause tekstist leitud subjekti else: #kui subjekti ei leitud, otsib, kas leidub verbile vastav kindel pronoomen tegija = tuvasta_alus(osalause['words'][0]['analysis']) if tegija != None: #kui subjekt / kindel pronoomen leiti, võib selle lisada lause algusesse osalause = uuenda_lause(tegija + " " + osalause['text']) #asesõnaga algavate lausete puhul võiks tulevikus asendada sobivaima sõnaga (viitealusega), hetkel pannakse sobivaim asesõna. elif osalause['words'][0]['analysis'][0]['partofspeech'] == 'P': asendaja = osalause['words'][0]['text'] vorm = osalause['words'][0]['analysis'][0]['form'] esimese_sona_lopp = osalause['words'][0][ 'end'] #indeks, kus esimene sõna lõppeb #kui lause ei alga piisavalt selge asesõnaga või suure tähega, siis see asendatakse if osalause['words'][0]['analysis'][0]['lemma'] not in ['mina', 'sina', 'tema', 'meie', 'teie', 'nemad', 'see', 'too', 'kõik', 'ise', 'mõni', 'sama', 'säärane', 'mõlema', 'üks', 'iga', 'keegi', 'selline', 'oma', 'kumb', 'mitu', 'miski', 'üksteise', 'missugune'] and \ not osalause['text'][0].isupper(): if osalause['words'][0]['analysis'][0]['lemma'] == "mis": asendaja = "See" tegija = None else: try: #igas lauses ei pruugi olla verbi #asendaja leitakse verbi järgi verbiindeks = Text( osalause['text']).postags.index('V') tegija = tuvasta_alus( osalause['words'][verbiindeks]['analysis']) if tegija != None: asendaja = tegija #kui asendajat ei leitud, tuleb võtta "Tema" else: asendaja = 'Tema' except: #muul juhul tuleb valida "Tema" asendaja = 'Tema' tegija = None #asendaja lausesse panemine: #võimalusel leitakse asendaja ainsus/mitmus tema viitealuse järgi am = sg_pl(osalause['words'][0]['text'], pikk_lause) if am: #kui leiti vorm, siis võib pronoomeni asendada vorm = am + " " + vorm.split( " ", 1 )[1] #liidab ainsuse/mitmuse ülejäänud vormi tunnustega uus_asendaja = synthesize(asendaja, vorm) if len( uus_asendaja ) == 2: #võimalusel võetakse pikem variant (nt 'sest' vs 'sellest') asendaja = uus_asendaja[1] else: asendaja = uus_asendaja[0] osalause = uuenda_lause( asendaja + osalause['text'][esimese_sona_lopp:]) else: #kui vormi ei leitud, tuleb see osalause liita eelmisega tagasi kokku osalause = uuenda_lause(valjund_listina[-1][:-1] + ", " + osalause['text']) valjund_listina = valjund_listina[:-1] #Edasised toimingud lausega vastavalt selle algusele / lõpule #Sõnadega ....... või tegusõnadega, mille 'form' väärtus on 'maks' või 'des', #algav lause liidetakse eelmisega tagasi kokku if len(valjund_listina)>=1 and ((osalause['words'][0]['analysis'][0]['lemma'] in \ ['kui', 'kas', 'kuidas', 'kus', 'kust', 'et', 'kuid', 'nagu', 'missugune', 'ehkki', 'ent', 'kuigi', 'ehk', 'miks', 'kuni', 'mil', 'vaid', 'sest', 'vist', 'aga', 'kuna', 'siis', 'kuivõrd', 'alates', 'mitu'] and not osalause['text'][0].isupper()) or \ osalause['words'][0]['analysis'][0]['form'] in ['maks', 'des'] or \ osalause['words'][0]['text'] in ['kuhu'] or \ (osalause['words'][0]['text'] in ['see', 'seda'] and (', see' in pikk_lause['text'] or ', seda' in pikk_lause['text']))): osalause = uuenda_lause(valjund_listina[-1][:-1] + ", " + osalause['text']) valjund_listina = valjund_listina[:-1] #Sõnaga 'kui', 'kuna(s)', 'nagu', 'et' või fraasiga "Ainult kui", "Sel(lel) ajal kui", "Enne kui" algav, #või sõnaga 'see' või 'seda' lõppev #lause tuleb liita järgmisega if (len(valjund_listina)==0 and osalause['words'][0]['analysis'][0]['lemma'] in ['kui', 'kuna', 'kunas', 'nagu', 'et']) or \ re.search("(([Aa]inult)|([Ss]el(lel)? ajal)|([Ee]nne)) kui", osalause['text']) or \ osalause['words'][-2]['text'] in ['see', 'seda']: eelmisest = uuenda_lause(osalause['text'][:-1]) #Sõnaga 'või', 'ega', lõppev lause tuleb liita järgmisega elif osalause['words'][-2]['text'] in ['või', 'ega']: eelmisest = uuenda_lause(osalause['text'][:-1]) #ühesõnalise lause puhul tuleb see sõna liita eelmisele lausele või viia järgmise osalause algusesse if len(osalause['text'].split()) == 1 and eelmisest == None: if len(valjund_listina) > 0: osalause = uuenda_lause(valjund_listina[-1][:-1] + " ja " + osalause['text']) valjund_listina = valjund_listina[:-1] else: osalause = osalaused[o] valjund_listina.append(osalause['text']) eelmisest = None #Muul juhul: lause algaks suure tähega ja korrastatud osalause võib lisada väljundisse elif eelmisest == None: osalause['text'] = osalause['text'][0].capitalize( ) + osalause['text'][1:] if osalause['text'][-1] != '.': osalause['text'] = osalause['text'].strip() + '.' valjund_listina.append(osalause['text']) eelmisest = None o += 1 except: o += 1 #kui 'eelmine' ei ole tühi, kuid kõik osalaused on üle vaadatud, tuleb viimane osalause lisada lausete listi if eelmisest != None and (len(valjund_listina) == 0 or valjund_listina[-1] not in eelmisest): #lause algus suureks eelmisest['text'] = eelmisest['text'][0].capitalize( ) + eelmisest['text'][1:] #lause lõppu punkt if eelmisest['words'][-1]['analysis'][0]['partofspeech'] != 'Z': if eelmisest['text'][-1] != '.': eelmisest['text'] = eelmisest['text'] + "." elif eelmisest['words'][-1]['text'] in [',', ':', ';', ')', '-']: eelmisest['text'] = (eelmisest['text'][:-1]).strip() + "." #lisab listi valjund_listina.append(eelmisest['text']) valjund = ' '.join( valjund_listina ) #ühendab listis olevad laused tühikutega eraldatuna üheks String-tüüpi sõneks. return valjund
def lihtsusta(esialgne_sisend): """ Peameetod sisendi lihtsustamiseks :param str esialgne_sisend: lihtsustatav sisend :return: paar lihtsustatud sisendist ning lisainformatsioonist """ debug_info = "" # Sisendi korrastamine sisend_sõne = eeltöötlus(esialgne_sisend) if DEBUG: debug_info += str(sisend_sõne) + '\n' sisendid = Text(sisend_sõne, **KWARGS) tulemus = "" onLihtsustatud = False for sisend in sisendid.sentence_texts: # ANALÜÜS sisend = Text(sisend, **KWARGS) if DEBUG: debug_info += str(sisend.word_texts) + '\n' debug_info += str(sisend.postags) + '\n' parser = MaltParser() initial_output = parser.parse_text(sisend, return_type='conll') debug_info += '\n'.join(initial_output) + '\n' for sõna in sisend.split_by("words"): otsing = None if re.match('.?".*".?', sõna.text): otsing = re.search('^.?"(.*)".?$', sõna.text) elif re.match('.?\(.*\).?', sõna.text): otsing = re.search('^.?\((.*)\).?$', sõna.text) if otsing: sisu = otsing.group(1) rekursioon = lihtsusta(sisu) debug_info += rekursioon[1] + '\n' sisend = sisend.replace(sisu, rekursioon[0]) verbi_loendur = 0 for i in range(len(sisend.postags)): if sisend.postags[i] == "V": verbi_loendur += 1 # Lõpetame lause vaatamise kui meil on ainult 1 verb, kuna sel juhul on ilmselt tegemist lihtlausega if verbi_loendur <= 1: debug_info += "__ÜKS TEGUSÕNA__\n" tulemus += sisend.text + " " continue # Suur lausealgustäht jäetakse alles vaid lühendite ning pärisnimede puhul. if sisend.postags[0] not in {"H", "Y"}: sisend.word_texts[0] = sisend.word_texts[0].lower() sisend.tag_syntax() süntaksi_list = list(zip(sisend.word_texts, sisend[LAYER_CONLL])) if DEBUG: debug_info += pformat(süntaksi_list) analüüsi_list = sisend.analysis siht_map = defaultdict(list) sõna_list = [] mitte_juur_lausepeasõnad = [] lause_peasõnad = [] tegusõnad = [] for i, element in enumerate(süntaksi_list): label, siht = element[1]['parser_out'][0] analüüs = analüüsi_list[i][0] pos = analüüs["partofspeech"] word = element[0] for char in {'"', '(', ')'}: if char in word: word = re.sub('(^[.,!?]|[.,!?]$)', '', word) break if re.match('.?\(.*\).?', word): label = "@<" pos = "SLG" if analüüsi_list[siht][0]["partofspeech"] == "Z": siht -= 1 if siht > 0 else 0 element_info = { "indeks": i, "word": word, "lemma": analüüs["lemma"], "form": analüüs["form"], "pos": pos, "label": label, "target": siht } if DEBUG: debug_info += str(element_info) + '\n' if label == "ROOT": lause_peasõnad.append(element_info) elif label == "@FMV": mitte_juur_lausepeasõnad.append(element_info) if label in TEGUSÕNAD: tegusõnad.append(element_info) if not pos == "Z": siht_map[siht].append(element_info) sõna_list.append(element_info) # Kui meil on mitu ROOT elementi, siis jätame lause vahele if len(lause_peasõnad) > 1: debug_info += "__MITU JUURSÕNA__\n" tulemus += sisend.text + " " continue tegusõnad = lause_peasõnad + tegusõnad lause_peasõnad.extend(mitte_juur_lausepeasõnad) if DEBUG: debug_info += pformat(tegusõnad) debug_info += pformat(lause_peasõnad) # TRANSFORMATSIOON for verb in tegusõnad: for alluv in siht_map[verb["indeks"]][:]: if alluv in lause_peasõnad: peasõnadEraldatud = False if not (verb["label"] == "ROOT" and verb["pos"] != "V"): for alluva_alluv in siht_map[alluv["indeks"]]: if alluva_alluv["indeks"] > verb["indeks"] and ( alluva_alluv["label"] == "@J" and alluva_alluv["lemma"] in {"ja", "ning"} or alluva_alluv["pos"] == "P" and alluva_alluv["lemma"] in {"kes", "mis"}): subjekt = leiaOtseneSubjekt(alluv, siht_map) if subjekt is None: uus_subjekt = leiaTegusõnaSubjekt( verb, siht_map, sõna_list) if uus_subjekt != None: peasõnadEraldatud = True alluva_alluv.update(uus_subjekt) else: peasõnadEraldatud = True if alluva_alluv != subjekt: siht_map[alluv["indeks"]].remove( alluva_alluv) if peasõnadEraldatud: siht_map[verb["indeks"]].remove(alluv) break if not peasõnadEraldatud: lause_peasõnad.remove(alluv) if len(lause_peasõnad) <= 1: debug_info += pformat(lause_peasõnad) debug_info += "__ÜKS PEASÕNA__\n" tulemus += sisend.text + " " continue # Muudame kõik asesõnad vastavateks nimisõnadeks. Kasutades nimisõna mitmesust ja asesõna käänet. # Kasutades nii asesõna mitmesust kui käänet on võimalik, et tulemus pole see, mida ootame. Näiteks võib ainsuse asemel olla mitmus. # Semantilise info puudumise tõttu, saame iga tegusõna kohta asendada vaid ühe asesõna. kasutatud_tegusõnad = set() kustutatavad = [] for i, element in enumerate(sõna_list): if element["pos"] == "P": if DEBUG: debug_info += str(element) + '\n' if not (i > 2 and sõna_list[i - 1]["pos"] == "Z" and sõna_list[i - 2]["pos"] in {"S", "H"} and element["lemma"] in {"kes", "mis"}): siht = sõna_list[element["target"]] if element["label"] == "@SUBJ": subj_counter = 0 for alluv in siht_map[siht["indeks"]]: if alluv["pos"] == "S" and alluv[ "label"] == "@SUBJ": subj_counter += 1 if subj_counter > 0: kustutatavad.append(element) continue if siht["pos"] != "V" or siht["target"] == -1: continue asendus = sõna_list[siht["target"]] if asendus["pos"] not in { "S", "H" } or siht["indeks"] in kasutatud_tegusõnad: continue else: asendus = sõna_list[i - 2] siht = sõna_list[element["target"]] if siht["indeks"] in kasutatud_tegusõnad: continue if siht["pos"] == "V": kasutatud_tegusõnad.add(siht["indeks"]) asendus_lemma = asendus["lemma"] asendus_pos = asendus["pos"] uus_sõnavorm = asendus["form"].split(" ")[0] + " " asesõna_sõnavorm = element["form"].split(" ") uus_sõnavorm += asesõna_sõnavorm[1 if len(asesõna_sõnavorm ) > 1 else 0] süntees = synthesize(asendus_lemma, uus_sõnavorm, asendus_pos) asendus_lemma_asesõna_vormis = asendus_lemma if len(süntees) > 0: asendus_lemma_asesõna_vormis = synthesize( asendus_lemma, uus_sõnavorm, asendus_pos)[0] element["word"] = asendus_lemma_asesõna_vormis element["lemma"] = asendus_lemma element["form"] = uus_sõnavorm element["pos"] = asendus["pos"] for kustutatav in kustutatavad: try: siht_map[sõna_list[kustutatav["target"]]["indeks"]].remove( kustutatav) sõna_list.remove(kustutatav) except: continue if DEBUG: debug_info += pformat(dict(siht_map)) debug_info += pformat(lause_peasõnad) debug_info += "---------------------------------------------------\n" debug_info += str(sisend_sõne) + '\n' debug_info += "---------------------------------------------------\n" for sõna in lause_peasõnad: lause = moodustaLause(sobitaMalli(sõna, siht_map)) tulemus += lause.strip() + '. ' onLihtsustatud = True if onLihtsustatud: debug_info += "__LIHTSUSTATUD__\n" return (tulemus.strip(), debug_info)
text = '''Keeletehnoloogia on arvutilingvistika praktiline pool. Keeletehnoloogid kasutavad arvutilingvistikas välja töötatud teooriaid, et luua rakendusi (nt arvutiprogramme), mis võimaldavad inimkeelt arvuti abil töödelda ja mõista. Tänapäeval on keeletehnoloogia tuntumateks valdkondadeks masintõlge, arvutileksikoloogia, dialoogisüsteemid, kõneanalüüs ja kõnesüntees. ''' # first tokenize and then morphologically analyze morf_analyzed = analyzer(tokenizer(text)) # print some results print (morf_analyzed.lemmas) print (morf_analyzed.postags) # print more information together pprint (list(zip(morf_analyzed.word_texts, morf_analyzed.lemmas, morf_analyzed.forms, morf_analyzed.postags))) # synthesis example from estnltk import synthesize print (synthesize('pood', form='pl p', partofspeech='S')) print (synthesize('palk', form='sg kom'))
text = '''Keeletehnoloogia on arvutilingvistika praktiline pool. Keeletehnoloogid kasutavad arvutilingvistikas välja töötatud teooriaid, et luua rakendusi (nt arvutiprogramme), mis võimaldavad inimkeelt arvuti abil töödelda ja mõista. Tänapäeval on keeletehnoloogia tuntumateks valdkondadeks masintõlge, arvutileksikoloogia, dialoogisüsteemid, kõneanalüüs ja kõnesüntees. ''' # first tokenize and then morphologically analyze morf_analyzed = analyzer(tokenizer(text)) # print some results print(morf_analyzed.lemmas) print(morf_analyzed.postags) # print more information together pprint( list( zip(morf_analyzed.word_texts, morf_analyzed.lemmas, morf_analyzed.forms, morf_analyzed.postags))) # synthesis example from estnltk import synthesize print(synthesize('pood', form='pl p', partofspeech='S')) print(synthesize('palk', form='sg kom'))