Der zweite Monat Remove NA: ein Update

Drei Aspekte aus dem zweiten Monat des Projekts Remove NA:

Extraktion von Entitäten

Im zweiten Monat habe ich mich intensiv mit der Extraktion von Entitäten auseinander gesetzt. Die Mitglieder:innen des Forums haben eine detaillierte Chronik erstellt. Darin ist in mehr als 230 Punkten die queere Geschichte Münchens aufgelistet. Das ist ein sehr dichter Text voller Zeitangaben, Orten, Personen, Organisationen.

Ein Beispiel:

Solche kleinen Absätze sind keine strukturierten Daten. Dazu brauche ich den Absatz zur Klappe am Holzplatz in so einer Form (schematische Darstellung):

Schematische Zusammenänge des Chronikeintrags zur Klappe am Holzplatz.

Umgesetzt habe ich dieses Annotieren mit rubrix, einem Framework geschrieben in Python, um die Aufgabe des Datenlabeln zu unterstützen. Das hat ganz gut geklappt: Einen Pandas dataframe kann man leicht in die lokale Webapp einspielen, annotieren oder die Ergebnisse eines Modells validieren und dann diese manuellen Entscheidungen wieder zurück in einen pandas dataframe holen.

Herkömmliche Modelle, die Entitäten in Fließtexten erkennen, arbeiten mit vier verschiedenen Möglichkeiten: Organisation, Person, Location und Misc (Sonstiges). Das hat mich etwas in Schwierigkeiten gebracht, denn für eine möglichst detaillierte Modellierung der Daten sind diese vier Gruppen viel zu grob. Wenn ich schon händisch drüber gehe, dann will ich das granularste Ergebnis, das möglich ist. So ergaben sich insgesamt 23 verschiedene Labels, die aus zwei Quellen kamen:

  1. Händisches Annotieren, etwa von EVENTS, PERSONEN, LAW, PUBLICATIOn etc.
  2. Regelbasiertes Extrahieren von Addressen und verschiedensten Zeitangaben (Jahr, Datum, „Zwischen 1933 und 1945“) mittels Spacy Entitiy Ruler. Die Zeitangaben habe ich erstmal nicht aggregiert, ich erhoffe mir daraus automatisiertes und trotzdem feines Datenmodellieren.
LabelQuelle
ADREntity Ruler
AWARDAnnotation
CITYAnnotation
CLUBAnnotation
COUNTRYAnnotation
DATEEntity Ruler
DATE_BETWEENEntity Ruler
DATE_DECADEEntity Ruler
DATE_SINGLEEntity Ruler
DATE_SINGLE_WITHOUT_DAYEntity Ruler
DATE_STARTEntity Ruler
DATE_YEAREntity Ruler
DISTRICTAnnotation
EVENTAnnotation
LAWAnnotation
LOCAnnotation
MOVEMENTAnnotation
ORGAnnotation
PARTYAnnotation
PERAnnotation
PUBLICATIONAnnotation
SLOGANAnnotation
Tabelle zur NER von Chronikeinträgen.

Wer Texte annotiert, will auch Modelle nachtrainieren. Auch ich – auch wenn mir nach Gesprächen mit einer kundigeren Frau schon klar war, dass das nicht recht klappen wird: zu wenige Trainingsdaten, insbesondere wegen der Gruppen, die ich aber nochmal aggiert habe.

Durchgeführt habe ich es dennoch: Hier das Notebook und hier dazugehörige Doku, inkl. Regeln für den Entitiy Ruler.

Am Ende habe ich nun aber alle Entitäten aus den 233 Chronikeinträgen extrahiert und mit internen IDs in der Datenbank gespeichert. Das obige Beispiel zur Klappe am Holzplatz sieht als plaine Tabelle so aus:

Damit lässt sich schob einiges machen…

Entitäten finden, Duplikate vermeiden

Wie schon im Post für die ersten vier Wochen beschrieben, besteht eine Aufgabe stets daraus alle neuen Entitäten, etwa aus der Chronik, an die bisherigen anzufügen, ohne Duplikate zu erstellen. Der schematische Ablauf nach drei Iterationen sieht nun so aus:

Schematischer Ablauf der Entity Disambiguation.

Einige Duplikate, insbesondere was Abkürzungen betrifft, lassen sich so aber nicht finden. Ein Beispiel: Dass der Verein für sexuelle Gleichberechtigung die identische Entität wie VSG ist, muss ich irgendwie explizit festlegen.

Kollaboration mit Factgrid

Nach meinem Zwischenbericht des erstens Monats hat sich Kontakt mit Olaf Simons ergeben. Er ist der Gründer und Kopf hinter Factgrid, einer Wikibase-Instanz für historische Projekte. Von Illuminaten über die strukturierte Erfassung aller Personen und Orte in der Bibel und dem Koran oder Fundorten von Keilschrift-Artefakten über die Vollerfassung des Paris‘ im Jahr 1820 treffen alle möglichen Zeiten, Orte und Inhalte in einer Datenbank zusammen.

Factgrid ist nicht auf akademische Projekte beschränkt, deshalb ist jetzt auch Remove NA Teil davon. Die Vorteile liegen auf der Hand: keine eigene Installation und v.a. die Betreuung von Wikibase notwendig, Kollaboration mit anderen Projekten, eine bestehende kleine Community und die Sicherheit, dass die Plattform eine Weile bestehen wird.

Die ersten Daten habe ich modelliert und mit intensiver Support von Olaf Simons (Danke nochmal dafür!) in den letzten Tagen über Quickstatements importiert.

Eine Liste von explizit homosexuellen Lokalen in München, die mit SPARQL abgefragt werden und auf einer Karte dargestellt:

Wenn etwas explizit homosexuell ist, dann wird die Eigenschaft „Zielgruppe“ vergeben. Die weichere Version davon ist „Treffpunkt von…“.

Das wird jetzt in den kommenden Tagen meine Hauptaufgabe werden: Alle bisherigen internen Daten zu modellieren und in Factgrid zu laden, am besten bereits mit Verweisen auf GND oder Wikidata. Wie immer wird es dabei eine Abwägung geben zwischen der Massenbearbeitung und der Berücksichtigung von Einzelfällen gehen.

Entitäten verbinden

Um dezentrale Datensätze miteinander zu verbinden, braucht es IDs. Die zwei wichtigsten für mich: Wikidata und die Gemeinsame Normdatei (GND). Die Daten der GND lassen sich programmatisch über die API von lobid abfragen.

Ich fragte also in mehreren Schritten nach den Entitäten in der internen Datenbank bei lobid. Etwa bei Büchern, von denen ich die ISBN-Nummer habe und mit dann daraus die GND-ID des Verlags oder Autor:innen hole. Oder den Namen der Verlage und ich gebe die Bedingung mit, dass das Ergebnis eine Körperschaft sein muss und die GND Subject Category „Buchwissenschaft, Buchhandel“. Ein Skript findet sich dazu hier im Repo. Technisch interessant ist dabei, dass ich jq genutzt habe, um die für mich relevanten Einträge aus der json Response herauszuziehen. Mehr dazu und die konkreten Commands in der technischen Doku.

Wie geht’s weiter?

Im Fokus: Datenmodellierung des Bibliothekbestands und der Chronik und deren Import in Factgrid.

Schreibe einen Kommentar