Mit sogenanntem Natural Language Processing wird versucht, dass der Computer unsere «normale Sprache» verstehen kann. Dadurch können grosse Mengen von unstrukturierten Texten automatisch ausgewertet werden. Dies wird z.B. in den sozialen Medien eingesetzt, um Beiträge zu kategorisieren oder in der Künstlichen Intelligenz bei Lernvorgängen.

# Einführung

Das Python-Modul spaCy https://spacy.io (opens new window)

Aufgabe «Vorbereitung»

  1. Starte Thonny und installiere das Modul spaCy (siehe Thonny, Paketverwaltung)
  2. Installiere das Modul «Deutsch»:
    • gehe oben im Menu auf Extras und wähle System Shell
    • gib den folgenden Code ein (erste Zeile, zweite Zeile nur wenn es bei der ersten eine Fehlermeldung gibt)
python -m spacy download de_core_news_sm
python3 -m spacy download de_core_news_sm
1
2
  1. Teste nun ob du die Sprache «Deutsch» laden kannst, indem du das folgende Python-Skript ausführst:
import spacy

nlp = spacy.load("de_core_news_sm")
1
2
3

Jetzt bist du für die weiteren Beispiele vorbereitet!

# Tokens

spaCy erkennt und kategorisiert sogenannte tokens. Das folgende Skript gibt diese für den Satz «Willhelm Tell lebte am Vierwaldstättersee.» aus:

import spacy

nlp = spacy.load("de_core_news_sm")
text = "Willhelm Tell lebte am Vierwaldstättersee."
doc = nlp(text)

for token in doc:
    print(token.text, token.lemma_, token.pos_, token.tag_, token.dep_)
1
2
3
4
5
6
7
8
text lemma_ pos_ tag_ dep_
Willhelm Willhelm PROPN NE pnc
Tell Tell PROPN NE sb
lebte leben VERB VVFIN ROOT
am am ADP APPRART mo
Vierwaldstättersee Vierwaldstättersee NOUN NN nk
. . PUNCT $. punct

Dabei wird z.B. die Stammform des Verbs in lemma_ ausgegeben.
pos_ steht für die grobe Unterteilung der part-of-speech, z.b. steht PROPN für «proper noun». (Details (opens new window)).
tag_ ist eine feinere Unterteilung von part-of-speech. Beim Verb kommt dort auch die Zeit rein. (Details (opens new window))
dep_ steht für dependancy und liefert Infos zur Abhänigkeit im Kontext. (Details (opens new window))

Aufgabe «Tokens»

  • Teste das obenstehende Programm aus
  • ändere die Zeit des analysierten Satzes auf Zeile 4 wie folgt ab:
    Willhelm Tell hat am Vierwaldstättersee gelebt.
  • Vergleiche den neuen Output mit der obenstehenden Tabelle

# Entitäten

spaCy kann auch benannte Entitäten erkennt, wie Personen oder Orte:

import spacy

nlp = spacy.load("de_core_news_sm")
text = '''
Schiller verwebt drei Handlungsstränge:
Im Mittelpunkt steht die Sage von Wilhelm Tell mit dem Apfelschuss und der Befreiung vom Tyrannen Gessler als einem Akt von Notwehr.
Der geschichtliche Hintergrund wird durch die Handlung um den eidgenössischen Bund und die Befreiung der Schwyz (Schweiz) gebildet.
Die dritte Handlung wird durch die Liebesgeschichte der Berta von Bruneck mit Ulrich von Rudenz bestimmt, der sich mit seinem Volk versöhnt und ihm die Freiheit schenkt.
Die letzten beiden Handlungsstränge verknüpfen sich am Schluss miteinander, während zwischen der Tell-Geschichte und dem anderen Geschehen nur eine lose Verbindung besteht.
'''
## Quelle: https://de.wikipedia.org/wiki/Wilhelm_Tell_(Schiller)

doc = nlp(text)

for ent in doc.ents:
    print(ent.text, ent.label_)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
text label_
Wilhelm Tell PER
eidgenössischen Bund MISC
Schwyz LOC
Schweiz LOC
Berta von Bruneck LOC
Ulrich von Rudenz PER
Tell-Geschichte MISC

label_ beschreibt die erkannte Entität (Details (opens new window))

# Ähnlichkeit

Es kann auch die Ähnlichkeit zwischen zwei Wörtern abgefragt werden. Dazu muss aber ein grösseres Sprach-Paket geladen werden, für Deutsch reicht de_core_news_sm nicht aus – man benötigt de_core_news_md! (Wie im Kapitel Einführung erläutert installieren.)

import spacy

nlp = spacy.load("de_core_news_md")
tokens = nlp("Hund Katze Banane")
   
for token1 in tokens:
    for token2 in tokens:
        print(token1.text, token2.text, token1.similarity(token2))
1
2
3
4
5
6
7
token1 token2 similarity
Hund Hund 1.0
Hund Katze 0.6760826
Hund Banane 0.24603654
Katze Hund 0.6760826
Katze Katze 1.0
Katze Banane 0.3822762
Banane Hund 0.24603654
Banane Katze 0.3822762
Banane Banane 1.0

# Andere Sprachen

Zuerst muss die gewünschte Sprache installiert werden:

  1. Thonny öffnen und oben im Menu auf Extras -> System-Shell gehen
  2. Dort für die gewünschte Sprache die entsprechende Zeile eintippen:
python -m spacy download en_core_web_sm
python -m spacy download fr_core_news_sm
python -m spacy download it_core_news_sm
python -m spacy download es_core_news_sm
1
2
3
4

wenn es einen Fehler gibt, dann schreibe statt python python3

python3 -m spacy download en_core_web_sm
python3 -m spacy download fr_core_news_sm
python3 -m spacy download it_core_news_sm
python3 -m spacy download es_core_news_sm
1
2
3
4

Jetzt solltest du die entsprechende Sprache im Python laden können, z.B. Spanisch:

import spacy

nlp = spacy.load("es_core_news_sm")
1
2
3

Aufgabe «Sprache»

Installiere «deine» Sprache und teste die beiden bestehenden Beispiele zu tokens und entites mit Texten in der neuen Sprache aus.

# Visualisierung

spaCy bietet auch die Möglichkeit, gewisse Dinge grafisch darzustellen. Dabei verwendet man am einfachsten den eingebauten Webserver: Mit den Befehl ?displacy.serve() wird dieser gestartet. Man kann dann auf den in der Shell angezeigten Link klicken, um die Darstellung über den Browser aufzurufen.

# Abhängigkeiten

Die Abhängigkeiten der token eines Textes lassen sich wie folgt darstellen:

Code
import spacy
from spacy import displacy

nlp = spacy.load("de_core_news_sm")

print('Bitte gib einen kurzen Satz ein:')
text = input()
doc = nlp(text)

displacy.serve(doc, style="dep")
1
2
3
4
5
6
7
8
9
10

Diese Darstellungsform eignet sich natürlich nur für kleinere Texte.

# Entities

Der Text mit den erkannten entites lässt sich wie folgt grafisch darstellen:

Code
import spacy
from spacy import displacy

nlp = spacy.load("de_core_news_sm")

text = '''
Durch die Eröffnung vom Gotthardpass am Anfang des 13.Jahrhunderts wurde die Region um die Waldstätte (heute Vierwaldstättersee) auch strategisch und wirtschaftlich interessant. Deshalb verstärkten die Habsburger ihren Besitzanspruch auf das Gebiet rund um den Vierwaldstättersee. Sie schickten Vögte ins Land welche die Urner, Schwyzer und Unterwaldner unterdrückten und massiv Steuern abkassierten.
Das liessen sich die aufrechten Männer von Uri, Schwyz und Unterwalden nicht tatenlos bieten. Auf dem Rütli wurde 1291 der Bund der Urkantone durch den Rütlischwur besiegelt. Unter Führung von Werner Stauffacher aus Schwyz, Arnold Melchtal aus Unterwalden und Walter Fürst aus Uri verbinden sich die drei Waldstädte um die gewalttätigen österreichischen Landvögte Gessler und Landenberg zu vertreiben.
Wilhelm Tell ist zu jener Zeit Bergbauer und lebt im steilen unwegsamen Schächental (Kanton Uri). Geboren in Bürglen, lebt er dort auf dem "Schochen Land", das er von seinem Vater nach dessen Tod übernommen hat. Das steile "Bergheimätli", welches der kräftig gebaute Tell mit seiner Familie bewirtschaftet, ist umgeben von hohen Bergen mit weiss leuchtenden Schneespitzen. Wilhelm Tells Arbeit ist hart. Aber es reicht um alle hungrigen Mäuler im Haus zu stopfen. Um immer genug Essen auf dem Tisch zu haben ist der Willi (wie der von seinen Freunden genannt wurde) öfters auf der Jagd anzutreffen. Mit seiner Armbrust ist er ein exzellenter Schütze. Wilhelm Tell geniesst den Ruf - weit über sein Dorf hinaus - der beste und treffsicherste Armbrustschütze weit und breit zu sein. Es gibt auf der Jagd keine flinke Gämse und kein Hacken schlagender Hase, der sich nicht vor Tells Armbrust und dessen Pfeil-Geschoss fürchtet.
Trotz des kargen Lebens ist Wilhelm Tell zufrieden mit sich und der Welt. Seine Frau Hedwig hatte ihm zwei prächtige Söhne mit dem Namen Walter und Wilhelm geschenkt. Die Jungs bereiteten dem Wilhelm Tell und seiner Frau Hedwig viel Freude.
Wie immer einmal jeden Monat steigt Wilhelm Tell hinab ins Tal um seine Einkäufe im nahen Altdorf zu tätigen.
Heute begleitet sein Sohn Walter den Vater Tell zum nahe gelegenen Altdorf.
Wie er von seinen Nachbarn erfahren hat, regiert Hermann Gessler, der Reichsvogt in Schwyz und Uri in Altdorf immer härter und brutaler. Das sei ein scharfer Hund. Der Vogt ist ein grosser Unterdrücker gegenüber dem Urner Volk. So denkt er sich immer wieder neue Misstaten aus um seine Untertanen zu quälen.
Auf dem Marktplatz in Altdorf angekommen herrscht reges Treiben rund um den Hauptplatz. Vereinzelt sind auch Soldaten des Vogts zu sehen.
Mitten auf dem Marktplatz steht neu eine Stange wo ein Hut drauf ist. Diesen Hut soll jeder Untertan des Vogtes grüssen so als ob der Vogt es persönlich anwesend sei. Doch Wilhelm Tell hält nichts von solch unsinnigen Gesetzen.
Er geht am Pfahl achtlos vorbei und kümmert sich nicht um den Hut des Landvogt Gesslers. Er wird unsanft von den Soldaten die den Hut auf dem Pfahl bewachen angehalten: "Hey Bauer grüsse deinen Landvogt!" Darauf entgegnet Wilhelm Tell: "Ich sehe nur einen Hut, kein Vogt Gessler hab ich da gesehen! Ich bin doch nicht Irre und grüss kein Hut!" Jetzt sind die Soldaten zornig und packen den sich nicht wehrenden Wilhelm Tell und halten ihn fest. In der Zwischenzeit hat sich ein Volksauflauf rund um Wilhelm Tell gebildet.
Der herbeigerufene Hermann Gessler erscheint nach kurzer Zeit und stellt den widerspenstigen Bauer zur Rede.
Der Vogt erkennt den Bauer und guten Schützen Tell. Er fragt: "Tell warum missachtest du meine Gesetze?"
Tell: "Warum soll ich eine Stange mit Hut grüssen. Das ist doch Schwachsinn!"
Erzürnt über solche Dreistigkeit befiehlt der Landvogt Gessler die erneute Ergreifung und Verhaftung von Wilhelm Tell. Dies lässt Wilhelm Tell alles über sich ergehen ohne sich zu wehren. Das erzürnt den Landvogt Gessler noch mehr. Erst jetzt erkennt der habsburgische Vogt das Tell seinen Sohn Walter dabei hat. Auch den kleinen Walter lässt Landvogt Gessler ergreifen. Um Tell aus der Reserve zu locken ersinnt der tyrannische Landvogt sogleich ein makaberes Spiel.
An Tell gerichtet: "Tell du bist doch ein Weiterum bekannter Meisterschütze. Du kannst deine Freiheit mit deiner Armbrust mit einem guten Schuss erlangen." Gessler langt in die Satteltasche und zieht einen roten saftigen Apfel heraus.
"Du musst nur diesen Apfel treffen." Dazu denkt sich der Meisterschütze Wilhelm Tell, "das schaff ich doch mit Links".
Doch Tell hat nicht mit dem dunklen Gedankengang von Gessler gerechnet.
Dieser befiehlt Tells Sohn Walter sich unter die 80 Meter entfernte Linde zu stellen. Dann geht der Landvogt zu Walter und legt den Apfel auf dessen Kopf. Dann spricht Gessler zu Tell gewandt: "Dieser Apfel auf dem Kopf deines Sohn Walter ist dein Ziel. Solltest du daneben schiessen wird dein Sohn sterben. Andernfalls wenn du den Apfel triffst bist du und dein Sohn ein freier Mann."
Wilhelm Tell dem nichts anderes übrig bleibt nimmt seine Armbrust zur Hand. Er nimmt Zwei Peile aus dem Köcher. Den einen legt er griffbereit neben sich, und den andern spannt er in die Armbrust ein. Dann hebt er die Armbrust an und zielt auf den Apfel auf Walters Kopf. Der sonst so sichere Armbrustschütze Wilhelm Tell zittert und vor seinen Augen verblasst und flimmert der Apfel. Tell muss absetzen und zieht den zweiten Pfeil näher zu sich ran. Erneut setzt Wilhelm Tell die Armbrust an. Schweiss steht Tell auf der Stirn. Nach langem zielen zieht er den Abzug seiner Armbrust durch. Tells Pfeil zieht eine schnurgerade Bahn auf den Apfel zu. Tells Pfeil trifft den Apfel in der Mitte entzwei. Ein wahrer Meisterschuss.
Die Leute rundum Jubeln und freuen sich mit Tell. Dieser packt den zweiten Pfeil und will diesen unauffällig in seinem Köcher versorgen.
Gessler der sein Gesicht nicht verlieren will spricht zum Wilhelm Tell: "Gratulation! Ein guter Schuss Schütze Tell und wie versprochen bist du jetzt wieder ein freier Untertan. Doch lass mich erfahren was du mit dem zweiten Pfeil im Sinne hattest?"
Darauf angesprochen erwidert Tell: "Wenn mein erster Schuss fehl gegangen wäre und meinen Sohn Walter getroffen hätte, so hätte mein zweiter Pfeil dich ganz sicher getroffen, so wahr ich Tell heisse." Erzürnt ob solcher Dreistigkeit liess der zornige Landvogt Tell wieder ergreifen und erneut verhaften. Zu Tell gewandt sagt Gessler: "In meiner Burg in Küssnacht kannst du ob deiner kühnen Antwort nachdenken bis Dir die Haut auf deinen Knochen alt wird.
Gessler, der im Urnerland keine Freunde hat, will mit seinem Gefangenen Wilhelm Tell so rasch wie möglich Altdorf verlassen. Trotz Sturmwarnung wegen Föhn lässt Gessler sein Schiff in Flüelen klar machen. Gesslers Soldaten murren deshalb leise vor sich hin, aber segeln auf dem Vierwaldstättersee hinaus mit Ziel Richtung Küssnacht. Zusammen mit seinem Gefangenen Wilhelm Tell und seinen Soldaten segelt Hermann Gessler auf den schon aufgewühlten Vierwaldstättersee hinaus. Der angekündigte Föhnsturm zieht immer stärker auf. Schon bald müssen die Segel eingezogen werden, der Sturm ist zu stark. Gessler ist zu stolz, er will nicht zurückkehren nach Flüelen. Deshalb müssen die Schiffsleute und Soldaten alle Kraft in die Riemen der Ruder legen. Aber der Föhnsturm wird immer stärker und gewaltiger. Es scheint so, als ob die Natur sich gegen das kleine Schiff Gesslers verschworen hat. Das Schiff droht zu kentern. Die Schiffsleute und Soldaten schreien und zittern um Ihr Leben.
Hermann Gessler bekommt Panik und sieht sein bedrohtes Leben schon dahin schwinden. Er schreit zu Wilhelm Tell: "Tell du bist doch extrem kräftig ein guter Seemann. Rette uns, und gehe an die Ruder." Tell nickt nur unmerklich. Darauf lässt Gessler Wilhelm Tell losbinden. Dieser packt sofort das Ruder und schreit. Lasst uns das Ufer der Felsplatte am Axen ansteuern, dies ist unsere einzige Rettung." Die Seeleute und Soldaten unter der Führung von Wilhelm Tell rudern um Ihr Leben. Trotz sturmgepeitschten Wasser und mächtiger Wellen bei orkanartigem Föhn gelingt es Tell das Boot gegen das Ufer zu steuern.
Plötzlich, fast schon am Ufer der Axen Felsplatte, packt Wilhelm Tell seine Armbrust mit Köcher und springt mit einem gewaltigen Satz ans Ufer. Dabei stösst er das Schiff mit Gessler in die aufgewühlte See zurück.
Tell weiss das sein Leben jetzt keinen Pfifferling mehr wert ist, solange der Gessler noch lebt.
Er weiss was es geschlagen hat und er durchdenkt genau was zu tun ist. Wilhelm Tell kennt die Gegend hier genau. Manches Reh und Gämse hat er hier gejagt. Tell eilt sodann auf kürzestem Wege übers Gebirge. Sein Ziel ist Küssnacht am Rigi. Über Sisikon, Brunnen, Schwyz und Arth hetzt er zur "Hohlen Gasse" bei Küssnacht, wo er auf dem Landvogt abpasst. In seinem sicheren Versteck an der Hohlen Gasse bei Küssnacht wartet er. Wilhelm Tell weiss, durch diese hohle Gasse muss er kommen. Es führt sonst kein anderer Weg nach Küssnacht. Er legt sich dort auf die Lauer. Stunde um Stunde vergeht. Plötzlich taucht er auf.
Gessler, der dem stürmischen See doch noch entkommen war, kommt mit seinem Gefolge heran geritten. Tell legt den Pfeil in seiner Armbrust zurecht. Er zielt und drückt ab. Mit dem zweiten Pfeil, den er bereits in Altdorf in seinen Köcher gesteckt hatte, erschiesst Wilhelm Tell den tyrannischen Landvogt.
Tells heldenhafte Taten wurden schnell im ganzen Land um die Waldstätte bekannt.
Diese Tat stärkte die Bewegung für Freiheit und Unabhängigkeit in der Urschweiz.
Die Waldstätte von Tells Taten aufgerüttelt entledigte sich darauf seiner Vögte und war bis in die heutige Zeit ein freies und unabhängiges Volk.
Tell hat danach noch in der blutigen Schlacht bei Morgarten 1315 an vorderster Front für die Eidgenossen mitgekämpft. Dabei errangen die Eidgenossen von Uri Schwyz und Unterwalden einen grossen Sieg gegen das Ritterheer der Herzoge von Habsburg. Wilhelm Tell ist dann 1354 im Schächenbach nahe seinem Heim beim Versuch der Rettung eines Kindes zu Tode gekommen.
Wir können stolz auf unseren Wilhelm Tell sein.
Deshalb halten wir Wilhelm Tell in unserem Gedächtnis einen angemessenen Platz frei.
Hier endet die eigentliche Wilhelm Tell Geschichte. 
Doch der Kampf für die Freiheit geht weiter. Wo immer auf unserer Welt die Freiheit der Menschen unterdrückt wird, lodert der Wille für Freiheit der Menschen auf, und fordert das Ende ihrer Tyrannenmacht...
'''
# Quelle: https://www.tell.ch/schweiz/wilhelm-tell.htm

doc = nlp(text)
displacy.serve(doc, style="ent")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

Dies klappt auch für längere Texte.

# Ideen

Aufgabe «Projekt»

Schaue dir die unten ausgeführten Ideen an. Versuche etwas davon umzusetzen und selbständig auszubauen.

# eigenen Chatbot programmieren

  • Lass den Benutzer mit input() einen Satz eingeben.
  • Versuche diesen zu analysieren indem du den Satzaufbau analysierst
  • Stelle eine weitere Frage oder liefere eine Antwort, z.B. indem du das Verb oder das Substantiv verwendest
  • Versuche nicht allzu allgemein zu chatten. Beschränke dich auf ein Thema (Wetter, Schmerzen, Fussball, …)
Vorlage
import spacy

nlp = spacy.load("de_core_news_sm")
print("Hallo. Sag mir was du auf dem Herzen hast?")

while True:
    text = input()
    doc = nlp(text)

    subject = None
    feeling = None

    for token in doc:
        print(token.text, token.lemma_, token.pos_, token.tag_, token.dep_)
        if token.dep_ == "oa":
            subject = token.text
            break;
        if token.dep_ == "pd":
            feeling = token.text
            break;        
            
    if subject:
        print("Erzähl mir mehr über " + subject)
    elif feeling:
        print("Wieso fühlst du dich " + feeling)
    else:
        print("Ja, das kann ich nachvollziehen. Sonst noch was?")
        
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

# grössere Texte analysieren

Versuche grössere Texte zu analysieren. Du könntest z.B. Entitäten zählen und so von einem Text auf gewisse Dinge schliessen.

Im folgenden Beispiel wird ein Buch (opens new window) von der Seite gutenberg.org (opens new window) als Textdatei geladen und nach Enitäten analysiert: Dabei werden locations gezählt und am Schluss die am meisten vorkommenenden Orte ausgegeben:

Vorlage
import spacy
import requests
import collections

nlp = spacy.load("de_core_news_sm")

# Text von gutenberg.org als txt-Datei holen:
response = requests.get("http://www.gutenberg.org/cache/epub/32201/pg32201.txt")
response.encoding = "utf-8"
text = response.text

doc = nlp(text)

locations = {}   # Dictionary um Orte zu zählen

for ent in doc.ents:
    if ent.label_ == "LOC":
        if ent.text not in locations:   # erstes Vorkommen des Ortes
            locations[ent.text] = 1
        else:                           # Ort ist bereit vorgekommen, muss Zahl um eins erhöhen
            locations[ent.text] = locations[ent.text] + 1


print("Orte: ")
for location in locations:
    if locations[location] > 4:  # nur Orte die mehr als 4x vorkommen
        print("-", location, locations[location])
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

Man könnte was ähnliches mit Personen machen, je nach Text den man versucht zu analysieren.

# Wörter raten

Man muss ein Wort erraten: Als Tipp erhält man jeweils die Ähnlichkeit des geratenen Wortes im Hinblick auf das gesuchte. Im ausbaufähigen Beispiel mit Früchten umgesetzt:

Vorlage
import spacy

nlp = spacy.load("de_core_news_md")

gesucht = "Apfel"
gefunden = False

print("Willkommen bei «Errate die Frucht»!")

while not gefunden:
    print("Bitte raten")
    versuch = input()
    tokens = nlp(versuch + " " + gesucht)
    
    if versuch == gesucht:
        print("Gratuliere!!")
        gefunden = True
    else:
        aehnlichkeit = tokens[0].similarity(tokens[1])
        print("Ähnlichkeit zur gesuchten Frucht", aehnlichkeit);
   
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

Das Programm könnte das gesuchte Wort zufällig aus einer Liste wählen. Oder aber ein Spieler tippt ein Wort ein, der andere muss dann raten. Oder gar beide müssen ein Wort eingeben und raten dann abwechslungsweise – es gewinnt, wer schneller die Lösung hat.

Letzte Änderung: 11.2.2021, 14:48:43