Asialista CLT131: Tekstityökalut 2010, kuudes luento Tommi A Pirinen tommi.pirinen@helsinki.fi Helsingin yliopisto Kieliteknologian oppiaine, Nykykielten laitos 2010-12-16 Kurssipalaute Kerätään kurssin puolivälistä kurssipalaute elomakkeella, tästä saa yhden tehtäväpisteen seuraaviin harjoituksiin. Palaute lähetettävä vuodenvaihteeseen mennessä, linkki saatavilla luennoilta tai sähköpostitse, koska elomake-osoitteita ei saa jakaa verkossa. edellisten laskuharjoitusten malliratkaisut ja seuraavat laskuharjoitukset tulevat verkkoon ennen joulua kevät aloitetaan joululoman/tammikuun laskuharjoituksilla vasta 26.1. pe 28.1. kevään ensimmäisellä luennolla enimmäkseen kerrataan säännölliset lausekkeet, ja jos aikaa jää, aloitetaan skriptaus ja tiedostojenhallintaa (esim. make) tarkastelkaa kalenteria tammikuun alusta muutoksia varten
lähtöteksti sisältää jopa kolmea eri merkkaustapaa: XML, mediawiki, XML-entiteettikoodattu HTML: täysimittainen muunnos raakatekstiksi olisi työläs Viime viikon tehtävät type on bash-komento, eikä toimi csh:lla: which on tähän tarkoitukseen riittävä korvike kuitenkin csh:n muuttaminen bashiksi on suositeltavaa hipun grep-versiossa on värjäyksessä bugi, joka teki tavutustehtävän testaamisen vieläkin haasteellisemmaksi tavutustehtävän pisteet lasketaan lisäpisteiksi (=eivät sisälly 50 %:iin arvostelussa) omorfin CG-tulosteessa oli bugi: omorfi-analyse.sh cg,cg saa aikaan halutun tuloksen omorfi-analyse.sh ei ymmärrä joitain erikoismerkkejä: $@<>\/ jne. (joko poistettava tr:llä tai lisättävä takakenoviiva eteen sedillä) vaikeammista tehtävistä tulee sivuille malliratkaisuja skripteistä Asialista Tutkimusongelma: adverbit Wikipedia-aineistossa Tehtäväkuvaus Halutaan selvittää tiettyjen erilaisten adverbien samankaltaisuutta...kontekstien perusteella (myöhemmin) Lähtökohdat wikipedian tietokanta korpuksena haut kohdistetaan analyyseihin, jotka pitää taasen saada yhdistettyä pareittain Ongelmat Asialista
Aineisto: Wikipedia http://fi.wikipedia.org/ vapaa ilmainen yhteisötuotettu tietosanakirja; sisältänee nykykielenkäytön mukaista asiatekstiä laajalta alalta XML-merkkaus pitää siistiä ja poistaa MediaWiki-merkkaus pitää siistiä ja poistaa XML-koodattu HTML-merkkaus pitää (muuntaa ja) siistiä ja poistaa teksti on noudettavissa yhtenä suurehkona tiedostona: http://download.wikipedia.org/ fiwiki/20101103/ (korvaa 20101103 sanalla latest noudettaessa tuoreinta) katsotaan: Amsterdam-artikkeli selaimessa http://fi.wikipedia.org/wiki/amsterdam/ MediaWiki-muoto selaimessa http://fi.wikipedia.org/w/index.php? title=amsterdam&action=edit Awk-artikkeli itse ladatusta tiedosta: head -n 484 Wikipedian siistittävät Lähtökohta: XML-merkkausta <page> <title>amsterdam</title> <id>1</id> <revision> MediaWiki-merkkausta {{Kaupunki2 virallinen_nimi = Amsterdam muu_nimi =...}} Amsterdam on [[Alankomaat Alankomaiden]] [[pääkaupunki]]. == Historia == XML-koodattua HTML-koodia...siellä asui 743 905 asukast......jono on kasvava jos kaikilla XML-merkkauksesta vielä varsinaisesti käsitellään vasta seuraavilla kursseilla: CLT132 verkkosivujen suunnitelu ja CLT236 XML nyt riittää tietää edelleen, että merkkaus sisältää kulmasulkein rajattuja merkintöjä tämän lisäksi, et-merkillä & ja puolipisteellä ; rajataan erikoismerkkejä: < tämä on tärkeää, koska wiki-merkkauksessa XML:ään on sisällytetty toista XML:ää (tässä tapauksessa suunnilleen HTML:ää) kaksinkertaisesti koodattuna: <ulompi><sisempi>sisin</sisempi></ul : satunnaisluvut bashissa suuren aineiston kanssa on yleensä järkevää kehitysvaiheessa käyttää vain osaa aineistosta käyttämällä satunnaisesti arvottuja osia saadaan vaihtelevaa aineistoa bash antaa arvottuja lukuja muuttujasta $RANDOM [0, 32767] koska tämä on usein väärää suuruusluokkaa, esim. bashin matematiikkatilaan pääsee erikoissulkeilla $(( )), jossa skaalaus voidaan suorittaa kertolaskulla *: : echo $RANDOM katsotaan satunnaislukuja echo $(($RANDOM *100)) satakertainen satunnaisluku head -n $(($RANDOM *100)) tail -n $RANDOM eräs satunnaispoiminta tiedostosta
: awkin monimutkaisempi tulostus tällä kertaa saneparien käsittelyn vielä helpottamiseksi hyödynnetään muotoiltua tulostamista; näin voidaan käsitellä analyysirivejä ja tulostaa sanepareista rivien osia muotoillun tulosteen komento on printf(muotoilu, muuttujat) muotoilu on merkkijono, jossa on aukkokohtia, joihin muuttujat järjestyksessä sijoitetaan aukkokohdan merkitsin on % ja kirjain: %s tulostaa muuttujan merkkijonona %d tulostaa muuttujan kokonaislukuna %f tulostaa muuttujan desimaalilukuna muut kuin aukkokohdat tulostetaan sellaisenaan; paitsi tutut takakenoviivailmaukset: \t tabulaattorille ja \n rivinvaihdolle printf ei tulosta rivinvaihtoakaan automaattisesti; rivit pitää lopettaa \n awk-esimerkit testataan: awk {printf("numero %d\n", 13)} = awk {print "numero", 13} awk {printf("%f\t%s\t%s\n", $1/100, $2, $3)} = awk {print $1/100, "\t", $2, "\t", $3} tämä printf toimii on myös C-ohjelmointikielessä (ja bashissa): ohjeita man-sivulta printf(3) osiosta Format of the Format string eteenpäin : awkin tarkempi poiminta halutaan poimia omorfin tulosteista vain jos analyysi tai sane täsmää hakuun; analyysithän esiintyvät riveinä muodossa: sane\tanalyysirivi awkin sanemuuttujat $n jäsentävät nämä että sane=1, analyysirivi=2 sanekohtainen täsmäys säännöllisillä lausekkeilla esitetään ehtokentässä, muodossa $n /säännöllinen lauseke/: awk $1 /sti$/ {print $1} tulosta kaikki sti-adverbit omorfin analyysilistasta awk $2 /CASE=PAR/ {print $1} tulosta kaikki partitiivit omorfin analyysilistasta huomattavaa myöhemmäksi: kaikki ehtolauseet, jotka toimivat awk-rivin alussa toimivat myös ohjelmalohkossa if-lausekkeen sisällä Asialista
Työsuunnitelma Alku hieman kuten viime kerrallakin: haetaan korpus (wget) puretaan tiedosto (bunzip2) tai käsitellään purkamista aina lennosta (bzcat) siistitään XML-merkkaus (sed) siistitääm MediaWiki-merkkaus (sed) muunnetaan XML-koodattu HTML ja siistitään XML:n tavoin (sed) poimitaan adverbit (awk) tehdään saneparilista, josta adverbien parit on poimittavissa (awk; keväällä) lasketaan adverbien pareista luokittain yleisimmät (sort, uniq, awk) XML-siistintä nyt MediaWikin XML ei poikkea europarlista merkittävästi, voimme käyttää viime kerralla keksittyä poistetaan vain kaikki kulmasuljeosiot: tekstinpätkät jotka alkavat <:lla ja päättyvät >:seen ilman muita >:ta välissä: bzcat fiwiki *bz2 sed -r -e s/<[ˆ>]*>//g tällä kertaa on tärkeää poistaa vain kulmasuljeilmaukset, koska niiden ympärillä onkin mediawiki-merkkauksessa jo kaikenlaista tärkeää; esim: <title>sivun otsikko</title> mutta: myös kaikkea roskaa: <username>xqbot</username>; tätä voidaan tarkemmin käsitellä myöhemmin (tai sen voi tehdä harjoitustyöksi) Korpuksen haku ja purkaminen Tätä ei tarvitse toistaa, koska korpus on iso (n. 280 Mt.) ja voidaan käyttää hipulla samaa: wget http: //download.wikimedia.org/fiwiki/latest/ fiwiki-latest-pages-articles.xml.bz2 bunzip2 fiwiki-latest-pages-articles.xml.bz2 joskus jos tila on vähissä tai muutoinkin, ei ole välttämätöntä purkaa tiedostoa erikseen; komento bzcat fiwiki-latest-pages-articles.xml.bz2 toimii samoin kuin cat fiwiki-latest-pages-articles.xml äskeisen bunzipin jälkeen Tällä saa asken purkamattoman version käytettäväkseen (jos oikeudet ovat kunnossa): ln -s /fs/metawrk/tpirinen/clt131/fiwiki-latest-pages- $HOME/ MediaWiki-siistintä karkeahkoon siistintään riittää kun poistetaan kaikki monimutkaiset merkkaukset sisältöineen: grep -invert-match ˆ\[{ }] aaltosulkein erotetut koodit ja pystyviivalla alkavat taulukot hakasuljelinkeistä halutaan vain tekstiosa, jos sellainen on erikseen: sed -r -e s/\[\[[ˆ] ]* ([ˆ]]*)\]\]/\1/g Yhtäsuuruusmerkkisarjoilla merkityt otsikot ja lainausmerkeillä merkityt korostukset ja loput kulmuasulkeet, aaltosulkeet jne. poistetaan sellaisenaan: sed -r -e s/[]={ } []+/ /g (huom. kaksoislainausmerkit koska poistettavissa on yksinkertainen) oikeastaan tässä vaiheessa mediawikimerkkauksesta jää myös paljon roskaa: monet erikoislinkit kuten kuvat ja toisenkielisiin wikipedioihiin osoittavat hakasuljeilmaukset jäävät vielä suodattumatta:
XML-merkattu HTML MediaWiki-merkkauksessa Wikipediaan voi kirjoittaa myös HTML-merkkausta, silloin ne piilotetaan ns. XML:n merkkiviittausten taakse näin: & &, < < ja > > ratkaisu: korjataan takaisin HTML:ksi, jotta voidaan siistiä XML:n tavoin: sed -r -e s/\&/\&/g -e s/\</</g -e s/\>/>/g nyt, tiedämme edelleen miten XML, taas, karkeasti ottaen siistitään: sed -r -e s/<[ˆ>] *>//g Omorfianalysointi ja adverbien poiminta otetaan satunnainen pätkä jonka ehtii analysoida luennolla: head -n $(($RANDOM * 100)) tail -n $RANDOM omorfi-analyse ei vielä hallitse joitain erikoismerkkejä, joten piilotetaan ne: tr -d $@ˆ/<>\\ viime harjoituksista opittiin, että omor-parametri helpottaa hakujen tekoa nyt voimme hakea adverbit POS=ADVERB-ilmauksella ja merkata tulevaa käsittelyä varten: awk $2 /POS=ADVERB/ printf("%s/adv\n", $1) Asialista Syyslukukaudella opittua: shelliskriptit (havaintoja voi täydentää kitwikiin :-) shell-skriptien teko: ensimmäiselle riville #!/bin/sh (tai bash) järjestetty kokoelma komentoja: voidaan poimia history-komennosta testailun jälkeen komento per rivi; komentoja voi ketjuttaa putkella (edellisen syöte seuraavan tulosteeksi) tallennetaan tiedostoon, jonka tarkenne on konvention mukaan.sh (tai.bash), ja joka on suoritettava (chmod +x) palautusarvot: onnistunut skripti palauttaa nollan, muutoin jotain muuta: exit 0 shelliskriptin suoritus ei pysähdy jos jokin komennoista epäonnistuu; pysäytys pitää tehdä itse (if! tämä-ei-toimi ; then exit 1 ; fi) toistoihin for x in a e i o u ; do echo $x ; done
Komennot apropos, man, info ohjeet awk haku säännöllisillä lausekkeilla ja ohjelmakoodilla, muokkaus ohjelmakoodilla cat tiedoston tai syötteen luku ja tulostus echo tulosta fgrep, egrep haut tekstillä, säännöllisillä lausekkeilla head, tail haut rivinumeroilla history,! tehdyt komennot locale kieliasetukset module hipun oma ympäristösäätö omorfi-interactive.sh, omorfi-analyse.sh suomen morfologinen analyysi Komennot recode, iconv, dos2unix, fromdos merkistösäädöt sed korvaukset ja muokkaukset säännöllisillä lausekkeilla sort, uniq rivien järjestely, toistojen poisto ja frekvenssilaskut test testaa tiedostoja, muuttujia tai palautusarvoja esim. if-lausekkeessa tr merkkien korvaus vim, emacs, nano tekstinmuokkaimet wget verkkonoudot Opitut käytännön asiat Yksinkertaiset haut fgrepillä frekvenssilista sortilla ja uniqilla tekstin saneistus tr:llä, saneiden ja tekstien jäsennys omorfilla tekstin osien poiminta headilla ja taililla (alku- ja loppulisenssien siistintä) kollokaattien haku egrepillä XML:n siistintä sedillä saneparien listaus awkin avulla MediaWikin karkea siistiminen sedillä, grepillä morfologisten piirteiden poiminta awkilla Säännölliset lausekkeet merkkijoukot hakasulkeissa []: luetellut merkit muodostavat joukon sinänsä: [aeiouyäö] vokaalit nimetyt joukot merkitään kaksoispistehakasulkein: [[:alpha:]] joukon vastakohta merkitään hatulla alkavan hakasulkeen perässä: [ˆaeiouyäö] ei-vokaalit merkin tai joukon jäljessä voi esittää kertoimen: * [0, ), + [1, ),? [0, 1], {n,k} [n, k] {n} n, {,k} [0, k], {n,} [n, ) muutamia erikoismerkkejä tai rajakohtia voi esittää takakenoviivalla \: n rivinvaihto, t sarkain, w sanamerkki, W ei-sanamerkki, < sanan vasen raja, > sanan oikea raja rivin tms. alkua merkitään hatulla, loppua dollarilla
AWK-ohjelmointi säännölliset lausekkeet hakuehtoina matemaattiset hakuehdot muuttujat matemaattiset laskut saneisiin viittaaminen $n print, printf tulostus for toistorakenne