CLT355: Kuudes luentokerta

Sananmuotojen frekvenssejä ym. ja table -funktio

Luetaan edellisellä kerralla käytetty Juhani Ahon "Helsinkiin" -novellista tehty havaintomatriisin muotoinen tiedosto (kun se on omalle koneelle ladattuna hakemistoon, joka on asetettu oletushakemistoksi esim. RGuin File-valikosta käsin):

> aho = read.table("aho-helsinkiin-lenwd.txt", header=T)
Muistamme, että tässä havaintomatriisissa oli kaksi muuttujaa, LEN ja WORD. Taulukoimme ensin sananmuodot muuttujaan wfq eli tuotamme rakenteen, jossa kullekin erilaiselle sananmuodolle on oma luokitteluarvonsa ja sille on laskettu, kuinka monta esiintymää teoksessa oli.
> wfq = table(aho$WORD)

Tuohon muuttujaan wfq ei kannata koskea sellaisenaan, koska siinä on paljon alkioita. Otamme siitä viipaleen, emme alusta, koska siinä on numeroita, vaan vähän matkan päästä pieni siivu:

> wfq[41:51]

      aika      aikaa  aikaakaan     aikaan aikamiehen     aikana    aikansa
         6         16          1          7          2          2          1
  aikeensa   aikeissa     aikoen   aikoihin 
         1          1          1          1 
Tässä siis varsinaista tietoa ovat lukuarvot ja niiden yläpuolelle on tulostettu se luokittekuarvo, jota frekvenssi vastaa, siis sananmuotoa "aika" löytyi 6 kappaletta ja sananmuotoa "aikaa" vastaavasti 16 kappaletta. R laittaa laskemansa taulukon luokitteluarvojen mukaiseen nousevaan järjestykseen.

Kun tuo koko lista on niin pitkä, ettemme sitä ehkä halua katsella, voimme valita siitä pienempiä osia. Voimme käyttää mielenkiintoisempiakin valintaperusteita kuin sijaintipaikkaa. Valitsemme seuraavassa ne alkiot, joissa frekvenssi on yli 100:

> wfq[wfq > 100]

antti    ei  että   hän hänen    ja  joka  kuin   kun mutta  niin
  209   184   145   482   124   980   116   141   129   180   146
  oli    on    se 
  479   133   153
Menettely on R:ssä yleinen. Hakasulkuihin voidaan laittaa paitsi yksittäisiä alkioiden indeksejä tai indeksien jonoja (kuten 41:51, joka vastaa sarjaa 41, 42, ..., 51) myös ehtoja. Ehto wfq>100 tarkoittaa yhtä pitkää vektoria kuin wfq jossa on totuusarvo kertomassa kustakin alkiosta, onko sen frekvenssi isompi kuin 100. Kun hakasuluissa on tällainen totuusarvovektori, hakasulkulauseke tekee uuden taulukon tai vektorin, jossa on jäljellä vain ne alkiot, joita vastaava totuusarvovektorin alkio on tosi. Teknisesti siis näin. Intuitiivisesti ehto on ehkä melkein itsensä selittävä.

Saattaisimme haluta nuo sananmuotojen frekvenssit frekvenssien laskevassa järjestyksessä. Taulukon voi lajitella sort -funktiolla. Taulukon alkioiden arvoina pidetään frekvenssiä, sananmuoto on tässä tapauksessa vain metatietoa eli lajittelu kohdistuu frekvenssiin. Taaskin tulostamme itsellemme vain osan alusta:

> swfq = sort(wfq, decreasing=T)
> swfq[1:8]

   ja   hän   oli antti    ei mutta    se  niin 
  980   482   479   209   184   180   153   146 
Jos haluamme, voimme rajoittaa tulostusta myös frekvenssin perusteella ja tulostaa vain yli 50 frekfenssillä olevat alkiot, jotka siis nyt ovat frekvenssinsä mukaisessa laskevassa järjestyksessä:
> swfq[swfq>50]

    ja    hän    oli  antti     ei  mutta     se   niin   että   kuin     on 
   980    482    479    209    184    180    153    146    145    141    133 
   kun  hänen   joka     he olivat    sen  ollut  häntä    nyt     jo  olisi 
   129    124    116     99     92     88     87     77     77     75     69 
  sitä   vain  vielä   minä     ne kaikki   sinä 
    69     66     66     63     58     51     51 
Usein ollaan kiinnostuneita siitä, miten kielessä tai teoksessa on yleisiä ja harvinaisia sanoja tai sananmuotoja. Silloin emme välitä siitä, mitä sanat ovat, vaan ainoastaan siitä, miten yleisiä sananmuotoja, keskmääräisen tavallisia ja harvinaisia saneet tekstissä ovat. Tulkitsemme nyt taulukkomme pelkkänä numerosarjana, jossa frekvenssit ovat laskevassa järjestyksessä:
> v = as.vector(swfq)
> plot(v[1:50])

> length(v)
[1] 7313
> table(v)

Kaksikieliset rinnakkaiskorpukset

Joistakin teksteistä on alkuperäisen lisäksi olemassa käännös. Kurssin tarkoituksia varten etsitään Project Gutenbergin arkistosta tekijänoikeuksista vapaita tekstejä, joista on sekä englannin- että suomenkielinen versio saatavana. Muistamme, että tekijänoikeus raukeaa 70 vuotta tekijän tai kääntäjän kuolemasta eli käännökseen on tekijän lisäksi kääntäjällä oikeudet. Sherlock Holmes -kirjat ovat kyllin vanhoja. Pienellä etsiskelyllä niistä löytyy ainakin yksi, joka on suomennettuna tuossa arkistossa, nimittäin Baskervillen koira, jota käytämme jatkossa.

Kaksikielisistä rinnakkaiskorpuksista löytyy monia tilastollisia kysymyksiä, esimerkiksi:

  • Miten käännetyn tekstin pituus suhtautuu alkutekstiin? Tätä voi tarkastella kokonaisina teoksina, mutta myös kappaleittain ja virkkeittäin. Tällaisia laskelmia voidaan tehdä erityisesti, jos tekstit on kohdistettu toisiinsa (engl. aligned), mikä tarkittaa sitä, että käännösten toisiaan vastaavat yksiköt, kuten kappaleet tai virkkeet on yhdistettävissä toisiinsa. Käännöksessähän voi olla eri määrä virkkeitä tai kappaleita kuin alkutekstissä, jolloin jommallakummalla puolella joudutaan joko yhdistämään tai jakamaan näitä yksiköitä.
  • Miten rinnakkaiskorpukset voitaisiin kohdistaa toisiinsa? Yksinkertaisetkin, kappaleiden tai virkkeiden pituuksiin perustuvat menetelmät ovat osoittautuneet tehokkaiksi. Ajatuksena on se, että pienillä korjauksilla siellä täällä saadaan vastinyksiköiden pituuksien suhteet pysymään lähellä vakiosuhdetta.

Kappaleiden tunnistaminen on usein helppoa, sillä kappaleiden rajat on merkattu jollakin selvällä tavalla. Gutenbergin aineistoissa kappaleiden välissä on tyhjä rivi. Tyhjä rivi on myös otsikoiden edellä ja jäljessä, mutta otsikoita kannattaa käsitellä kappaleiden veroisina muutenkin.

Virkkeiden rajalla on ns. iso välimerkki esim. piste, huutomerkki, kysymysmerkki. Kaikki pisteet eivät kuitenkaan osoita virkkeen loppumista. Hyväksi havaittuja virkkeen loppumisen kriteerejä:

  • Pieni kirjain, piste, välilyönti, iso kirjain. Tällaisissa paikoissa on yleensä virkeraja. Pisteen edellä tai heti sen perässä saattaa olla lainausmerkki tai loppusulku. Vastaavasti ison kirjaimen edessä saattaa olla lainausmerkki tai alkusulku. Tämän säännön avulla vältetään tekemästä rajaa etunimen alkukirjaimen ja sitä seuraavan sukunimen väliin.
  • Sääntöön tarvitaan vain pieni lisä niistä harvoista lyhenteistä, jotka eivät milloinkaan lopeta virkettä. Näitä ovat erilaiset tittelit ja "esim.", "mm." ym. Muutoin tulisi väärä virkeraja seuraavanlaisissa tapauksissa: "kansantulo esim. Suomessa on".

Tehtävä 4

Tämän sivun liitteenä on tiedostot baskeren1par.txt ja baskerfi1par.txt eli ensimmäiset luvut englannin- ja suomenkielisistä versioista kappale per rivi -muodossa sekä baskeren1len.txt ja baskerfi1len.txt eli kappaleiden pituudet merkkeinä laskettuna suoraan edellisistä tiedostoista.

Tutki päällisin puolin pituuksien tiedostoja ja päättele, vastaavatko englanninkieliset kappaleet suomenkielisiä kappaleita, vai vastaako jossakin kohdassa toisen kielen kappale toisessa kielessä kahta kappaletta (tai puuttuuko toisesta kappaleita, joita toisessa on)? Montako kappaletta kummassakin tekstissä on?

Vastaavuuden pysymistä tahdissa voi tarkastella, kun pituuksien sarjaa käsitellään aikasarjana. Pituuksista saa ns. aikasarjan funktiolla
tsen=ts(en$LEN)
Aikasarjan voisi piirtää funktiolla plot(tsen), mutta parempaa on, jos saamme molemmat aikasarjat piirretyksi samaan kuvaan. Tämä onnistuu nimenomaan aikasarjoja varten olevalla komennolla
ts.plot(tsen, tsfi, gpars=list(lty=c(1,2)))
Tutki näin syntyviä yhtenäisellä viivalla piirrettyä englannin- ja katkoviivalla piirrettyä suomenkielistä sarjaa. Niiden muodot ovat samankaltaiset, ne ovat alussa samassa tahdissa, mutta niiden tahdit erkaantuvat myöhemmin.

> en = read.table("baskeren1len.txt", header=T)
> fi = read.table("baskerfi1len.txt", header=T)
> tsen = ts(en)
> tsfi = ts(fi)
> ts.plot(tsen, tsfi, gpars=list(lty=c(1,2)))

Mitkä kappaleet yhdistämällä tekstit saa vastaamaan kappaleittain toisiaan? Anna vastaukseksi kopio niistä peräkkäisistä kappaleista, jotka pitäisi yhdistää. Tarkista tiedostoista baskeren1par.txt ja baskerfi1par.txt, tee niihin tarvittavat korjaukset samoin kuin pituustiedostoihin baskeren1len.txt ja baskerfi1len.txt. Laita korjattujen tiedostojen nimen perään ennen pistettä kirjain c. Tarkista korjatuilla tiedostoilla, että nyt kappaleiden pituuksien aikasarjat pysyvät toistensa tahdissa.

Tehtävä 5

Edellä mainitusta Gutenbergin arkistosta voi etsiä tekijänoikeudesta vapautuneita teoksia eri kriteereillä. Kyseisen edellisessä tehtävässä esiintyneen Sherlock Holmes -kirjan ja sen käännökset löydät helpoiten laittamalla lokeroon Title Word(s) hakuavaimeksi baskerville. Lataa itsellesi eli omalle koneellesi arkistosta sekä englanninkielinen versio "The Hound of the Baskervilles" että suomennos "Baskervillen koira". Hakeminen sujuu napsauttamalla teoksen nimeä ja sieltä aukeavalta sivulta edetään välilehdelle "Download". Lataa "Plain Text UTF-8" -muotoinen versio.

Gutenbergin teksteissä on alussa ja lopussa tekstiin liittyvää lisätietoa, joka ei siis kuulu alkuperäisiin teksteihin. Muodosta kummastakin tiedostosta typistetty versio, josta on poistettu nämä alkuun ja loppuun lisätyt metatiedot ja lisenssitekstit. Anna näille versioille nimet baskeren.txt (suomenkielinen) ja baskerfi.txt (englanninkielinen).

Ota kummastakin tiedostosta varsinaisen tekstin toinen luku (pois lukien luvun otsikko). Yhdistä samassa kappaleessa olevat virkkeet yhdeksi pitkäksi riviksi, jolla siis ovat kappaleen kaikki virkkeet peräkkäin. (Huolehdi siitä, että pisteen jälkeen on yksi välilyönti.) Tämän voit tehdä joko käsin editoimalla tai sopivalla Python-kielisellä pienellä skriptillä. Käytä mallina tämän sivun liitetiedostoja (baskeren1par.txt ja baskerfi1par.txt). Talleta nämä tiedostot nimillä baskeren2par.txt ja baskerfi2par.txt. Laske kummastakin kappaleiden pituuden merkkeinä ja tee niistä havaintomatriisin muotoisia (baskeren2len.txt ja baskerfi2len.txt) esim. seuraavalla Python-skriptillä:

import sys
print("LEN")
for line in sys.stdin:
        ll = len(line) - 1
        if ll > 0: print(ll,)
Sisällytä vastaukseen kummankin kappaleittaisen tiedoston kolme ensimmäistä kappaletta tiedostoista baskeren2par.txt ja baskerfi2par.txt sekä kymmenen ensimmäistä riviä tiedostoista baskeren2len.txt ja baskerfi2len.txt. Tuliko kumpaankin versioon yhtä monta kappaletta? Toista edellisen tehtävän aikasarjavertailu tälle toiselle luvulle. Mitä voit päätellä rinnakkaisista aikasarjoista? Mitä kappaleita pitäisi ehkä yhdistää, jotta luvun suomen- ja englanninkieliset versiot voitaisiin menestyksellisesti kohdistaa toisiinsa. Perustele.

-- KimmoKoskenniemi - 2010-11-18



 
Topic attachments
I Attachment Action Size Date Who Comment
Texttxt baskeren1len.txt manage 0.3 K 2010-11-21 - 17:51 KimmoKoskenniemi Engl. Baskerville, 1. luvun kappaleiden pituudet
Texttxt baskeren1par.txt manage 12.3 K 2010-11-21 - 17:49 KimmoKoskenniemi Engl. Baskerville, 1 luku kappale/rivi
Texttxt baskerfi1len.txt manage 0.3 K 2010-11-21 - 17:52 KimmoKoskenniemi Suom. Baskerville, 1. luvun kappaleiden pituudet
Texttxt baskerfi1par.txt manage 14.0 K 2010-11-21 - 17:50 KimmoKoskenniemi Suom. Baskerville, 1. luku, kappale/rivi
Topic revision: r6 - 2010-12-02 - KimmoKoskenniemi
 
This site is powered by the TWiki collaboration platform Powered by PerlCopyright © 2008-2018 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback