Tietokantagalaksi

Kirjastot — Avainsanat: , , , — Matti @ 18:39

Kutakuinkin 40000 henkilöä ja noin 310000 yhteyttä

Kutakuinkin 40000 henkilöä ja noin 310000 yhteyttä


Finmarc 600-kentän datan yhteyksiä  hieman lähempää

Finmarc 600-kentän datan yhteyksiä hieman lähempää


Datasetin reuna-alueita

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.

Luetteloijan vuodenkierto

Kirjastot — Avainsanat: , , , — Matti @ 16:23

Vuoden kierto näkyy kirjastoissa. Kesä tyhjentää dekkarihyllyt ja synkimmän talven aikaan matkakirjat löytävät lukijansa. Mutta näkyykö vuoden kierto kirjastotiedossa, luettelotietokannan tietuessa?

Viime kesänä aiempia kirjastoluettelografiikoita tehdessäni olin kiinnittänyt huomiota MARC -kontrollikentässä 008 olevaan päivämäärään. Tuohon kenttään tallennetaan tieto siitä, milloin kyseinen MARC-tietue on alunperin luotu. Sopivasti kentän tietoja käsittelemällä olisi siis mahdollista summailla yhteen tiettyinä kuukausina ja vuosina (ja miksei myös päivinä) luetteloitujen teosten määriä. Tuolloin asian kehittely jäi, koska tiedossani ei ollut kohtuullisella vaivalla opeteltavia työkaluja melkoisen suuren datamäärän läpikäyntiä varten. Tämä pulma ratkesi, kun olen nyt graduuni ja työhöni liittyen koittanut perehtyä XQuery-ohjelmointikieleen ja XML-tietokantoihin. Yhteenvetolukujen laskeminen alkoi näyttää mahdolliselta — tarvitsisi vain tallentaa Helmet-tietokannan sisältö XML-tietokantaan ja harrastaa hieman XQuery-magiaa.

Ja katso, lopulta Ärrä pyöräytti ulos käppyrän. Otin käsittelyyn mukaan aineiston vuodesta 1980 eteenpäin, sillä tätä vanhempaa aineistoa ovat poistot karsineet siksi paljon että kuvion skaalaero olisi tullut turhan suureksi. Lisäksi poistin vuoden 1992 lokakuulta 130961 (!!) tietokantaan viedyn teoksen piikin. Mitäköhän kummaa kirjastossa on tuolloin tapahtunut — vai liekö datassa virhe?

Helsingin kaupunginkirjaston kokoelman kartunta suhteessa aikaan

Helsingin kaupunginkirjaston kokoelman kartunta suhteessa aikaan

Kirjastotyössä olevat osannevat sanoa, muistuttaako kuvio todellisuutta. Kesän hiljaisuus erottuu, mutta näkyykö kuvasta jotain muutakin? Esimerkiksi, mikähän lie syy yksittäisten luettelointiaktiivisuuspiikkien taustalla?PDF-versiosta erottunee yksityiskohdat paremmin.

Työvaiheet olivat kutakuinkin samat, kuin aiemmissa Helmet-aineistoa käyttäneissä kokeiluissani. Aluksi muunsin Helmet-datadumpin XSLT-muunnostiedoston avulla MODS-muotoon (kiitokset muuten Labs-väelle datadumpin päivittämisestä!). MODS-muodosta ajoin tietokannan vielä pienempään ja näppärämpään muotoon, jossa oli vain tarvitsemani tiedot. Vaivainen koneeni ei jaksa pyörittää kovin suuria datamääriä, joten minun tuli karsia aineistosta kaikki ylimääräinen tieto pois. Järeillä laitteilla aineistoa voisi käsitellä suoraan, ilman alkuvaiheen muunnoksia. Lopulta latasin epäolennaisista tiedoista karsitut XML-tiedostot tietokantaan. Karsimisesta huolimatta koneeni alkoi yskähdellä, joten päätin ottaa tarkasteltavakseni vain Helsigin kaupunginkirjaston kokoelmasta löytyvien teosten luettelointitiedot.

Nyt kun tarvitsemani tiedot olivat XML-tietokannassa, saatoin aloittaa niiden käsittelyn XQuery-kielen avulla. Aluksi siistin eksoottisessa MARC-muodossa olevan päivämäärätiedon hieman rakenteisempaan muotoon:


import module namespace functx="http://www.functx.com";

{
for $record in /records/record
let $date:=string($record/created)
let $year:=substring($date,1,2)
let $month:=substring($date,3,2)
let $day:=substring($date,5,2)
return(
{$year}
{$month}
{$day}
)

Varsinainen yhteenvetolukujen laskeminen tapahtui XQueryn count()-funktiolla. Huomasin, että olin onnistunut ylikirjoittamaan toisella skriptillä tämän laskennan tehneen XQuery-loitsun, mutta kyseessä oli kutakuinkin samanmittainen pätkä kuin ylempi.

Viimeisenä askeleena ennen Ärrään siirtymistä otin tiedot ulos CSV-muodossa:


for $year in distinct-values(//year)
for $done_in_month in //done[year=$year]
let $month:=data($done_in_month/month/@id)
return ({$year}-{$month}-1,{data($done_in_month/month)})

Tälläkin kertaa päätin luoda grafiikan R:n ggplot2-kirjaston tarjoamilla työkaluilla. Kuvio syntyi R-komennoilla:

t<-qplot(date, count, data=lastyears, geom="path", group=1, ymax=2000,ylab="",xlab="")
t + scale_x_date(format='%Y',major="years") + theme_bw()

Sanojen rihmat

Kirjastot — Avainsanat: , , , — Matti @ 23:46

Viikonlopun alla julkaistiin Gephi-visualisointityökalun uusi kokeiluversio, ja päätin ottaa asiakseni tutkailla ohjelmaa hieman. Gephi oli minulle nimeltä tuttu, mutten aiemmin ole viitsinyt asentaa sitä koneelleni kun olen arvellut Javalla toteutetun ohjelman olevan kovin resurssisyöppö. No, arveluni osui oikeaan, mutta sopivan pienellä aineistolla viiveet pysyivät siedettävinä.

Tällä kertaa päätin katsoa, millaisia verkostoja Helmet-dumpin tekstimuotoiselle aineistolle annetut asiasanat muodostavat. Kokonaisuudessaan tekstiaineistoa on dumpissa noin 50000 tietuetta. Pilkoin tästä satunnaisotannalla käsiteltäväksi muutamia erikokoisia datasettejä. Tällä kertaa en tarvinnut Python-skriptejä, vaan sain luotua tarvitsemani tiedostot yksinkertaisen XSLT-muunnostiedoston ja UNIX-komentorivityökalujen avulla. Ajoin aluksi koko dumpin tekstiaineiston asiasanat muotoon, jossa kunkin teoksen asiasanat on listattu yhdellä rivillä. Gephiin ladattavat tiedostot syntyivät tästä suuresta tiedostosta rl-työkalun avulla, joka poimii sille annetusta tiedostosta halutun kokoisen satunnaisotannan.

Ohessa kuva kuudensadan tietueen otannasta (korkearesoluutioinen kuva PDF-tiedostona). Kuvassa sinisellä sävyllä korostettu asiasanaryhmä liittyy suomenkieliseen kaunokirjallisuuteen ja keltainen ruotsinkieliseen kaunokirjallisuuteen. Oranssilla on merkitty ruotsinkieliseen tietokirjallisuuteen liittyvät asiasanat ja vihertävällä suomenkielisen tietokirjallisuuden asiasanat. Viivojen paksuus kuvaa sitä, kuinka usein jotkin asiasanat esiintyvät yhdessä. Tähän kuvaan en ole laittanut näkyville, mitkä sanat ovat kyseessä. Täytyy mietiskellä, minkälaiseen kuvaan sanat saisi otettua mukaan, ilman että kuva menee täysin tukkoon. Gephi on melkoisen monipuolinen ohjelma, joten eiköhän sieltä löydy ongelmaan ratkaisu.

Kuudensadan kirjan asiasanojen yhteydet

Runolliset tietueet

Kirjastot — Avainsanat: , , , , — Matti @ 21:06

Muokattu 4.4: Nyt julkaistuja teoksia kuvaavien ympyröiden koko määräytyy teosten lukumäärän logaritmina. Pakkautumisongelma tuntuu helpottavan ja yksityiskohdat säilyvät paremmin. Päivitin esikatselukuvan ja ladattavan PDF-tiedoston.

Jatkoin Helmet-datadumpin pyörittelyä. Istuskelin perjantai-iltapäivän työ/opiskelupaikkani järjestämässä verkostoanalyysi-metodipajassa, josta sain ajatuksen kokeilla SNA-menetelmiä Helmet-aineistoon.

Koska aineisto on melkoisen suuri — satojatuhansia tietueita — mopokonetta ja hermoja säästääkseni päätin ottaa aineistosta jonkin kiinnostavan osajoukon käsiteltäväkseni. Päädyin Suomessa suomeksi tai ruotsiksi julkaistuihin runoihin ja runojen kustantajiin: näin näppitultumalta runoja ei julkaista vuositasolla kovin hurjia määriä ja on mielenkiintoista tietää, mitkä tahot hoitavat tätä julkaisutoimintaa.

Aloitin tarvitsemani aineiston koostamisen ajamalla aiemmin MODS-muotoon saattamastani Helmet-datadumpista XSLT-muunnoksen CSV-taulukkomuotoon, johon tallensin kunkin runoteoksen tekijän, kustantajan ja julkaisuvuoden.
XSLT-muunnoksen synnyttämät taulukot eivät olleet suoralta käsin käyttövalmiita, vaan aineistoa joutui siivoilemaan jonkin verran käsin.

Tämän jälkeen järjestelin ja suodatin UNIX-komentorivityökalujen (sort ja unique) avulla tiedoston sellaiseen muotoon, jossa riveillä on kirjailijan nimi, kustantaja ja kyseisen kustantajan kautta julkaistujen teosten lukumäärä. Nyt data oli sellaisessa muodossa, että käytettävissäni oli kaikki ne tiedot, jotka oletin tarvitsevani mielessäni olevan grafiikan toteuttamiseksi koneen avulla.

Datasta syntyi kaavio Python-ohjelmointikielen NetworkX verkostoanalyysipaketin sekä Graphviz -visualisointityökalun suosiollisella avustuksella.

Python-skriptin nielemä tieto näytti tältä:

4 WSOY Töyrylä, Timo
19 WSOY Vaara, Elina
4 WSOY Vala, Katri
5 WSOY Venho, Johanna

…ja skriptin tuottama, DOT-muotoinen tieto kutakuinkin tältä:


"Vaara, Elina" [style=filled, fixedsize=true, height="0.25", width="0.25", shape=circle, role=author, fontsize=1, label="", color=lightgray];
WSOY [width="2.5", style=filled, fontsize=12, fixedsize=true, role=publisher, color=red, height="2.5"];
"Vaara, Elina" -> WSOY [color=gray37, penwidth=4];

Loppu olikin silkkaa automagiaa suurimmaksi osaksi. Latasin DOT-tiedoston Graphviz-ohjelmaan, joka pienen asetustensäätelyn jälkeen lykkäsi ulos haluamani grafiikan. Jahka saan opeteltua Graphviziä lisää, koitan josko saisin mankeloitua esityksen hieman havainnollisempaan muotoon.

Runokustantajat

Kuvassa punaiset ympyrät ovat kustantajia ja harmaat kirjailijoita. Ympyrän koko heijastelee julkaistujen teosten määriä.

Esikatselukuva sisältää vain pienen osan koko grafiikasta — ohessa kuva kokonaisuudessaan PDF-muodossa.

Kartta kirjastosta

Kirjastot — Avainsanat: , , — Matti @ 14:13

Macen tammikuisen postauksen innoittamana sain viimeinkin piirreltyä ensimmäiset Helmet-kirjastojen kokoelmaa kuvaavat tilastografiikat. Aloitin grafiikkojen takana olevan aineiston pyörittelyn jo kesäkuun helteiden aikaan, Helmet-kirjastojen julkaistua kokoelmatietokantansa avoimena datana. Proggis kuitenkin jäi telakalle, josta sen nyt viikonloppuna herätin henkiin virkistääkseni R-taitoja gradutaistoa varten.

Grafiikat ovat syntyneet Helmet MARCXML-aineistodumpista, joka on ajettu aluksi MODS-muotoon XSLT-muunnostiedostolla. Sen jälkeen tiedot muutettiin CSV-taulukkomuotoon toisella XSLT-muunnoksella. Ensimmäisen muunnosvaiheen olisi voinut hyvin jättää väliin, ja ajaa tiedot taulukoksi suoraan MARCXML-muodossa. Koin kuitenkin selväkielisen MODS-tiedostomuodon käsittelyn helpommaksi, siihen nähden että olisin MARCXML:ää pyöritellessäni joutunut miettimään, mikä kenttäkoodi vastaa mitäkin metatietoa.

Siivoilin muunnostiedostojen avulla syntynyttä CSV-taulukkotiedostoa pienillä Python-koodinpätkillä ja latasin tämän jälkeen tiedoston R-tilasto-ohjelmaan. Ärrässä mankeloin tiedot tarvitsemaani muotoon ja lopulta tuotin grafiikat R:n treemap-kirjaston avulla. Kaikki edellä mainitut ohjelmat ja työkalut ovat vapaata koodia.

Pidemmittä puheitta — kokoelmagrafiikoita, olkaa hyvä. Pikkukuvaa klikkaamalla grafiiikan saa suurennettua. Mikäli grafiikkojen muoto on outo, Wikipedia-selvittää mistä on kyse (Treemapping-artikkeli).

This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License.
(c) 2012 Kaukomieli | powered by WordPress with Barecity