donderdag 11 december 2014

Google op de juiste wijze souffleren

Websites als Genealogie Online krijgen veel verkeer via Google (de 67,8% in onderstaande taartdiagram staat voor 427K sessie in de afgelopen maand).

imageDit gebeurt niet allemaal vanzelf, je kunt hier zelf heel wat invloed op hebben. Zo heeft biedt Genealogie Online meerdere sitemaps aan Google, waaronder één van bijna 25M items! Hierdoor haalt de Googlebot zo’n 1,4M pagina per dag op:

image

Ook bevatten veel van de Coret Genealogie pagina’s microdata zoals gedefinieerd door schema.org, waardoor Google ook beter de inhoud begrijpt. Zo weet Google dat er op Genealogie Online heel wat Persons zijn te vinden, op het Stamboom Forum genealogische Events en in de Stamboom Gids Reviews van genealogische websites.

Je kunt Google ook vertellen hoe de zoekmachine van je website werkt. Dit is handig om de statistieken in Google Analytics te krijgen over interne zoekopdrachten, maar Google gebruikt het ook in de zoekmachine. Zoek je op Google bijvoorbeeld op “genealogieonline” dan krijg je naast de beschrijving en belangrijke pagina’s ook een zoekvak. Als je in dit zoekvak een zoekterm intypt en op de zoekknop klikt wordt direct de zoekfunctie van Genealogie Online aangeroepen.

image

imageAls je als website niet aan Google uitlegt hoe je zoekfunctie werkt kun je alsnog zo’n zoekvak zien, maar die leidt dan tot een zoekactie binnen alle door Google geïndexeerde pagina van je website (dus “site:www.mijnwebsite.nl zoekterm”).

Nieuw is dat Google Search in de resultaten op smartphones nu ook aangeeft dat de website “voor mobiel” geschikt is. Zo ver ik weet heb ik dit Google niet expliciet verteld, dus de Googlebot heeft ook naar de CSS van mijn websites gekeken en (goed) geconcludeerd dat door de responsive design van de website het ook goed op een mobiel te bekijken is.

donderdag 25 september 2014

#opendata verrijken met #opendata

De gemeente Enschede heeft een eigen Open Data portal waar ze diverse open data sets ten toon en beschikbaar stellen. Naar aanleiding van een WOB verzoek mijnerzijds hebben zij ook datasets van het Stadsarchief Enschede toegevoegd. De historische gegevens van de Burgerlijke Stand van Lonneker en Enschede zijn nu ook beschikbaar voor hergebruik.

De dataset is opgedeeld in 6 delen:

  • Geboorteakten Enschede (1811-1910)
  • Geboorteakten Lonneker (1811-1910)
  • Huwelijksakten Enschede (1811-1935)
  • Huwelijksakten Lonneker (1811-1934)
  • Overlijdensakten Enschede (1811-1960)
  • Overlijdensakten Lonneker (1811-1934)

Het verwerken van de geboorte- en overlijdensakten – beschikbaar gesteld in HTML, JSON, XML, CSV, TSV, TAG, maar niet A2A – voor opname in Open Archieven ging redelijk voorspoedig.

De datasets bevatten helaas niet alle meta-data van de akten. Zo ontbreken het opmerkingen veld èn is er geen link naar een thumbnail of viewer van de scan van de akte. Met wat kunst- en vliegwerk kan er wel een link worden gelegd naar de akte op de website van het Stadsarchief Enschede (behalve bij de geboorteakten van Enschede lukt dit nog niet).

Ambigue data

Bij de huwelijksakten liep ik tegen een probleem aan. Men heeft er voor gekozen om de ouders van de bruid en bruidegom met de rol ‘Vader’ en ‘Moeder’ aan te duiden. Zie hieronder een voorbeeld van deze data:

image

Voor de presentatie en de slimme zoekfunctionaliteit op Open Archieven en ook voor de OAI-PMH data provider (waarmee alle open data voor harvesting beschikbaar is volgens A2A model) is het van belang te weten wie de ouders van wie zijn.

image
De uitdaging was dus om de juiste vader en moeder bij bruid en bruidegom te krijgen. Eén deel is makkelijk, daar de familienaam van de vader in deze tijd (1811-1935) werd doorgegeven aan het kind. Het probleem was hiermee gehalveerd, nu alleen nog de juiste moeders bij bruid en bruidegom krijgen!

Om dit te bereiken worden de geboorte- en overlijdensakten gebruikt. Deze akten bevatten immers ook relatiegegevens (kind-vader-moeder en overledene-vader-moeder). Door nu binnen deze geboorte- en overlijdensakten (fonetisch) te zoeken naar bruidegom+vader van de bruidegom+moeder 1 of moeder 2 en bruid+vader van de bruid+moeder 1 of moeder 2 valt de juiste combinatie te achterhalen. Overigens hoeven in veel gevallen niet alle combinaties getest te worden.

image

Het is geen perfecte oplossing. Immers bruid of bruidegom kan geboren zijn voor 1811 of na 1910, zijn overleden voor 1811 of na 1960, maar nog waarschijnlijker ze zijn geboren of overleden buiten Lonneker en Enschede, in al deze gevallen zullen er dus geen geboorte- of overlijdensakten gevonden worden voor het ‘afleiden van ouderschap’. Onderstaande tabel toont de resultaten van deze “verrijkingsaanpak”:

Huwelijksakten Ouderparen gevonden Ouderparen niet gevonden
Enschede 10.879 (61%) 7.042 (39%)
Lonneker 8.258 (77%) 2.502 (23%)
Totaal 19.137 (67%) 9.544 (33%)

Dat 2 op de 3 huwelijksakten “verrijkt” kon worden met behulp van (als open data beschikbaar gestelde) geboorte- en huwelijksakten is toch leuk!
 
image

dinsdag 23 september 2014

Kennisgevingen van verwijdering uit Google Zoeken, een eerste analyse

De uitspraak van het Europe Hof dat iedereen het recht heeft om vergeten te worden op Internet heeft Google en andere zoekmachines genoodzaakt om het mogelijk te maken voor inwoners van de Europese Unie om een verzoek in te dienen om bepaalde links met persoonlijke informatie te laten verwijderen.

De uitspraak vereist dat Google en andere zoekmachines afwegingen maken tussen het recht van een individu om vergeten te worden en het recht van het publiek op informatie.

Inmiddels zijn er voor websites van Coret Genealogie de eerste kennisgevingen binnengekomen, tijd voor een eerste analyse.

image

URL: http://www.genealogieonline.nl/genealogie-beernaert-corneillie/I21942.php

Op Genealogie Online staat de publicatie Genealogie Beernaert - Corneillie met daarin een pagina over Michiel Delanghe. De goede man is in 1713 overleden, dus ik denk niet dat hij degene is die het verzoek heeft ingediend. Het vreemde is dat er op deze pagina helemaal geen informatie staat over levende personen. Geldt het recht op vergeten te worden ook voor overleden personen?

URL: http://www.genealogieonline.nl/over-de-familienaam/knuijver

Op Genealogie Online staan pagina’s met verzamelde informatie over familienamen. Op de “Over de familienaam Knuijver” pagina komen een tweetal namen voor van levende personen, onderzoekers die de familienaam (onder)zoeken. Is puur het noemen van namen van onderzoekers al reden om te laten vergeten?

Of één van de twee onderzoekers het verzoek heeft ingediend weet ik niet. Google geeft alleen een algemene kennisgeving waar je zeer weinig uithaalt, alleen de uit de zoekresultaten verwijderde URL(‘s). De drempel om een verzoek tot verwijdering in te dienen is best hoog, zo moet er bijvoorbeeld een kopie identificatiebewijs worden aangeleverd. Als onderzoekers de gegevens weg willen hebben is het makkelijker om zelf de door hen zelf ingevoerde profielgegevens aan te passen op het Stamboom Forum! Dan had het verwijderingsverzoek voor http://www.stamboomforum.nl/wiezoektwie/zoeken.php?q=knuijver ook achterwege kunnen blijven.

URL: http://www.genealogieonline.nl/stamboom-van-rijn/I68353.php
URL: http://www.genealogieonline.nl/stamboom-van-rijn/I68636.php

De Genealogie Online publicatie Stamboom Van Rijn bevat pagina’s over Nicolaas Petrus Kerssens en Martha Maria van Berkel, beide overleden. Genealogie Online heeft ingebouwde privacy bescherming: als van personen niet kan worden bepaald (door te kijken naar beschikbare data van de persoon, zijn gezin en voorouders) dat hij of zij is overleden dan wordt aangenomen dat de personen leven en dus worden de gegevens niet gepubliceerd. Bij deze twee personen (een echtpaar) zat er in een notitieveld (=vrije tekst) informatie over nog levende personen (hun kinderen). Gegronde reden voor een verzoek vergeten te worden.

Maar, met zo’n verzoek aan zoekmachines verdwijnt de informatie niet! Het lijkt dat door het recht om vergeten te worden mensen zijn vergeten dat je bij de bron de informatie moet (laten) aanpassen of verwijderen. Is de bron weg of aangepast dan wordt de index van Google automatisch aangepast. In dit geval heb ik wel de auteur van de publicatie ingelicht die de notitie heeft verwijderd, maar dat is nu net weer geen automatisme.

dinsdag 12 augustus 2014

Geographical distribution of genealogical events in a new graph

One of the aspects shown on a statistics page of a publication on Genealogie Online is the “Distribution within the Benelux”. This map shows(approximately) where in the Belgium, Netherlands and Luxemburg area the genealogical events in the data collection took place. The larger the circle, the more events. This works reasonable when the numbers are small (see image below on the left) but doesn’t do well with big numbers (see image below on the right).

Spreiding binnen de BeneluxDistribution within the Benelux

Hexagonal binning

What I wanted was a means to aggregate the data into a more coarse representation suitable for display. Enter hexagonal binning. Rather than displaying a scatter plot with tens of thousands of points/circles, you can bin points into gridded hexagons, and then display the distribution using colour and/or area.

I’ve worked with D3.js before, see for example the interactive paternal lineage graph. The D3 Javascript library helps you bring data to life using HTML, SVG and CSS. I started from the Bivariate Hexbin Map example which showcased the use of the d3.hexbin plugin. Where my previous distribution graph just worked with a base image, for the hexbin map I needed the contours of the Benelux countries in JSON format. I found I could generate a GeoJSON via an usefull website which had this public domain information. But, the hexbin map required a TopoJSON. This is an extension of GeoJSON that encodes topology. Rather than representing geometries discretely, geometries in TopoJSON files are stitched together from shared line segments called arcs. TopoJSON eliminates redundancy, offering much more compact representations of geometry than with GeoJSON; typical TopoJSON files are 80% smaller than their GeoJSON equivalents. With the use of the topojson tool I could easily convert the GeoJSON to the required TopoJSON.

The data which get’s binned is constructed by Genealogie Online from the users GEDCOM. Each place name, from individual events like birth and death and family events like marriage, is collected. The dataset of geographical database Geonames.org is used to lookup the longitude and latitude of each place. The quality of this fuzzy matching process depends on the quality of the data of the users. In general over 80% of place names is recognized. Lastly, the longitude/latitude values for each event are counted. This results in tab separated lines like “52.29616 4.57822 25” which translated to “in this publication 25 genealogical events were found which took place in Hillegom (Netherlands)”.

The hexbin map draws a hexagon for a specific area. The colour is determined by the number of events within this area, which could consist of multiple places. The d3.hexbin plugin takes care of the heavy lifting, basically it just takes the TopoJSON and the TSV and constructs the hexbin maps:

imageimage

The result is cleaner, but maybe less impressive for the large numbers. To counter this a little bit, a legend was added to show what a hexagon represents (waarden=values). Still, the lightest colour in the left image could represent values 1-70, where as the same colour in the right image could represent 1-5000. More tweaking can be done by using other colouring scales (which now is linear) and the size of the hexagon.

Output format

The hexbin map is generated on the fly within the users browser. But this does require a modern browser, loading several Javascript files and the TopoJSON and TSV files. Alternatively the ‘HTML page’ could be loaded server-side by phantomjs, a headless WebKit scriptable with a JavaScript API. By scripting this in the whole publication process of Genealogie Online, the result is just SVG which D3 generated. The resulting SVG is somewhat big, around 400KB. Using an SVG scrubber like Scour the SVG can be optimised (which brings it down to 2/3) and compressed (which brings is down to 1/10). The resulting SVGZ is around 21KB. Browser support for SVG(Z) is pretty good, major exception being IE8. About 2.5% of Genealogie Online users still use IE8. So I should have a backup like a PNG version. From the SVG, a PNG can be made via svg2png. A final call to optipng downsizes the 112KB PNG to a 75KB file.

Work in progress

At the moment, the hexbin maps are only available as proof of concept. Looking at the maps resulted in new questions. Should the hexagons have tooltips? Should they be clickable, causing a geographical search within the publication for people with events in that area? Why limit the graph to the Benelux? Why not make the map zoomable and pan-able? Or should I just opt for the marker cluster solution I use on the Stamboom Forum (see image below, click it to see dynamic version)?

image

vrijdag 25 juli 2014

Roadmap for smarter historical records search engines

This article describes a roadmap which developers of historical records search engines can follow to make the results better. To show the most comprehensive solution works, some insight is given in the results of the website Open Archives.

Roadmap

Generation 1 – searching within a single databaseGeneration 1 – searching within a single database

Many archive websites in the Netherlands offer historical records. These records are indexed and the search engine uses this index of meta data. Search results are listed and usually can be filtered by source type and year. By clicking a search result the record is shown, e.g. all the available meta-data and, when available, a link to a scan. The search ends here (why?!). The next step in the search process has to be taken by the user himself, maybe by clicking a linked name in the result which starts a new search, by looking at other search result or entering a new search based on gained knowledge.

Generation 2 – searching within multiple databases (portals)Generation 2 – searching within multiple databases (portals)

When a website has multiple databases (or logical datasets within a single database) from several sources, the user can search these multiple databases with one search. The Dutch playing field shows 3 categories of ‘portals’. One big supplier of an archival system (a SaaS solution) has made a separate portal site which shows all data of all customers (who also show only their own data on their own website). Another big supplier, who also offers an archival system as a SaaS, doesn’t offer a separate portal, but offers their customers the opportunity to have the search on their website include search results from other customers (archives). A third category of websites collect data from archives, for example by harvesting via the OAI-PMH protocol. This generation of search engines simply have more data to search within, but in principle don’t differ much from the 1st generation.

Generation 3 – smart re-searching after records selectionGeneration 3 – smart re-searching after records selection

A researcher/genealogists usually continues the search to get knowledge about the personal relations and to find more ‘proof’ in the form of relevant records. These kind of searches, which follow after a record is selected and shown can be executed automatically! With ‘smart re-searching’ I refer to the ability to use the meta-data of a records to do additional relevant searches. The results, being suggestion for related records, are shown with the record (e.g. on the page of the birth record the persons marriage- and death record is also shown as direct links). Smart re-search which can be executed automatically using for example the name & birth date of the person(s) mentioned, or by using the names of both parents. With smart re-search you’ll get more information from the same database (compared to the 1st generation search engines)!

Generation 4 – smart re-searching within multiple databasesGeneration 4 – smart re-searching within multiple databases

This generation of search engines merge the combination of datasets (the portals) with smart re-searching which results in getting even more information from more data. This make sense in a technical way, but also in a practical way. People may not live in one place only. They are born in one place, get married in a second place and die in a third place. This results in records being scattered over multiple archives. This generation of search engines shows a combined view of records from several archives centred about a person.

Generation 5 – smart re-searching within multiple databases and beyondGeneration 5 – smart re-searching within multiple databases and beyond

The ‘pool of databases’ which are queried for a search can be expanded even more, with external sources. By using the API’s of such external source or harvesting the required index (so not all data, just the meta-data to be used in smart re-searching) even more information is available for a smart re-search after record selection.
So, don’t stop searching after a search result is shown, this should trigger smart re-search, which should include external data sources!

The proof of the pudding is in the eating

Open Archives is an independent website which harvests open data (=data available for re-use under a free license) from archives and researchers. Archives in the Netherlands which offer open data include Erfgoed Leiden, the municipal archives of Tholen, Ede, Schouwen-Duiveland and Wassenaar, regional archive Langstraat Heusden Altena and the National Archives. The index of these datasets is used for normal querying but also smart re-searching. For smart re-searching an array of  external sources is also used, like Find-A-Grave-like sites Graftombe.nl and Dutch-Cemeteries.com, the victim register of the war graves society, the Biographic Portal of the Netherlands and the largest Dutch family tree website Genealogie Online. So Open Archives is an example of a 5th generation search engine.
An examples shows the smart re-search in action. The registration of Cornelia van Ast (a record of the archive in Leiden) is presented with:
  • a link to the birth record from Noordgoude (from the municipal archive of Schouwen-Duiveland),
  • links to 2 registrations in Tholen (from the municipal archive of Tholen),
  • a link to a family tree on Genealogie Online. a link to a photo of her grave on Dutch-Cemeteries.com, and,
  • a link to a family tree on Genealogie Online.
These highly linked results are a very useful tool for users!

chord diagram


Nice example, but are there more? To find out, all records presented on Open Archives where analyzed to count the links to other sources (from the same archive, another archive or an external source) for each record based on name & birth date (so only one method of smart re-searching). The resulting matrix (with number of links from a source to another source) can be shown in a chord diagram. This diagram shows smart re-searches do deliver results. The dynamic version of this graph can be seen on the Archives linked by historical persons page on Open Archives.
chord diagram
In this diagram the 3-letter codes are the datasets from archives, the 2-letter capital codes are external sources (these sources obviously don’t have links to archives). The ‘humps’ in the archive datasets mean that a lot of additional records were found in the same archive dataset, showing that even generation 3 is already feasible and valuable.

maandag 7 juli 2014

Inzet van de crowd en algoritmes bij Nijmeegse woningkaarten

Open Archieven heeft nu een tweede crowdsourcingsproject: de woningkaarten van Nijmegen (1920-1946).

De door het Regionaal Archief Nijmegen aangeleverde data (bestaande uit 26.458 records) bevatte per woningkaart een link naar één scan. Het idee hierachter was dat de woningkaarten dubbelzijdig zijn en de achterkant vaak leeg was. Bij een steekproef bleek mij echter dat het ook vaak voorkwam dat er meerdere scans waren gekoppeld aan één woningkaart. Het meest extreme voorbeeld was de woningkaart van Westkanaaldijk 301 (Weesinrichting Neerbosch) waaraan maar liefst 290 scans aan gekoppeld waren. Via wat ‘scripting’ heb ik per woningkaart achterhaald welke scans eraan welke woningkaart waren gekoppeld. In onderstaande grafiek (met logaritmische y-as) kan worden afgelezen hoeveel woningkaarten een bepaald aantal gekoppelde scans heeft.

 image

Als alleen de eerste scan van een woningkaart geïndexeerd zou worden (dus de eerste verticale balk in bovenstaande grafiek) zou een groot deel (35.950 scans) ongeïndexeerd blijven. Dit leek mij geen goed idee, vandaar dat alle scans zijn ingelezen in de indexeringstool van Open Archieven.

Scan bevat geen informatie

Toen alle 59.667 scans waren opgenomen kwam je bij het indexeren wel vaak een lege woningkaart tegen, te vaak… De indexeerder heeft de mogelijkheid om aan te geven dat de scan geen informatie bevat, maar dit voelt toch niet fijn als je wilt indexeren. Bij crowd-sourcing vraag je aan mensen om een relatief eenvoudige taak uit te voeren die voor de computer te lastig is. Een mens ziet eenvoudig of een kaart leeg is, maar een computer?

De uitdaging die werd opgepakt: bedenk (en maak) een algoritme die een scan van een ingevulde woningkaart kan onderscheiden van een scan van een lege woningkaart. De gekozen aanpak gaat ervan uit dat de woningkaarten een vaste structuur hebben. Er wordt uit de woningkaart een gedeelte gepakt die overeenkomt met ruwweg de 1e cel van het ‘formulier’ (hieronder weergegeven door de gele rechthoek). Het aantal kleuren van dit gedeelte wordt teruggebracht naar een zeer beperkt aantal kleuren. Hierna wordt er ‘geteld’ hoeveel zwarte pixels er in voorkomen. Wanneer dit aantal hoger is dan een bepaalde drempelwaarde, dan staat er tekst!

image Een visuele controle van de methode leerde dat het algoritme vrij goed werkte maar niet perfect is, of beter gezegd de uitgangspunten die ten grondslag liggen aan het algoritme zijn niet altijd waar. Een enkele keer begint de tekst in de 2e cel, soms is de kaart donker waardoor er meer zwart wordt ‘gezien’, soms is de structuur van de kaart net iets anders, enz.

Kwaliteit van indexeren

Om hoge kwaliteit indexen te krijgen wordt elke kaart minimaal 2 keer geïndexeerd. Als er twee maal hetzelfde is ingevoerd (door twee verschillende indexeerders) dan kan worden aangenomen dat de tekst goed is overgenomen (de kans dat twee personen dezelfde fout maken is erg klein). Komt de invoer niet overeen dan wordt de kaart voor een 3e keer ter indexering aangeboden. Is er hierna nog niet een set van 2 overeenstemmende invoersets dan kijkt een controleur er naar.

Omdat er niet volledig op het lege-kaart-detectie-algoritme kan worden vertrouwd worden de indexeerders hierbij ingeschakeld. Het algoritme zorgt voor de 1e invoer – ruim 4 duizend herkende lege kaarten - en de indexeerders voor de 2e invoer. Op deze manier krijgen indexeerders de helft minder lege kaarten te zien en wordt de uitkomst van het algoritme gecontroleerd door de indexeerder (doordat hij/zij aangeeft dat de scan geen informatie bevat).

Nu is het even afwachten totdat de indexeerders alle woonkaarten hebben geïndexeerd, dan wordt zichtbaar of het algoritme veel of weinig lege kaarten heeft gemist. Hoe dan ook is er dan weer een mooie index beschikbaar, die voor een ieder als open data beschikbaar is!

dinsdag 27 mei 2014

What's the best way to harvest an OAI-PMH data provider?



The OAI-PMH protocol defines several verbs which can be used in requests to an OAI-PMH data provider. For harvesting, the most obvious are:
  • ListIdentifiers, which returns a list of identifier of records, in combination with
  • GetRecord, which returns the record for the specified identifier
  • ListRecords, which return a set of records
Which verb to use?

Some harvesting solutions choose to do a ListIdentifiers and for each identifier do a GetRecord. Some choose to harvest with the ListRecords verb. Although both methods lead to the same content (discarding the OAI envelope header and focusing on the record), the number of HTTP requests differ, obviously. But, does this have an impact on the performance?

Which connection method to use?

As the OAI-PMH protocol harvests via the HTTP protocol there are also alternative connection methods to be inspected, like HTTP compression (accept-encoding:gzip) and connection Keep-Alive. What is the impact of these alternative connection methods on the performance of OAI-PMH harvesting?

Test method

To answer these questions the following test was conducted. Four (Dutch) OAI-PMH data provider where selected. For each data provider an harvest for about 10.000 records was done with both the ListIdentifier/GetRecord method and the ListRecords method. For each of these tests the standard connection was timed, as well as a gzipped, gzipped+keep-alive and keep-alive connection method. These 16 tests were carried out twice and an average of the elapsed times was analyzed.

Test results

The graph below shows the results of these tests, so the number of records per minute for each connection type (more=better).
The complete results as well as the graph are available in a Google Spreadsheet. For the connection type WebPageTest was uses to determine if the method was supported. The tests where carried out with 2 Perl scripts and a Bash file which, together with the resulting output, can be downloaded here.

Conclusions

  • Clearly, you get a better performance (=higher number of records per minute in a harvest) when you use the ListRecords method. So lesser HTTP requests results in faster harvests (about 2.5 - 11 times faster!!!)
  • The use of keep-alive and gzip varies per OAI-PMH data provider. In general: if a data provider supports keep-alive and/of gzip, you'd better use is, it improves performance! You mileage may vary per data provider, so test what's the best solution.

Final notes
  • Although this test was conceived to show the difference in verb usage and connection type, it also shows that some data providers perform better than others. Room for improvement...
  • For those who have inspected the used Perl scripts might wonder why the "Beeld en Geluid" and "Open Beelden" data providers receive other parameters. Well, it's seems they do not follow the OAI-PMH version 2.0 standard by the letter. It's stated that the metadataPrefix is required when doing a ListIdentifiers or ListRecords. But these two data providers do not work when you use the metadataPrefix and resumptionToken together...