Hilfe:Personendaten/Datenextraktion

aus Wikipedia, der freien Enzyklopädie
Wechseln zu: Navigation, Suche

Die Extraktion der Personendaten und PND-Links ist entweder aus einer SQL-Datenbank oder direkt aus dem XML-Dump [1] möglich.

Extraktion aus einer SQL-Datenbank[Bearbeiten]

Mit einer SQL-Abfrage in der Datenbank lassen sich durch jeden Nutzer die Personendaten aus allen Wikipedia-Artikeln des letzten Datenbank-Dumps herausfiltern.

SELECT cur_namespace, cur_title,
SUBSTRING(SUBSTRING(cur_text FROM INSTR(cur_text,'{{Personendaten|' )), 1, INSTR(SUBSTRING(cur_text FROM INSTR(cur_text,'{{Personendaten|' )),'}}')+1) AS 'Personendaten'
FROM cur
where cur_text Like "%{{Personendaten%"
and cur_namespace = 0
and cur_is_redirect = 0
Limit 10

Allerdings müssen die so extrahierten Personendaten mit weiteren Skripten in einzelne Datenfelder aufgeteilt werden.

Extraktion aus einem XML-Dump mittels Perl-Skript[Bearbeiten]

Im Folgenden wird ein einfaches Perl-Skript dargestellt, welches aus einem z. B. mittels des Tools Seiten exportieren erstellten XML-Dump die Personendaten ausliest und in eine CSV-Tabelle umwandelt, die sich dann in üblichen Tabellenkalkulationen weiterverarbeiten lässt. Dazu wird perl benötigt, welches auf Unix-Betriebssystem wie Linux meistens vorinstalliert ist. Windows-User müssen es i. d. R. selbst installieren und können dazu z. B. Strawberry Perl verwenden.

Vorgehensweise[Bearbeiten]

1. XML-Dump herunterladen und als Datei mit beliebigem Namen (z. B. quelldatei.xml) speichern.

2. Den folgenden Quelltext in einer weiteren Datei (z. B. pndextrakt.pl) speichern, der Einfachheit halber im gleichen Verzeichnis wie obige Datei:

printf "Name\tAlternativnamen\tKurzbeschreibung\tGeburtsdatum\tGeburtsort\tSterbedatum\tSterbeort\n"; #Tabellenkopf
while ($zeile = <>) #Die folgenden Aktionen laufen für jede Zeile des XML-Dumps
{
if ($zeile =~ m/{{Personendaten/)
        {
        if ($offen == 1)
                {
                printf "Syntaxfehler in der Datenquelle. Offene Personendaten nicht geschlossen. $zeile\n" ;
                $fehlerzaehler = $fehlerzaehler + 1;
                $zaehler = $zaehler + 1; 
                }
        else
                {
                $offen = 1;
                $zaehler = $zaehler + 1;
                }
        }
if ($offen == 1)
        {
                while($zeile =~ m/(.*)\[\[(.+\|)?(.*)\]\](.*)/) #entfernt Wiki-Links, solange noch welche in der Zeile stecken
                        {
                        $zeile = $1.$3.$4;
                        }
                if($zeile =~ m/NAME=(.*)/)
                        {
                        $name = "$1";
                        }
                if($zeile =~ m/ALTERNATIVNAMEN=(.*)/)
                        {
                        $alternativnamen = "$1";
                        }
                if($zeile =~ m/KURZBESCHREIBUNG=(.*)/)
                        {
                        $beschreibung = "$1";
                        }
                if($zeile =~ m/GEBURTSDATUM=(.*)/)
                        {
                        $geburtsdatum = "$1";
                        }
                if($zeile =~ m/GEBURTSORT=(.*)/)
                        {
                        $geburtsort = "$1";
                        }
                if($zeile =~ m/STERBEDATUM=(.*)/)
                        {
                        $sterbedatum = "$1";
                        }
                if($zeile =~ m/STERBEORT=(.*)/)
                        {
                        $sterbeort = "$1";
                        }
        }       
        
        
if ($zeile =~ m/}}/ && $offen == 1)
        {
        $offen = 0;
        printf "$name\t$alternativnamen\t$beschreibung\t$geburtsdatum\t$geburtsort\t$sterbedatum\t$sterbeort\n"; #Datensatz ausgeben
        }
}
printf "Personen: $zaehler\n";
if($fehlerzaehler > 0)
        {
        printf "Fehler: $fehlerzaehler.\n";
        }

3. Skriptdatei mit folgendem Befehl ausführen

perl pndextrakt.pl quelldatei.xml > zieldatei.csv

zieldatei.csv ist nun die CSV-Datei mit den extrahierten Daten. Es kann auch ein beliebiger anderer Name für diese Datei gewählt werden. Jeder Personendatensatz steckt in einer Zeile, die einzelnen Werte (bzw. Zellen) sind durch Tabulatoren getrennt. Beim Öffnen in OpenOffice muss daher unter Trennoptionen „getrennt“ und als Trennzeichen ausschließlich „Tabulator“ angegeben werden. In der letzten Zeile steht die Anzahl der erfassten Personendatensätze.

Extraktion aus dem XML-Dump[Bearbeiten]

Im Folgenden wird nicht nur die Extraktion von Personendaten aus dem XML-Dump, sondern ein gesamter ETL-Prozess beschrieben, mit dessen Ergebnis die Personendaten detailliert aufbereitet zur Verfügung stehen.

Extraktion[Bearbeiten]

Processing MediaWiki XML with STX ist eine Möglichkeit zum Parsen des XML-Dumps. Dazu werden STX- und Perl-Skripte verwendet (extractPersonendaten.stx, pd2tab.stx und ggf. correct-dump.pl), die unter  (Seite nicht mehr abrufbar; Suche im Webarchiv)[2] Vorlage:Toter Link/tools.wikimedia.de verfügbar sind:

XML_DUMP=pages_current.xml.gz
zcat $XML_DUMP | correct-dump.pl 
               | java -jar joost.jar -o pd.extract - extractPersonendaten.stx pd2tab.stx 
              2> pd.log

Als Ausgabe werden eine Logdatei pd.log mit Mitteilungen und Warnungen sowie die Tabulator-getrennte Datei pd.extract in UTF-8-Kodierung mit den Datenfeldern der Personendaten und des Artikels aus dem sie stammen angelegt. Die Reihenfolge der Datenfelder ist folgende:

1 pd_id Interne Datenbank-ID des Artikels
2 pd_article Name des Artikels
3 pd_name NAME der Person
4 pd_alternative ALTERNATIVNAMEN der Person
5 pd_description KURZBESCHREIBUNG der Person
6 pd_born GEBURTSDATUM
7 pd_born_in GEBURTSORT
8 pd_died STERBEDATUM
9 pd_died_in STERBEORT
10 pd_pnd PND-Nummer

Bei Artikeln mit mehreren Personendaten oder mehreren PND-Nummern wird nur jeweils die erste Vorlage ausgewertet und eine Warnung in pd.log geschrieben. Bei Artikeln, die nur PND-Nummer oder nur Personendaten enthalten, bleiben die übrigen Felder leer.

Transformation[Bearbeiten]

Die extrahierten und in Datenfelder aufgesplitteten Personendaten können anschließend mit Hilfe des Perl-Skriptes transform.pl bereinigt und transformiert werden; beispielsweise werden die Datumsangaben ausgewertet und PND-Nummer geprüft, und es wird versucht, den konkreten Ort zu bestimmen, in dem eine Person geboren oder gestorben ist:

 ./transform.pl < pd.extract > pd.tab

Die Aufbereitung der Daten führt zu einer Zunahme der Daten, wobei zusätzliche Redundanzen erzeugt werden. Im Gegensatz zum herkömmlichen Datenbankentwurf ist dies jedoch nicht negativ, sondern ein übliches Vorgehen beim Data-Warehousing, um anschließende Auswertungen möglich zu machen. Folgende Datenfelder werden zusätzlich zu den bei der Extraktion angelegten erzeugt.

11 pnd_nr geprüfte PND-Nummer
12 pnd_date zusätzliche Datumsangabe bei PND-Nummern (als Kommentar)
13 n_given Vorname (falls sich der Name in „Nachname, Vorname“ aufsplitten lässt)
14 n_surname Nachname (falls sich der Name in „Nachname, Vorname“ aufsplitten lässt)
15 b_place Artikel zum Geburtsort (falls eindeutig durch Wikilink gekennzeichnet)
16 d_place Artikel zum Sterbeort (falls eindeutig durch Wikilink gekennzeichnet)
17 b_day Geburtstag (1-31)
18 b_month Geburtsmonat (1-12)
19 b_year Geburtsjahr (Jahre vor Christus als negative Zahlen)
20 b_decade Geburtsjahrzehnt (zum Beispiel „1930“)
21 b_century Geburtsjahrhundert (zum Beispiel „20“)
22 b_year1 Erstes Jahr der Zeitspanne, in der die Geburt liegt (falls eine Spanne angegeben)
23 b_year2 Letztes Jahr der Zeitspanne, in der die Geburt liegt (falls eine Spanne angegeben)
24 b_note Zusatz zum Geburtstag (beispielsweise „vermutlich“ oder „um“)
25 d_day Todestag (1-31)
26 d_month Sterbemonat (1-12)
27 d_year Sterbejahr
28 d_decade Sterbejahrzehnt
29 d_century Sterbejahrhundert
30 d_year1 Erstes Jahr der Zeitspanne, in der der Todestag liegt (falls eine Spanne angegeben)
31 d_year2 Letztes Jahr der Zeitspanne, in der der Todestag liegt (falls eine Spanne angegeben)
32 d_note Zusatz zum Todestag

Das Datenfeld GEBURTSDATUM der Personendaten mit dem Wert „um 1181/1182“ würde beispielsweise in folgende Felder aufgeteilt:

pd_born = um 1181/1182
b_decade = 1180
b_year1 = 1181
b_year2 = 1182
b_century = 12
b_note = um

Die extrahierten und transformierten Personendaten werden mehr oder weniger regelmäßig auf die oben beschriebene Weise aus dem Datenbankdump erzeugt und sind unter  (Seite nicht mehr abrufbar; Suche im Webarchiv)[3] Vorlage:Toter Link/tools.wikimedia.de verfügbar.

Laden[Bearbeiten]

Die Tabulator-getrennten Datei können bereits mit einfachen Mitteln auch ohne Datenbank ausgewertet werden. Beispielsweise liefert folgender Aufruf eine Liste aller geprüften PND-Nummern und den dazugehörigen Artikeln:

awk -F '\t' '// {if ($11) print $11" "$2}' < pd.tab

Umfangreichere Auswertungen sind allerdings besser in einer SQL-Datenbank möglich. Die Datei pd-schema.sql enthält das  (Seite nicht mehr abrufbar; Suche im Webarchiv)[4] Vorlage:Toter Link/wikimeta.de Datenbankschema für die Tabelle pd, in das die Daten sehr schnell mit einem bulk insert geladen werden können.

LOAD DATA LOCAL INFILE 'pd.extract' INTO TABLE pd

Auswertung[Bearbeiten]

Verschiedene Auswertungen der Personendaten und PND-Links werden unter Hilfe:Personendaten/Auswertung gesammelt. Weitere Beiträge sind erwünscht!