udpipe: NLP Toolkit in R

Natural Language Processing ist die automatisierte Verarbeitung von Texten durch den Computer.

Das Vorgehen ist für die meisten Anwendungen ähnlich:

1) Texte sammeln

2) Token (Wörter, n-Gramme, Buchstaben, Sätze) extrahieren

3) Vorverarbeitung der Token

4) Analyse


Dieser Beitrag beschäftigt sich mit einem Paket, dass alle 4 Punkte übernimmt: udpipe.


Udpipe kann sich mit spacy vergleichen lassen, einem sehr beliebten Python-Paket für NLP. Für spacy gibt es ebenfalls ein R-Paket.

Die Gruppe hinter udpipe hat einen [Vergleich zwischen den beiden Paketen](https://www.bnosac.be/index.php/blog/75-a-comparison-between-spacy-and-udpipe-for-natural-language-processing-for-r-users) veröffentlicht. So unterstützt udpipe mehr Sprachen, ist etwas genauer, allerdings auch langsamer.


Mit udpipe kann der Text in Token aufgetrennt werden. Die Token können dann bezüglich

der Wortart und der Stammwörter untersucht werden. Sowie weitere Wort-bezogene Infomationen können erzeugt werden.

Dies kann in einem Rutsch erfolgen und genau das werden wir nun machen.


Text für udpipe vorbereiten


Zunächst laden wir das Paket udpipe und die übrigen Pakete, welche hier genutzt werden.



library(udpipe)
library(lattice)
library(igraph)
library(ggraph)
library(ggplot2)

Tokenization, Lemmatization und POS-Tagging


Wir untersuchen einen Artikel von Wikipedia zum Thema Computerlinguistik.


NLP_Wiki <- "Computerlinguistik

In der Computerlinguistik (CL) oder linguistischen Datenverarbeitung (LDV)[1] wird untersucht, wie natürliche Sprache in Form von Text- oder Sprachdaten mit Hilfe des Computers algorithmisch verarbeitet werden kann. Sie ist Schnittstelle zwischen Sprachwissenschaft und Informatik. In der englischsprachigen Literatur und Informatik ist der Begriff Natural language processing (NLP) gebräuchlich. 

Geschichte

Computerlinguistik lässt sich als Begriff (oder dessen Umschreibung) in die 1960er Jahre zurückverfolgen.[2] Mit den Anfängen der künstlichen Intelligenz war die Aufgabenstellung schon nahegelegt. Chomskys Syntactic Structures von 1957 präsentierte die Sprache in einem entsprechend passenden neuen formalen Gerüst. Hinzu kamen die Sprachlogiken von Saul Kripke und Richard Montague. Die teilweise aus dem US-Verteidigungsbudget sehr hoch geförderten Forschungen brachten jedoch nicht die erhofften Durchbrüche. Besonders die Koryphäen Chomsky und Weizenbaum dämpften die Erwartungen an Automatisierungen von Sprachübersetzung. Der Wende von behavioristischen Wissenschaftskonzeptionen zu mentalistischen (Chomsky) folgten umfassende Konzipierungen in den Kognitionswissenschaften.

In den siebziger Jahren erschienen zunehmend häufiger Publikationen mit dem Begriff Computerlinguistik im Titel. Es gab bereits finanziell aufwändige Versuche exegetischer Anwendungen (Konkordanzen, Wort- und Formstatistik), aber auch schon größere Projekte zur maschinellen Sprachanalyse und zu Übersetzungen. Die ersten Computerlinguistik-Studiengänge in Deutschland wurden an der Universität des Saarlandes und in Stuttgart eingerichtet. Die Computerlinguistik bekam mit der Verbreitung von Arbeitsplatzrechnern (PC) und mit dem Aufkommen des Internets neue Anwendungsgebiete. Im Gegensatz zu einer Internetlinguistik, die insbesondere menschliches Sprachverhalten und die darüber induzierten Sprachbildungen im und mittels Internet untersucht, entstand in der Computerlinguistik eine stärker informatisch-praktische Ausrichtung. Doch gab das Fach die klassischen philosophisch-linguistischen Fragen nicht ganz auf und wird heute in theoretische und praktische Computerlinguistik unterschieden. 

Gegenwärtige Aufgabe der Computerlinguistik

    „Computerlinguistik erforscht die maschinelle Verarbeitung natürlicher Sprachen. Sie erarbeitet die theoretischen Grundlagen der Darstellung, Erkennung und Erzeugung gesprochener und geschriebener Sprache durch Maschinen.“

– Universität München

Das Saarbrücker Pipelinemodell

Computer sehen Sprache entweder in der Form von Schallinformation (wenn die Sprache akustisch vorliegt) oder in der Form von Buchstabenketten (wenn die Sprache in Schriftform vorliegt). Um die Sprache zu analysieren, arbeitet man sich schrittweise von dieser Eingangsrepräsentation in Richtung Bedeutung vor und durchläuft dabei verschiedene sprachliche Repräsentationsebenen. In praktischen Systemen werden diese Schritte typischerweise sequentiell durchgeführt, daher spricht man vom Pipelinemodell,[4] mit folgenden Schritten:

Spracherkennung
    Falls der Text als Schallinformation vorliegt, muss er erst in Textform umgewandelt werden.
Tokenisierung
    Die Buchstabenkette wird in Wörter, Sätze etc. segmentiert.
Morphologische Analyse
    Personalformen oder Fallmarkierungen werden analysiert, um die grammatische Information zu extrahieren und die Wörter im Text auf Grundformen zurückzuführen, wie sie z. B. im Lexikon stehen.
Syntaktische Analyse
    Die Wörter jedes Satzes werden auf ihre strukturelle Funktion im Satz hin analysiert (z. B. Subjekt, Objekt, Modifikator, Artikel etc.).
Semantische Analyse
    Den Sätzen bzw. ihren Teilen wird Bedeutung zugeordnet. Dieser Schritt umfasst potentiell eine Vielzahl verschiedener Einzelschritte, da Bedeutung schwer fassbar ist.
Dialog- und Diskursanalyse
    Die Beziehungen zwischen aufeinander folgenden Sätzen werden erkannt. Im Dialog könnten das z. B. Frage und Antwort sein, im Diskurs eine Aussage und ihre Begründung oder ihre Einschränkung.

Es ist allerdings nicht so, dass sämtliche Verfahren der Computerlinguistik diese komplette Kette durchlaufen. Die zunehmende Verwendung von maschinellen Lernverfahren hat zu der Einsicht geführt, dass auf jeder der Analyseebenen statistische Regelmäßigkeiten existieren, die zur Modellierung sprachlicher Phänomene genutzt werden können. Beispielsweise verwenden viele aktuelle Modelle der maschinellen Übersetzung Syntax nur in eingeschränktem Umfang und Semantik so gut wie gar nicht; stattdessen beschränken sie sich darauf, Korrespondenzmuster auf Wortebene auszunutzen.[5]

Am anderen Ende der Skala stehen Verfahren, die nach dem Prinzip Semantics first, syntax second arbeiten. So baut die auf dem MultiNet-Paradigma beruhende, kognitiv orientierte Sprachverarbeitung auf einem semantikbasierten Computerlexikon auf, das auf einem im Wesentlichen sprachunabhängigen semantischen Kern mit sprachspezifischen morphosyntaktischen Ergänzungen beruht.[6] Dieses Lexikon wird beim Parsing von einer Wortklassen-gesteuerten Analyse zur unmittelbaren Erzeugung von semantischen Strukturen eingesetzt.
Beispiele für Probleme der Sprachverarbeitung

    Auflösung syntaktischer Mehrdeutigkeiten. In einigen Fällen lässt sich ein Satz auf mehrere Arten analysieren und deuten. Die richtige auszuwählen, erfordert manchmal semantische Information über den Sprechakt und die Intention der Sprecher, mindestens jedoch statistisches Vorwissen über das gemeinsame Auftreten von Wörtern. Beispiel: „Peter sah Maria mit dem Fernglas“ – hier ist nicht zwangsläufig klar, ob Peter Maria gesehen hat, die ein Fernglas in der Hand hielt, oder ob Peter Maria mit Hilfe eines Fernglases sehen konnte.
    Bestimmen der Semantik. Die gleiche Wortform kann je nach Kontext eine andere Bedeutung aufweisen (vergleiche Homonym, Polysem). Man muss die für den Kontext zutreffende Bedeutung auswählen. Auf der anderen Seite braucht man Formalismen zur Repräsentation von Wortbedeutungen.
    Erkennen der Absicht einer sprachlichen Äußerung (siehe Pragmatik). Manche Sätze sind nicht wörtlich gemeint. Beispielsweise erwartet man auf die Frage „Können Sie mir sagen, wie spät es ist?“ nicht eine Antwort wie „Ja“ oder „Nein“, sondern bittet damit um Auskunft über die Uhrzeit.

Anwendungen in der Praxis

Praktische Computerlinguistik ist ein Begriff, der sich im Lehrangebot einiger Universitäten etabliert hat. Solche Ausbildungsgänge sind nahe an konkreten Berufsbildern um die informatisch-technische Wartung und Entwicklung von sprachverarbeitenden Maschinen und ihrer Programme. Dazu gehören zum Beispiel:

    Die Unterstützung des Computerbenutzers bei der Textverarbeitung, beispielsweise die automatische Korrektur von Tipp- und Rechtschreibfehlern, die Prüfung auf grammatische Richtigkeit oder die Umwandlung in Bedeutungszeichen in Japanisch oder Chinesisch.
    Das Auffinden von Informationen in großen sprachlichen Datenmengen (Text Mining, Informationsextraktion), von der automatischen Suche nach relevanten Textstellen (Information Retrieval und Suchmaschinen) bis hin zur direkten Beantwortung von Fragen (Question Answering (QA)).
    Die Unterstützung beim Übersetzen von Texten in eine andere Sprache (Computer-aided Translation (CAT)) oder auch die vollständige automatische Übersetzung.
    Die Verarbeitung von gesprochener Sprache (Spracherkennung und Sprachsynthese), zum Beispiel bei digitalen Diktiergeräten oder Lesegeräten für Blinde.
    Die Generierung von natürlichsprachlichen Texten wie Wegbeschreibungen oder Wettervorhersagen.
    Die Aufbereitung von sprachlich vorliegenden Daten, beispielsweise die automatische Verschlagwortung von Literatur, die Anfertigung von Registern und Inhaltsverzeichnissen, die Herstellung von Zusammenfassungen und Abstracts.
    Die Unterstützung von Autoren beim Verfassen von Texten, zum Beispiel das Finden des treffenden Ausdrucks oder der richtigen Terminologie, etwa bei der Verwendung eines kontrollierten Vokabulars in der technischen Dokumentation.
    Die sprachliche Interaktion mit einem Benutzer im Rahmen eines Dialogsystems, z. B. bei telefonischen Auskunftsdiensten, aber auch zur Sprachsteuerung technischer Geräte oder Computer.
    Die automatisierte Messung von persönlichen Stärken anhand natürlicher Gespräche wie offenen Interviews, Bewerbungsgesprächen, Talkshows, Podiumsdiskussionen oder Gruppendiskussionen."


Udpipe benötigt die UTF-8-Kodierung bei Texten, um mit Umlauten und Sonderzeichen arbeiten zukönnen. Daher prüfen wir zunächst, ob der Text in UTF-8 vorliegt:

Encoding(NLP_Wiki)

Das Ergebnis der Prüfung ist "latin1". Wir wandeln daher den Text in UTF-8 um.

NLP_Wiki <- iconv(NLP_Wiki, from = "latin1", to = "UTF-8")

Nun können wir das Model herunterladen und den Text in Token (Wörter), Stammworte und Part-of-Speech analysieren lassen.

udmodel <- udpipe_download_model(language = "german")
udmodel <- udpipe_load_model(file = udmodel$file_model)
x <- udpipe_annotate(udmodel, x = NLP_Wiki)
x <- as.data.frame(x)
head(x)


Ausschnitt des mit udpipe erzeugten Dataframes

Analyse der Wortarten


Nun haben wir den Text in Wörter mit ihrem Wortstamm und ihrer Wortart aufgeteilt. Mit diesen Informationen können wir uns Ansehen, welche Wörter und Wortarten im Text herausstechen.

stats <- txt_freq(x$upos)
stats$key <- factor(stats$key, levels = rev(stats$key))
barchart(key ~ freq, data = stats, col = "cadetblue", 
         main = "UPOS (Universal Parts of Speech)\n frequency of                                        occurrence", 
         xlab = "Freq")

Häufigkeitsverteilung der Wortarten im Text

Schlagworte herausfiltern

Die Schlagworte kann man in ähnlicher Weise extrahieren. Dazu nutzen wir hier ein POS-Muster. Wir suchen spezifisch nach Phrasen mit Nomen und Verben.

x$phrase_tag <- as_phrasemachine(x$upos, type = "upos")
stats <- keywords_phrases(x = x$phrase_tag, term = tolower(x$token), 
                          pattern = "(A|N)*N(P+D*(A|N)*N)*", 
                          is_regex = TRUE, detailed = FALSE)
#stats <- subset(stats, ngram > 1 & freq > 3)
stats$key <- factor(stats$keyword, levels = rev(stats$keyword))
barchart(key ~ freq, data = head(stats, 20), col = "cadetblue", 
         main = "Keywords - simple noun phrases", xlab = "Frequency")

Analyse der Schlagwörter mittels Nomen-Phrasen

Andere Schlagwort-Algorithmen stehen ebenfalls zur Verfügung. Hier nutzen wir RAKE (Rapid Automatic Keyword Extraction)

stats <- keywords_rake(x = x, term = "lemma", group = "doc_id", 
                       relevant = x$upos %in% c("NOUN", "ADJ"))
stats$key <- factor(stats$keyword, levels = rev(stats$keyword))
barchart(key ~ rake, data = head(stats, 20), col = "cadetblue", 
         main = "Keywords identified by RAKE", 
         xlab = "Rake")

Analyse der Schlagwörter mittels RAKE

Kookkurrenzen des Textes finden


Und zum Schluss sehen wir uns noch kurz die Kookkurrenzen des Textes an, in denen Nomen und Adjektive zusammen genutzt werden:

cooc <- cooccurrence(x = subset(x, upos %in% c("NOUN", "ADJ")), 
                     term = "lemma", 
                     group = c("doc_id", "paragraph_id", "sentence_id"))

Nun visualisieren wir die Kookkurrenzen als Netzwerk:

wordnetwork <- head(cooc, 30)
wordnetwork <- graph_from_data_frame(wordnetwork)
ggraph(wordnetwork, layout = "fr") +
  geom_edge_link(aes(width = cooc, edge_alpha = cooc), edge_colour = "pink") +
  geom_node_text(aes(label = name), col = "darkgreen", size = 4) +
  theme_graph(base_family = "Arial") +
  theme(legend.position = "none") +
  labs(title = "Cooccurrences within sentence", subtitle = "Nouns & Adjective")

Kookkurrenzen im Text

Es wird deutlich, dass der Text sich mit Computerlinguistik und Sprache beschäftigt. Dies haben wir bereits in den Schlagworten gesehen. Mit den Kookkurrenzen sehen wir zudem, dass es um Informationen, bzw. Daten geht und welche Formen von Sprache für die Computerlinguistik interessant sind.


Fazit


Udpipe ist ein sehr mächtiges Paket im Bereich des Natural Language Processing. Es liefert sehr gute Ergebnisse, wenn es um das Tagging von Wörtern geht. Der Output kann verwendet werden um verschiedene Analysen durchzuführen. Beispielsweise Kookkurrenzen herausfiltern oder Schlagworte generieren.