Blogin kymmenvuotishuolto

Loma-ajan rauhan ollessa syvimmillään reippaat skriptilapsoset jostain päin maailmaa tekivät minulle palveluksen ja saivat blogiani pyörittäneen Wordpress-julkaisutyökalun pahasti solmuun. Päivittämättä jäänyt lisäosa teki asennuksesta haavoittuvan, vaikka Wordpress itsessään olikin kaikin tavoin kunnossa ja päivitetty. Jälkiä siivotessani tulin tulokseen, että nyt voisin vastaisen varalta palata ajassa taaksepäin, hylätä julkaisujärjestelmät ja pystyttää sivustoni toimimaan ilman palvelinpuolella ajettavaa koodia.

Muistin lukeneeni pari vuotta sitten Hiking in Finland -blogista Octopress-julkaisujärjestelmästä, haeskelin postauksen esille ja ryhdyin perehtymään aiheeseen. Muutaman mutkan kautta päädyin lueskelemaan Octopressin kaltaisten julkaisutyökalujen vertailua. Toisin kuin julkaisujärjestelmät yleensä, nämä työkalut eivät vaadi palvelimelta tietokantaa, PHP:n tai minkään muunkaan ohjelmointikielen tukea ja niiden laitteistovaatimukset ovat minimaaliset. Julkaisutyökalua käytetään omalta koneelta ja tuloksena syntyvät staattiset HTML-sivut siirretään palvelimelle julkaistavaksi.

Vertailtuani eri vaihtoehtoja suhteessa Octopressiin päädyin valitsemaan Docpad-julkaisutyökalun. Rubyn ja Railsin tuntevalle Octopress olisi ollut oiva valinta mutta nollapisteestä lähtiessäni Docpadin Javascriptiin (NodeJS) perustuva toteutus tuntui kiinnostavammalta perehtyä -- Javascriptiä kun ei nykyään juuri voi välttää, teki mitä tahansa kehitystyötä.

Sivuston uudelleenpystyttämisessä suurin vaiva oli vanhojen sisältöjen siirtämisessä. Onneksi skriptilapsoset eivät olleet tyhjentäneet tietokantaa, joten sain ladattua menneiden vuosien kirjoitukset talteen wp2octopress-skriptillä. Skriptin tuottamaa tulosta joutui paikoitellen muokkaamaan aika lailla, mutta suurin osa kirjoituksista oli suoraan siirrettävissä. Hyökkäyksen seurauksena Wordpressin tiedostonsiirtotoiminnallisuuden avulla siirretyt kuvat olivat tipotiessään, mutta ne sai onneksi ongittua talteen Internet Archiven Wayback Machinen avulla. Kommentit saivat uuden kodin Disqus-kommentointipalvelusta ja siirto sujui täysin Disqusin omien ohjeiden mukaisesti.

Alkuunpääsyä helpottaakseni en ryhtynyt pystyttämään Docpadia alusta alkaen itse, vaan käytin pohjana Erv Walterin Githubissa julkaisemaa blogikäyttöön viritettyä kokoonpanoa. Jahka kesä kääntyy syksyä kohti, lie systemaattisemman NodeJS-tutkiskelun aika.

Suomen kansallisgallerian kuva

Valtion taidemuseo, vuoden 2014 alusta alkaen Kansallisgalleria, julkaisi lokakuun alussa kokoelmiensa metatiedot avoimena datana. Sen lisäksi, että CC0-lisensoitua kokoelmadataa voi käsitellä erittäin hyvin dokumentoidun rajapinnan kautta, metatiedot voi ladata pakettina datan paikallista käsittelyä varten. Nyt joulun jouteliaina välipäivinä latailin datapaketin koneelleni ja päätin katsoa, miltä data näyttää BaseX XML-tietokantaohjelman kautta tarkasteltuna.

Kuten kirjastoaineistoja, myös taideteoksia kuvaillaan kontrolloitujen asianasastojen avulla -- onpa tämä oma tutkimusalansakin, ikonografia. Pintapuolisen datasetin läpikäynnin perusteella näytti, ettei lähellekkään kaikkia kokoelmien teoksia ole kuvailtu asiasanoin. Kuvailtuja teoksia on datasetissä kuitenkin niin paljon, että kokoelmista voisi saada luotua suht. paikkansapitävän yleiskuvan visualisoimalla käytetyt asiasanat verkostona, kuten olen tehnyt aikaisemmin kirjastoaineistojen tapauksessa.

Mielenkiintoisen eron kirjastoaineistojen kuvailutietoihin tekee taideteosten kuvailussa käytetty Iconclass-luokitusjärjestelmä. Iconclassin asiananat muodostuvat kirjain- ja numerosarjoista sekä selväkielisestä määritteestä, joka täsmentää numero-kirjainsarjan koodaamaa kuvailutermiä. Koska teokset kuvaillaan kieliriippumattomilla koodeilla, kuvailut ovat ymmärrettävissä vaikka kuvailutyötä tehnyt henkilö ja taideteosten metatietojen selailija eivät jakaisikaan yhteistä kieltä. Käytännössä siis, sen sijaan että jouluista aihetta kuvaava teos kuvailtaisiin suomalaisessa taidemuseossa asiasanalla 'joulu', kuvailuterminä voidaan käyttää Iconclass-koodia 11Q7612. Voidaan siis ajatella, että Iconclass-koodit ovat eräänlaisia linkkejä taideteoksista luokitusjärjestelmään -- ihanteellinen linkitetyn datan sovelluskohde siis.

Tähän ilmiselvään sovelluskohteeseen on myös tartuttu ja Iconclass on julkaistu koneluettavassa muodossa. Edellinen 11Q7612-kuvailutermi voidaan ilmaista linkkinä http://iconclass.org/11Q7612.json, jonka kautta selviää Iconclass-koodin selväkielinen merkitys useilla eri kielillä -- suomi mukaanlukien --sekä koodin sijainti kuvailutermien hierarkiassa. Koska koodien selväkielisiin ilmauksiin pääsee käsiksi helposti muodostettavien URL-osoitteiden kautta, on suhteellisen helppoa kirjoittaa XQuery-skripti, joka käy läpi kunkin taideteoksen kuvailutiedot, lataa verkosta kuvailukoodien selväkieliset ilmaukset ja muotoilee tiedot siten, että ne voidaan esittää verkostona Gephi-visualisointiohjelman avulla.

Iconclass-kuvaillut teokset Kiasman kokoelmissa.

(Lataa tarkkaresoluutioinen kuva.)

Omistaja lkm
Kiasma 1934
Sinebrychoffin taidemuseo 645
Ateneum 61
Teostyyppi lkm
maalaus 1120
grafiikka 464
valokuva 356
piirustus 202
veistos 154
mediataide 80
installaatio 73
esineteos 51
mustavalkoinen valokuva 31
muut ~ 90

Pääasiassa Kiasman kokoelmiin kuuluvien Iconclass-kuvailtujen teosten lisäksi päätin ottaa käsittelyyn selväkielisillä asiasanoilla kuvailtujen teosten metatiedot. Suurin osa näistä teoksista kuuluu Ateneumin kokoelmiin.

(Lataa tarkkaresoluutioinen kuva.)

Omistaja lkm
Ateneum 5310
Kiasma 1950
Sinebrychoffin taidemuseo 744
Teostyyppi lkm
maalaus 3709
piirustus 2699
grafiikka 1046
veistos 378
valokuva 28
reliefi 22
esineteos 19
miniatyyri 16
installaatio 12

Kansakunnan kaapin päällä

YLE Kirjasto -tietopalvelu on kaikessa hiljaisuudessa julkaissut artikkeliviitetietokantansa sisällön avoimena datana. Tietokanta sisältää yli 65500 viitettä pääasiassa kotimaisista aikakauslehdistä. Latasin Excel-muodossa olevan datasetin ja uteliaisuuttani vilkaisin, mitä tietoja artikkeleista on tallennettu tietokantaan. Huomasin, että viitetietokannan Asiasanat-kenttään on tallennettu runsaasti henkilöiden nimiä; oletettavasti niiden henkilöiden, joita artikkeli on käsitellyt. Tästä sain ajatuksen tutkailla tietokannan avulla, miltä suomalainen mediatodellisuus näyttää aikakauslehtiartikkeileiden viitteiden valossa. Keistä koostuu se henkilökaarti, joka nauttii toimittajien suosiosta vuodesta toiseen?

Ensitöikseni muunsin aineiston Excel-muodosta standardiin CSV-taulukkomuotoon ja latasin tiedon BaseX XML-tietokantaan. BaseX osaa ladata suoraan CSV-muotoisia tiedostoja.

Artikkiliviitteiden asiasanat on tallennettu puolipistein erotettuna yhteen kenttään suuraakkosin kirjoitettuna. Saadakseni poimittua muiden metatietojen joukosta henkilönimet, minun tuli kirjoitella XQuery-skripti joka erottaa henkilönimet ja muuntaa nimet noudattamaan normaaleja oikeinkirjoitussääntöjä. Alla oleva skripti on toteutukseltaan karkea, sillä se tunnistaa henkilönimet asiasanan sisältämän välilyönnin perusteella. Tämän seurauksena mukaan tulee myös muita kaksiosaisia asiasanoja. Tämä ei kuitenkaan haittaa tietokannan sisällön käsittelyä, sillä virheelliset tiedot voi seuloa pois myöhemmässä vaiheessa.

import module namespace functx = "http://www.functx.com"; 
for $record in //record
let $subjects:= tokenize(fn:normalize-space($record/Asiasanat), '; ')
for $subject in $subjects
    let $fullname_reversed:=$subject[contains(., ' ')]
    let $fullname_tokenized:=tokenize(lower-case($fullname_reversed), ' ')
    let $name:= <name>{string-join((functx:capitalize-first($fullname_tokenized[2]),functx:capitalize-first($fullname_tokenized[1])), ' ')}</name>
    let $to_print:= 
    if(string-length($name)>3)
    then <name>{data($name)}</name>
    else ()
return if (not(empty($to_print))) then
insert node $to_print into $record/persons
else()

Skripti täydentää artikkeliviitetietokannan sisältöä persons-kenttään tallennettavilla henkilötiedoilla. Seuraavaksi nämä tiedot tulee ryhmitellä henkilöiden mukaisesti, siten että kunkin henkilön alle kootaan tiedot vuosista, joina kyseinen henkilö on mainittu artikkeliviitessä.

<mentions_in_press>{
for $record in //record
for $person in $record/persons/name

group by $person
return <press_mention><fullname>{$person}</fullname><year>{$record/Vuosi}</year></press_mention>
}</mentions_in_press>

Tämän työvaiheen jälkeen tiedot tulee koostaa vielä kerran, siten että toistuvat vuosiluvut poistetaan ja korvataan kunkin vuosiluvun kohtaan tallennettavalla toistuvuustiedolla.

<press_mentions_in_year>{
for $press_mention in //press_mention
let $years:=distinct-values($press_mention/year/Vuosi)
let $counts:= for $year in $years
              let $count:=count($press_mention/year/Vuosi[.=data($year)])
              order by $year
              return <year count='{$count}'>{$year}</year>
return <press_mention_per_year>
          <name>{$press_mention/fullname}</name>{
          for $count in $counts
            return $count
      }</press_mention_per_year>
    }</press_mentions_in_year>

Viimein kasassa on XML-tietokanta, josta voidaan tehdä suhteellisen helposti erilaisia henkilöihin liittyviä kyselyitä. Tietokannan sisältö siivottuna noin 5000 rivin tienoille muista kuin henkilötiedoista löytyy Githubista. Ajattelin, että tämä saattaisi olla jollekulle mielenkiintoinen XQuery-harjoitteluaineisto :) Myös skriptit löytyvät samasta paikasta.

On oletettavaa, että henkilömainintojen useus riippuu siitä, minkä tyyppisistä lehdistä lehtitietokannan viitteet ovat peräisin. Seuraavista lehdistä tietokanta sisältää yli tuhat viitettä:

Lehti Viitteiden lukumäärä
Apu 10860
Seura 10434
Anna 5867
Me 4810
Hymy 4771
Katso 3587
Spiegel 3318
Eeva 2727
Ilta-Sanomat Plus 2377
Stern 1974
Helsingin Sanomat kuukausiliite 1381
Gloria 1333
City 1237
Se-lehti 1072

Mutta nyt asiaan, henkilömainintoihin.

Eniten mainintoja vuodessa on prinsessa Dianalla, 47 kappaletta vuonna 1997.

Eniten vuosittaisia mainintoja lehtien palstalla on Katri Helenalla. Hänet on mainittu kaikkiaan 37 vuoden aikana. Katri Helenalla mainintoja on eniten vuonna 1993, 13 kappaletta.

Kahdeksan henkilöä ovat paistatelleet vähintään 30 vuotena lehtien palstoilla:

Nimi Ensimmäinen maininta Viimeisin maininta
Esko Salminen 1961 2012
Jörn Donner 1966 2012
Katri Helena 1966 2012
Tapani Kansa 1968 2011
Paula Koivuniemi 1969 2012
Marion Rung 1970 2012
Kaari Utrio 1976 2011
Riitta Väisänen 1976 2012

Kun tarkastellaan vähintään 25 eri vuotena mainittuja henkilöitä -- poislukien edellä mainitut kahdeksan henkilöä -- joukko on jo selvästi suurempi. Ensimmäisen maininnan mukaisessa järjestyksessä:

Nimi Ensimmäinen maininta
Pirkko Mannola 1960
Lenita Airisto 1966
Tamara Lund 1967
Urho Kekkonen 1967
Vesa-Matti Loiri 1968
Ilkka Lipsanen 1968
Marjatta Leppänen 1969
Arja Saijonmaa 1969
Anita Hirvonen 1969
Mirja Pyykkö 1969
Åke Lindman 1970
Sinikka Sokka 1970
Aira Samulin 1970
Erkki Liikanen 1970
Ritva Oksanen 1971
Teija Sopanen 1974
Anne Pohtamo 1976
Armi Aavikko 1977
Matti Nykänen 1982
Anna-Leena Härkönen 1983
Karita Mattila 1983
Satu Silvo 1984
Hannele Lauri 1986

Otetaan lopuksi vielä tarkasteluun ikuisen mäkikotkan, kaimani Matin seikkailut julkisuudessa. Lehtiartikkelimainintojen mukaan järjestestettynä Matin vilkkaimmat vuodet ovat olleet:

Mainintoja Vuodet
9 1994
8 1998
7 1996 ja 2004
6 2010
5 1989, 1995 ja 2005
4 1987, 1988, 1999, 200, 2003, 2006, 2008, 2012
3 1993, 2002, 2011
2 1990, 1991, 2007
1 1982, 1983, 1984, 1992, 1997, 2001, 2009

Nyt kun artikkeliviitetietokanta on XML-muodossa, täytynee ottaa se myös uudemman kerran tarkasteluun. Tämän kokemuksen perusteella tietokannasta saa yllättävän vähällä vaivalla irti yksityiskohtia, jotka ovat tavallisesti kätkeytyneetä tietokannan kokonaisuuteen.

MARC-kenttien käyttö Helmet-tietokannassa

Otin asiakseni tutkia, mitä kirjastoissa vuosikymmeniä eri muodoissa käytetyn MARC-metadataformaatin kenttiä hyödynnetään pääkaupunkiseudun Helmet-tietokannassa. Alkujaan tarkoituksenani oli seuloa MarcXimiL-työkalun avulla tietokannasta esiin siitä todennäköisesti löytyvät duplikaattitietueet. Ohjelman osoittauduttua tuskaisen hitaaksi ja hieman bugiseksi, päätin jättää asian sikseen ja julkaista duplikaattivertailua varten laatimani kenttäyhteenvedon nyt, ja toteuttaa duplikaattivertailun XQueryn avulla joskus myöhemmin, jollei joku muu ratkaise pulmaa minua ennen.

Kenttäyhteenvedon pohjana käytin MarcXimil-työkalun mukana tulleen colldescr -skriptin tulostetta. Oletusarvoisesti colldescr tulostaa kenttien käytöstä prosenttijakaumat sekä kenttien pituuksien keskiarvot. Muokkasin skriptiä niin, että se tulosteeseen saadaan kenttien absoluuttiset määrät sekä pituuksien mediaanit. Muunnetun skriptin voi ladata käyttöön Gist-palvelusta. Ajoin colldescr-skriptin jokaisen Helmet-datadumpin 68 MARCXML-tiedoston kohdalla, joista kukin sisälsi keskimäärin 10000 MARC-tietuetta. Helmet-tietokannan nykyisessä datadumpissa on kaikkiaan 672206 tietuetta (versio 1.1 / 20.5.2011).

Luonnollisestikaan skriptiä ei kannattanut ajaa käsipelillä, vaan kutsuin sitä BASH-komentotulkkiskriptin kautta. Oheisessa komentotulkkiskriptissä viitattu files_to_process.tmp sisältää listan kaikista 68 MARCXML-tiedostosta:

#!/bin/bash

while read line; do
echo $line
python misc/colldescr.py $line > $line.csv
done < files_to_process.tmp%

Skriptin suoritettuani minulla oli 68 kappaletta CSV-muotoisia tiedostoja, joista kukin sisälsi ennen taulukkosarakkeita muutaman rivin skriptin ajonaikaisia viestejä. Nämä täytyi saada poistettua tiedostoista ennen tiedostojen jatkokäsittelyä. Maltoin kuitenkin mieleni ryhtyä poistamaan rivejä käsin ja tutkin hieman R-tilasto-ohjelman dokumentaatiota - olin joka tapauksessa päättänyt laskea yhteenvedon R:ssä, joten jos mahdollista, myös taulukot kannattaisi siivota samaa työkalua käyttäen. Kuinka ollakaan, R:n taulukkolukija osaa jättää pois tiedostojen alusta halutun määrän rivejä ja onnekseni ajonaikaisten viestien määrä tiedostoissa oli vakio. Seuraava R-skripti lataa CSV-muotoiset tiedostot sekä yhdistää taulukkojen arvot yhteisten avainten (l. kenttätunnisteiden) perusteella.

require(plyr)
require(reshape)
csv_files = list.files(
  path="/Users/matti/Documents/2012/HelmetMARCUsage/csv",
  pattern = '*.csv',
  all.files = TRUE, 
  full.names = TRUE)

csv_file_list = lapply(
  csv_files, 
  function(x){
    read.csv(
      file = x,
      skip = 13,
      sep = '\t',
      col.names = c('field', 'count', 'length')
      )})

merged_csv <- merge_all(csv_file_list)

marc_field_usage<-ddply(
  merged_csv,
  c("field"),
  summarise, 
  count = sum(count),
  length = median(length)
  )

Luotu marc_field_usage -muuttuja sisältää kaikkien Helmet-tietokannassa käytettyjen MARC-kenttien ja osakenttien lukumäärät sekä näiden pituuksien mediaanit. Alla olevaan taulukkoon olen ottanut 96 useimmin käytettyä kenttää, sekä liittänyt näiden yhteyteen kenttäkuvaukset Helmet-luettelointiohjeesta.

Kenttä Lkm Mediaanipituus Kuvaus
650 4 a 2603565 11.0 Asiasana, lähdettä ei määritetty
700 1 a 1061766 14.0 Lisäkirjaus henkilötekijästä: nimien järjestys käänteinen, sukunimi.
700 1 e 839056 6.0 Lisäkirjaus henkilötekijästä: tekijän funktio
245 10 a 588940 23.0 Päänimeke
730 0 a 563711 21.0 Lisäkirjaus yhtenäistetystä nimekkeestä: yhtenäistetty nimeke.
730 0 g 561594 14.0 Lisäkirjaus yhtenäistetystä nimekkeestä: säveltäjä.
300 a 552299 13.0 Ulko- tai ilmiasutiedot: aineiston eritysmääre ja laajuus.
041 0 a 547986 3.0 Kielikoodi: teoksen pääkieli.
001controlfield 536786 10.0 Kontrollinumero. ISBN tai ISMN ilman väliviivoja, mikäli saatavissa.
245 10 c 514656 31.0 Vastuullisuusmerkinnöt
260 b 512282 13.0 Julkaisutiedot: kustantaja.
588 a 490797 4.0 Luokka: Helsinki. pääluokka.
260 a 482828 9.0 Julkaisutiedot: kustannuspaikka.
546 a 481203 8.0 Kielihuomautus: teoksen pääkielet.
100 1 a 470081 14.0 Pääkirjaus henkilön nimestä, nimien järjestys käänteinen: sukunimi
020 a 452504 17.0 ISBN-tunnus väliviivoin.
740 0 a 398752 18.0 Lisäkirjaus nimekkeestä: nimeke.
651 4 a 383787 8.0 Maantieteellinen nimi asiasanana, lähdettä ei määritetty: maantieteellinen asiasana.
589 a 371353 4.0 Luokka: Espoo. Pääluokka.
005controlfiled 366827 16.0 Viimeisen transaktion tiedot (konversiohetki Plussa-järjestelmästä?)
590 a 328006 4.0 Luokka: Vantaa. Pääluokka.
913 00 a 321508 12.0 Tuntematon
300 b 280761 6.0 Ulko- tai ilmiasutiedot: kuvitus.
599 a 271929 12.0 Materiaali
260 c 250238 4.0 Julkaisutiedot: julkaisuaika.
300 c 236403 5.0 Ulko- tai ilmiasutiedot: koko.
574 a 223388 16.0 Kirjastokohtainen huomautuskenttä:helsinki. luetteloijan nimi.
500 a 208552 64.5 Yleinen huomautus, soitinkokoonpanohuomautus, laulun alkusanat.
008controlfield 192104 37.0 MARC21-formaatin kiinteämittainen kontrollikenttä.
245 10 b 172685 35.0 Nimeke- ja vastuullisuustiedot: toinen päänimeke.
028 01 a 153642 8.0 ISBN-tunnus väliviivoin.
591 a 143879 4.0 Luokka:Kauniainen. pääluokka.
7102 a 142713 17.0 Lisäkirjaus yhteisötekijästä: analyyttinen tekijä-nimeke -lisäkirjaus.
505 0 a 138765 354.5 Sisältöä tai aihetta koskeva huomautus.
577 a 137756 16.0 Kirjastokohtainen huomautuskenttä: Vantaa.
084 a 137749 5.0 Luokituskoodi
440 0 a 137364 22.0 Sarjamerkintö: sarjan päänimeke.
080 a 127299 5.5 Tuntematon
7102 e 124897 7.0 Lisäkirjaus yhteisötekijästä: analyyttinen tekijä-nimeke -lisäkirjaus. tekijän funktio.
575 a 115631 16.0 Kirjastokohtainen huomautuskenttä: espoo. luetteloijan nimi.
0411 a 114375 3.0 Kielikoodit. teos on käännös tai sisältää käännöksen. teoksen pääkieli.
0411 h 109795 5.0 Kielikoodit. teos on käännös tai sisältää käännöksen. teoksen alkukieli.
300 e 106489 12.0 Ulko- tai ilmiasutiedot. teoksen liiteaineisto.
600 14 a 105818 15.0 Kohdehenkilö. nimien osien järjestys käänteinen, sukunimi.
511 0 a 105443 111.0 Osallistuja- tai esittäjähuomautus.
577 b 102400 9.0 Kirjastokohtainen huomautuskenttä: Vantaa. MuistiVantaa-merkintä, uutuusluettelomerkintä.
028 01 b 101682 9.0 Tuotetunnus. Tuotemerkki.
575 b 97448 9.0 Kirjastokohtainen huomautuskenttä: Espoo.
7650 t 97006 21.0 Alkuteoksen nimeke.
588 b 90809 5.0 Luokka: Helsinki. luokkalisäkirjaus.
574 b 88316 10.0 Kirjastokohtainen huomautuskenttä: Helsinki.
100 1 e 78438 7.0 Pääkirjaus henkilön nimestä, nimen osien järjestys käänteinen. tekijän funktio.
250 a 74135 13.0 Painostiedot, painosmerkintö.
003controlfield 64439 3.0 MARC-kontrollikenttä
590 b 54811 5.0 Luokka: Vantaa. Luokkalisäkirjaus.
589 b 53503 5.0 Luokka: Espoo. Luokkalisäkirjaus.
440 0 v 53200 3.0 Sarjamerkintö. sarjan sisäinen numerointi.
245 14 a 49023 26.0 Nimeke- ja vastuullisuustiedot, ohitettavien merkkien määrä neljä
245 14 c 46261 27.0 Nimeke- ja vastuullisuustiedot, ohitettavien merkkien määrä 4.
7000 a 44243 8.0 Lisäkirjaus henkilötekijästä. sukunimi tai vastaava hakuelementtinä toimiva nimen osa.
700 12 a 41967 15.0 Lisäkirjaus henkilötekijästä. analyyttinen tekijä-nimeke -lisäkirjaus. sukunimi tai vastaava hakuelementtinä toimiva nimen osa.
700 12 t 41847 29.0 Lisäkirjaus henkilötekijästä. analyyttinen tekijä-nimeke -liskirjasu. nimeke.
110 2 a 41220 11.0 Pääkirjaus yhteisön nimestä. valtion tai hallintoalueen nimi tai pääyhteisö.
110 2 e 40253 7.0 Pääkirjaus yhteisön nimestä. tekijän funktio.
700 0 e 40186 6.0 Lisäkirjaus henkilötekijästä. tekijän funktio.
730 0 l 37506 24.5 Lisäkirjaus yhtenäistetystä nimekkestä. teoksen kieliversio.
730 0 p 34534 16.0 Lisäkirjaus yhtenäistetystä nimekkeestä. teoksen osan mikeme.
730 0 o 31642 18.0 Lisäkirjaus yhtenäistetystä niekkeestä. sovitusmerkintö.
600 04 a 30958 8.0 Kohdehenkilö, lähdettä ei määritetty. sukunimi tai vastaava hakuelementtinä toimiva nimen osa.
0243 a 28756 12.0 Muu kansainvälinen tunnus, ean. kansainvälinen tunnus.
7304 a 27400 24.0 Lisäkirjaus yhtenäistetystä nimekkeestä, yhtenäistetty nimeke.
7304 g 26946 13.0 Lisäkirjaus yhtenäistetystä nimekkeestä, säveltäjä.
7404 a 23670 23.0 Lisäkirjaus yhtenäistetystä nimekkeestä, yhtenäistetty nimeke.
578 b 22515 10.0 Kirjastokohtainen huomautuskenttä: kauniainen.
610 24 a 21589 17.0 Kohdeyleisö. muut yhteisöt, ei lähdettä määritetty. valtion tai hallintoalueen nimi, tai pääyhteisö.
440 0x 20711 10.0 Sarjamerkintö, ISSN.
260 f 18553 14.0 Julkaisutiedot, kirjapainon nimi.
730 0 n 17904 7.0 Lisäkirjaus yhtenäistetystä nimekkeestä.
506 a 15830 28.0 Tarkastus tai inventointi, käyttörajoitushuomautus.
260 e 15511 10.0 Julkaisutuiedot, painopaikka.
041 0 b 14056 5.0 Kielikoodi, teos on käännös tai sisältää käännöksen. tiivistelmän tai teoksen muun osan kielti.
100 0 a 13592 8.0 Pääkirjaus henkilön nimestä, nimien järjestys suora
245 14 b 13562 35.0 Nimeke ja vastuullisuustiedot. ohitettavien merkkien määrä neljä, toinen päänimeke.
591 b 12499 5.0 Luokka: Kauniainen.
520 a 12266 56.5 Tiivistelmä ja tiivistelmää tai yhteenvetoa kosketa huomautus. tiivistelmän nimeke.
035 a 12206 19.0 Tunnistenumero järjestelmässä.
518 a 11939 47.0 Äänitys- tai kuvausaikaa ja -paikkaa tai esinelöydön aikaa ja paikkaa koskeva huomautus. huomautus.
730 3 a 11653 21.0 Lisäkirjaus yhtenäistetystä nimekkeestä, yhtenäistetty nimeke.
730 3 g 11448 11.0 Lisäkirjaus yhtenäistetystä nimekkeestä, säveltäjä.
534 c 11000 25.0 Alkuperäisjulkaisua koskeva huomautus, julkaisutiedot.
245 13 a 10665 24.0 Nimeke ja vastuullisuustiedot. päänimeke, ohitettava kolme merkkiä.
240 10 a 10401 24.0 Yhtenäistetty nimeke.
245 13 c 9985 28.0 Nimeke ja vastuullisuustieto, ohitettavia merkkejä kolme
240 10 g 9744 8.0 Nimeke- ja vastuullisuustiedot.
578 a 8699 10.0 Kirjastokohtainen huomautuskenttä: Kauniainen. Luetteloijan nimi.
028 0 a 6881 8.0 Tuotetunnus

Tietokantagalaksi

Kutakuinkin 40000 henkilöä ja noin 310000 yhteyttä

Finmarc 600-kentän datan yhteyksiä  hieman lähempää Datasetin reuna-alueita

Vaski-kirjastot julkaisivat luettelotietokantansa avoimena datana menneen viikon perjantaina - oiva tilaisuus testata, selviääkö vastikään lisämuistilla terästetty (2GB->8GB) työjuhtani koko ~1.7 miljoonan tietueen datasetin pyörittelystä kerrallaan.

Kohteekseni otin FINMARC-luettelointioppaasta bongaamani 600 Kohdehenkilö-kentän, jonka määritys kuuluu: "Kenttään tallennettavat tiedot kohdehenkilöstä liittyvät teoksen sisältöön. Henkilön nimi on asiasanana.". Oppaasta mainittiin myös, että kenttään saatetaan tallentaa myös teoksen kohteena olevan suvun tjms. tietoja -- mielenkiintoista! Päätin katsoa, millaisia verkostoja tähän kenttään tallennettujen henkilöiden ja henkilöjoukkojen välille muodostuu. Nyt alkuvaiheessa tarkoituksenani ei ollut tehdä näistä verkostoista sen kummempia analyysejä, kunhan saisin datan sopivaan muotoon myöhempiä analyysejä varten ja pari nättiä kuvaa tänne verkkoon näytille :)

Harjoituksen vuoksi noudatin tavanomaisesta poikkeavaa työkulkua. Tällä kertaa pidin käsittelemäni tiedot alusta loppuun XML-muodossa. Lähtöpäässä oleva tieto näytti tältä:

<record xmlns="info:lc/xmlns/marcxchange-v1">
  <datafield tag="600" ind1="1" ind2=" ">
    <subfield code="a">Lehtonen</subfield>
    <subfield code="h">J. V.</subfield>
    <subfield code="x">juhlajulkaisu</subfield>
  </datafield>
  <datafield tag="600" ind1="1" ind2=" ">
    <subfield code="a">Sillanpää</subfield>
    <subfield code="h">F. E.</subfield>
    <subfield code="t">Nuorena nukkunut</subfield>
  </datafield>
  <datafield tag="600" ind1="1" ind2=" ">
    <subfield code="a">Lassila</subfield>
    <subfield code="h">Maiju</subfield>
    <subfield code="x">kirjallinen jäämistö</subfield>
  </datafield>
  <datafield tag="600" ind1="1" ind2=" ">
    <subfield code="a">Kivi</subfield>
    <subfield code="h">Aleksis</subfield>
    <subfield code="t">Canzio</subfield>
  </datafield>
  <datafield tag="600" ind1="1" ind2=" ">
    <subfield code="a">Richelieu</subfield>
    <subfield code="h">Armand Jean du Plessis de</subfield>
  </datafield>
</record>

..ja putken päästä, XQueryn avulla tehdyn mankeloinnin jälkeen ulos tuli tällaista, Gephi-visualisointityökalun ymmärtämää GEXF-muotoista XML:ää .

<?xml version="1.0" encoding="UTF-8"?>
<gexf xmlns="http://www.gexf.net/1.1draft" version="1.1" xmlns:viz="http://www.gexf.net/1.1draft/viz" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.gexf.net/1.1draft http://www.gexf.net/1.1draft/gexf.xsd">
  <meta lastmodifieddate="2011-10-02">
    <creator>Matti Lassila</creator>
    <description>Co-occurencies of names in Vaski-database</description>
  </meta>
  <graph defaultedgetype="mixed" mode="static">
  <attributes class="node">
      <attribute id="role" title="role" type="string"/>
  </attributes>
        <nodes>
            <node id="aleksis_kivi" label="Aleksis Kivi">
                <attvalues>
                    <attvalue for="role" value="person"/>
                </attvalues>
                <viz:size xmlns:viz="http://www.gexf.net/1.1draft/viz" value="232"/>
            </node>
            <node id="maria_jotuni" label="Maria Jotuni">
                <attvalues>
                    <attvalue for="role" value="person"/>
                </attvalues>
                <viz:size xmlns:viz="http://www.gexf.net/1.1draft/viz" value="44"/>
            </node>
            <node id="anakreon" label="Anakreon">
                <attvalues>
                    <attvalue for="role" value="person"/>
                </attvalues>
                <viz:size xmlns:viz="http://www.gexf.net/1.1draft/viz" value="3"/>
            </node>
        </nodes>
        <edges>
            <edge source="minna_canth" target="aleksis_kivi"/>
            <edge source="minna_canth" target="juhani_aho"/>
            <edge source="minna_canth" target="teuvo_pakkala"/>
            <edge source="minna_canth" target="ilmari_kianto"/>
        </edges>
  </graph>
</gexf>

En vielä nykyisillä XQuery-taidoillani saanut tehtyä muunnosta yhdellä loitsulla, vaan suodattelin ja yhdistelin datasettiä aina pienempiin ja pienempiin osiin. Loppuvaiheen koostamisen ennen Gephiin siirtymistä tein editorissa, eli laitoin yhteen tiedostoon mukaan erikseen luomani henkilö-solmut ja toisessa tiedostossa olevat henkilö-solmujen väliset yhteydet.

Nyt kun datasetti on oikeassa muodossa ja siistitty, työläin työvaihe on takanapäin. Jahka aikaa on, tutkiskelen mitä datasetistä saa irti. Samalla koitan kirjoittaa lyhyesti auki, mitä työvaiheita MARCXML-muotoisten FINMARC-tietueiden mankelointi Gephin ymmärtämään muotoon vaati.