def gdep(dbcon=False): """"Aluksi määritellään kaikkien elementtien luokaksi gdep, jota sitten tarkennetaan niin pitkälle kuin mahdollista """ LogNewDeprel('Create the category of gdep in the SN data') dbcon.query('UPDATE ru_conll SET contr_head = head, contr_deprel = %(contrdep)s',{'contrdep':'gdep'}) log('The gdep category was succesfully created')
def cdep(dbcon=False): """ Sivulauseet SN-aineistossa: SN-jäsennystä muutetaan siten, että sivulauseen pääverbistä tehdään päälauseen dependentti, josta sivulauseen aloittava konjunktio riippuu. Kontrastiivinen analyysikerros toteutetaan siten, että kaikki alisteisen sivulauseen pääsanat luokitellaan cdep-kategoriaan, jolloin niistä käy ilmi, että kyseessä on sivulauseen muodostama täydennys tai määrite, muttei sitä, minkä tyypin argumentti on kyseessä. Kuvatunlainen kompromissi on väistämätön, sillä TDT-analyysi ei anna sivulauseiden suhteesta pääsanaansa yhtä tarkkaa informaatiota kuin SN-analyysi ja toisaalta SN-analyysi ei jaottele sivulauseita sen mukaan, ovatko ne täydennyksiä vai määritteitä. Tuloksena on väljempi yläkäsite, josta käy ilmi se, että kyseessä on sivulauseen muodostama argumentti. Tarkempi informaatio ei sinänsä katoa, sillä se on edelleen läsnä kielikohtaisissa jäsennyksissä. """ LogNewDeprel('Create the cdep and the sc categories in SN') thisSearch = makeSearch(database=dbcon.dbname, dbtable = 'ru_conll', ConditionColumns={'deprel':('подч-союзн',)}) updated = 0 for key, matchlist in thisSearch.matches.items(): for match in matchlist: try: mhead = match.matchedsentence.words[match.matchedword.head] dbcon.query('UPDATE ru_conll SET contr_head = %(contrhead)s, contr_deprel = %(contrdep)s WHERE id = %(matchid)s',{'contrhead':match.matchedword.tokenid,'contrdep':'sc','matchid':mhead.dbid}) dbcon.query('UPDATE ru_conll SET contr_head = %(contrhead)s, contr_deprel = %(contrdep)s WHERE id = %(matchid)s',{'contrhead':mhead.head,'contrdep':'cdep','matchid':match.matchedword.dbid}) updated += 1 except KeyError: log('KeyError with word {}, sentence {}'.format(match.matchedword.token,match.matchedsentence.sentence_id)) log('Updated {} items in the db'.format(updated))
def semsubj(dbcon=False): """Otan käyttöön termin semsubj nesessiivilauseille ja muille vastaaville rakenteille, joissa SN-analyysi määrittää infinitiivimuotoisen verbin subjektiksi. Näin TDT:n nsubj ja SN:n 2-kompl (1-kompl!) ja dat-subj muuttuvat (näiden lauseiden osalta) kontrastiivisessa kerroksessa muotoon semsubj. Rakenteen finiittimuotoinen verbi katsotaan SN-jäsennyksen mukaisesti juureksi ja infinitiivimuotoinen verbi luetaan infcomp-kategoriaan. Muutan kuitenkin SN-jäsennystä TDT-jäsennyksen mallin mukaiseksi siinä, että semsubj-kategorialla analysoitu sanamuoto katsotaan infinitiivimuodon eikä apuverbin dependentiksi. HUOM! - verbi on joskus muu kuin predik (1-kompl,razjasnit) - semsubj-kandidaatti voi olla predik! - Lisäksi infinitiivitäydennys puuttuu joskus kokonaan (мне надо к нему) """ LogNewDeprel('Create the class of SemSubj in SN ') featset = Featset() thisSearch = makeSearch(database=dbcon.dbname,dbtable='ru_conll', ConditionColumns={'deprel':('1-компл', '2-компл','дат-субъект')}) updated = 0 #Check out whether there is a 'predik' or infinitival 1-kompl depending on the verbal head for key, matchlist in thisSearch.matches.items(): for match in matchlist: match.matchedsentence.listDependents(match.matchedword.head) for codependent in match.matchedsentence.dependentlist: #If there is an infinitival codependent marked as predik or 1-kompl AND the nominal complement is in dative: if (codependent.deprel in ('предик','1-компл') and codependent.feat in featset.inf) and (match.matchedword.feat in featset.NounDat or match.matchedword.feat in featset.PronDat): dbcon.query('UPDATE ru_conll SET contr_head = %(contrhead)s, contr_deprel = %(contrdep)s WHERE id = %(matchid)s',{'contrhead':codependent.tokenid,'contrdep':'semsubj','matchid':match.matchedword.dbid}) updated += 1 log('Updated {} items in the db'.format(updated))
def nsubj(dbcon=False): """nsubj VAATII huomiota! """ LogNewDeprel('Create the category of nsubj in the TDT data') dbcon.query( 'UPDATE fi_conll SET contr_deprel = %(contrdep)s WHERE deprel IN %(deprel)s AND contr_deprel = %(oldcontrdep)s', { 'contrdep': 'nsubj', 'oldcontrdep': 'gdep', 'deprel': ('csubj', 'csubj-cop') }) log('Succesfully renamed csubj-cop and csubj to nsubj')
def fixChains(dbcon=False): """Lopuksi saattaa olla tarve korjata joitakin vääriä contr_deprel-merkintöjä, esim. apuverbiketjujen tuloksena syntyneita aux-tapauksia """ LogNewDeprel('Fix auxes to infcomp') dbcon.query( 'UPDATE fi_conll SET contr_deprel = %(contrdep)s WHERE contr_deprel IN %(oldcontrdep)s', { 'contrdep': 'infcomp', 'oldcontrdep': ('aux', 'auxpass', 'neg') }) log('to be updated: {} database rows.'.format(dbcon.cur.rowcount))
def conj(dbcon=False): """Rinnasteisten elementtien osalta SN-jäsennys käyttää kolmea eri luokkaa: sotš-sojuzn, sent-sotš ja sotšin. Kontrastiivisessa analyysissa lähdetään TDT-jäsennyksen mukaisesta perusajatuksesta siinä, että rinnastetun lauseen pääsana tai myöhempi rinnastettu elementti katsotaan ensimmäisen rinnastettavan elementin (eikä rinnastuskonjunktion) dependentiksi. - Rinnastuskonjunktiot merkitään TDT:n tapaan cc-kategorialla, - kaikki rinnastettavat elementit analysoidaan conj-kategoriaan kuuluviksi. On vielä huomattava, että SN-jäsennyksessä sotšin-tyyppiä käytetään rinnastuskonjunktioiden lisäksi luettelomuotoisissa rinnastustapauksissa myös luettelon osien kategorisointiin – TDT-analyysi luokittelee vastaavat tilanteet osaksi conj-kategoriaan, osaksi erilliseen parataxis-kategoriaansa. Tässä suhteessa kontrastiivista analyysia yksinkertaistetaan niin, että TDT:n parataxis-elementit samoin kuin ne venäjän sotšin-tapaukset, jotka eivät ole rinnastuskonjunktioita, luokitellaan conj-kategoriaan. MIKÄ on rinnastuskonjunktion pääsana? сент-соч pitää joskus erikseen, koska aina ei ole sotshin """ LogNewDeprel('Create the conj and cc categories in SN') thisSearch = makeSearch(database=dbcon.dbname, dbtable = 'ru_conll', ConditionColumns={'deprel':('сочин','сент-соч','соч-союзн')}) updated = 0 for key, matchlist in thisSearch.matches.items(): for match in matchlist: if match.matchedword.pos == 'C': #Update the conjunction dbcon.query('UPDATE ru_conll SET contr_deprel = %(contrdep)s WHERE id = %(matchid)s',{'contrdep':'cc','matchid':match.matchedword.dbid}) else: if match.matchedword.head == 0 or match.matchedword.head not in match.matchedsentence.words.keys(): pass else: mhead = match.matchedsentence.words[match.matchedword.head] while mhead.pos == 'C' and mhead.head in match.matchedsentence.words.keys(): mhead = match.matchedsentence.words[mhead.head] #Update the actual coordinated element dbcon.query('UPDATE ru_conll SET contr_head = %(contrhead)s, contr_deprel = %(contrdep)s WHERE id = %(matchid)s',{'contrhead':mhead.tokenid,'contrdep':'conj','matchid':match.matchedword.dbid}) updated += 1 log('Updated {} items in the db'.format(updated))
def getRelDict(thisSearch): """Fetch the relative clauses to a dict""" #Get the actual relative clauses and save information about them in a list of dicts log('Processing all the relative clauses to a list') relclauses = list() for key, matches in thisSearch.matches.items(): for match in matches: delthese = list() for tokenid, word in match.matchedsentence.words.items(): #Assume the relative word is the first word of the clause and remove all the preceding words if word.tokenid < match.matchedword.tokenid: delthese.append(word.tokenid) for delthis in delthese: del (match.matchedsentence.words[delthis]) match.matchedword.token = fakenonrel(match.matchedword.token) match.BuildSentencePrintString() relclauses.append({'clause': '', 'dbid': 0}) relclauses[-1]["clause"] = match.matchedsentence.cleanprintstring relclauses[-1]["dbid"] = match.matchedword.dbid #save as pickle pickle.dump(relclauses, open('relclauses.p', "wb")) return relclauses
def UpdateContrRel(dbcon, originalClauses, newdeprels): """Update the new deprels to the database according to the reparsed file""" contr_deprels = list() #Pair the relativizers' dbids and the reparsed deprels: for idx, clause in enumerate(originalClauses): contr_deprels.append({ 'baseval': clause['dbid'], 'changedval': newdeprels[idx] }) updates = [{ 'updatedcolumn': 'contr_deprel', 'basecolumn': 'id', 'valuelist': contr_deprels }] #Insert to database: log('Updating the database, this might take long.. ') dbcon.BatchUpdate(table='fi_conll', updates=updates) log('Update done. This will potentially effect {} database rows.'.format( dbcon.cur.rowcount))
def nsubj(dbcon=False): """Nimetään uudelleen predik-kategoria nsubj:ksi""" LogNewDeprel('Create the category of nsubj in the SN data') dbcon.query('UPDATE ru_conll SET contr_deprel = %(contrdep)s WHERE deprel = %(deprel)s',{'contrdep':'nsubj','deprel':'предик'}) log('Succesfully renamed predik to nsubj')
def rel(dbcon=False): """ HUOM! joten-sana kohdeltava erikseen """ LogNewDeprel('REANALYZE the rel category in TDT') log('1. Search for all the relative pronouns analyzed as "rel"'.format( dbcon.dbname)) thisSearch = makeSearch(database=dbcon.dbname, dbtable='fi_conll', ConditionColumns={ 'deprel': ('rel', ), 'lemma': ('joka', 'mikä') }) log('2. Extract the relative clauses') relclauses = rel_tdt.getRelDict(thisSearch) log('3. Print the relative clauses to file') rel_tdt.PrintRelClausesToFile(relclauses) #Reparse, if not yet done reparsedfile = "{}_reparsedrelativizers.conll".format(dbcon.dbname) if not os.path.isfile(reparsedfile): #if no previous reprse found: log('Now re-parse. This should take at least 10 mins ') os.system( "cat parserinput.txt | /home/juho/Dropbox/VK/skriptit/python/finnish_dep_parser/Finnish-dep-parser/parser_wrapper.sh > {}" .format(reparsedfile)) log('4. Read the new deprels from the reparsed file') newdeprels = rel_tdt.ReadConllInput(reparsedfile) log('5. Insert the new deprels to the database') rel_tdt.UpdateContrRel(dbcon, relclauses, newdeprels)
def prdctv(dbcon=False): """Tämä tarkoittaa käytännössä sitä, että TDT-jäsennetyn aineiston nsubj-cop-tapaukset luokitellaan tavallisiksi nominisubjekteiksi (nsubj) ja sekä niiden että predikatiivina olevan sanan pääsanaksi vaihdetaan sana, joka alun perin on analysoitu kategorialla cop. Kopulan dependenssityypiksi siirretään se tyyppi, johon predikatiivi oli luokiteltu. Jää monia nsibj-cop-tapauksia, joiden lauseessa ei ole kopulaa Haverinen 32: - The basic alternatives for predicatives are nominals (nouns, adjectives, pro- nouns and numerals). - Words of these parts-of-speech are required to be in nomi- native, partitive or genitive to be accepted as predicatives. ongelma: apuverbien ketjut. """ updater = deptypetools.DepTypeUpdater(dbcon, 'fi_conll', 'Create the prdctv category in tdt') updater.search = makeSearch(database=dbcon.dbname, dbtable='fi_conll', ConditionColumns={'deprel': ('nsubj-cop', )}) log('Change nsubj-cop to subj') #Change the deprel of nsubj-cop to always be nsubj updater.simpleupdate(deprel='nsubj') #Update the contrastive layer for nsubj-cop and cop nocopula = list() contr_heads = list() contr_deprels = list() for key, matchlist in updater.search.matches.items(): for match in matchlist: try: prdctv = match.matchedsentence.words[match.matchedword.head] match.matchedword.tokenid nsubjcop = match.matchedword match.matchedsentence.listDependents(match.matchedword.head) cop = False for dep in match.matchedsentence.dependentlist: if dep.deprel == 'cop': cop = dep if not cop: #If the nsubj-cop's head has no cop as its dependent, look in the entire sentence for key, dep in match.matchedsentence.words.items(): if dep.deprel == 'cop': cop = dep if cop: #Set the new heads: contr_heads.append({ 'baseval': nsubjcop.dbid, 'changedval': cop.tokenid }) contr_heads.append({ 'baseval': prdctv.dbid, 'changedval': cop.tokenid }) contr_heads.append({ 'baseval': cop.dbid, 'changedval': prdctv.head }) #Set the new deprels: contr_deprels.append({ 'baseval': prdctv.dbid, 'changedval': 'prdctv' }) contr_deprels.append({ 'baseval': cop.dbid, 'changedval': prdctv.deprel }) else: #If no copula at all nocopula.append(str(match.matchedsentence.sentence_id)) except KeyError: log('KeyError') updates = [{ 'updatedcolumn': 'contr_deprel', 'basecolumn': 'id', 'valuelist': contr_deprels }, { 'updatedcolumn': 'contr_head', 'basecolumn': 'id', 'valuelist': contr_heads }] dbcon.BatchUpdate(table='fi_conll', updates=updates) log('This might potentially effect {} database rows.'.format( dbcon.cur.rowcount)) log('Sentences {} contain no copula'.format(','.join(nocopula)))