Warum nicht Tools von Amazon oder Google verwenden?
Das würde das Leben natürlich wesentlich leichter machen, aber niemand weiß wirklich etwas über die Lebensdauer der Daten in den Netzwerken dieser globalen Unternehmen. Und wie sieht es da eigentlich mit dem Datenschutz aus?
Aus meiner Sicht gibt es also nur eine Lösung: Sie richten es selber ein und machen dies, indem sie dafür ein bereits bestehendes Open-Source-Projekt benutzen. Sofern Ihre Trainingsdaten nicht zu komplex sind, schadet Ihnen diese Vorgehensweise aus Hardware-Sicht nicht wirklich.
NLU vs. NLP – ein paar Grundlagen
Als erstes sollte man wissen, dass NLU nicht NLP ist. Damit ist gemeint, dass das Natural Language Understanding nicht das Natural Language Processing ist. Wer mehr über die Unterschiede erfahren möchte, dem kann ich diesen Blogpost empfehlen. Kurz gesagt: NLP ist das komplette Ökosystem der Interaktion zwischen Menschen und Maschine, während NLU „nur“ der KI-Teil bei der Sortierung der unstrukturierten Daten ist und diese in eine Form bringt mit der
- diese von Maschinen verstanden werden können
- mit denen ein Intent bewertet werden kann
- bedeutende Entities extrahiert werden können
- es möglich ist, Modelle zu trainieren
Gehen wir noch etwas weiter ins Detail.
INTENT
Den Intent zu verstehen – einfacher gesprochen: das, was die andere Person eigentlich meint – ist selbst in der menschlichen Interaktion sehr kniffelig. Was ist die Intention, die eine Person ausdrücken möchte? Aber das ist eine ganz andere Geschichte.
Im Moment versuchen wir Maschinen so zu trainieren, dass sie die Absicht (Intent) eines Satzes verstehen. Werfen wir einen Blick auf das folgende Beispiel:
„Ich muss bis Freitag zu Hause bleiben.“
Dieser Satz kann mehrere Intents haben, was es ziemlich schwer macht, ihn zu verstehen:
- Der Erzähler hat Kinder und kein Kindermädchen für die kommende Woche.
- Der Erzähler ist krank.
- Aus irgendeinen Grund muss der Erzähler von zuhause aus arbeiten.
Diese Intents haben fast nichts gemeinsam, außer der Tatsache, dass der Erzähler am Freitag zurück sein wird.
ENTITY
Für diese Intents ist es wichtig, dass wir einige nützliche Werte aus diesen Sätzen entnehmen. Nehmen wir uns doch das Beispiel von oben. Was könnte in diesem Satz ein Wert sein, den wir zu erhalten versuchen sollten? Ich würde sagen, dass es sich bei „Freitag“ um einen solchen Wert handelt.
Warum? Je nach Intent sind diese Informationen wirklich nützlich. Also machen wir damit weiter und bringen es in eine Variable. Sagen wir mal, dass es der letzte_Tag von etwas ist. Wenn wir einen Intent wie „Krankmeldung“ haben, dann kann dieser Wert z. B. dafür benutzt werden um ein Jira-Ticket zu erstellen mit dem Betreff „Krank: Maximillian Berghoff [Datum vom letzten Tag]“.
MODEL
Um jedoch eine Maschine dazu zu bekommen, dass sie unsere Intents verstehen und Entities erfassen kann, müssen wir sie trainieren. Für diese Blogbeitrag habe ich RASA NLU verwendet.
Die Trainingsdaten sehen so aus:
language: "en" pipeline: - name: "nlp_spacy" model: "de" - name: "tokenizer_spacy" - name: "ner_crf" - name: "intent_featurizer_spacy" - name: "intent_classifier_sklearn" data: | ## intent:report_sick_duration - I will stay home for [3 days](duration) - I can not come the next [4 days](duration) - I will stay in bed for the next [5 days](duration) ## intent:report_sick_from_to - I will stay home until [friday](last) - My doctor suggests me to stay home until [friday](last) - I am absent from [monday](first) to [friday](last) - I will be back on [friday](last) ## lookup:duration - 1 days - 2 days - a week ## lookup:first - monday - tuesday - wednesday - thursday - friday ## lookup:last - monday - tuesday - wednesday - thursday - friday
Sehen wir uns den Datenschlüssel an. Hier finden Sie die Intents vor. Ich habe die Krankmeldung in zwei verschiedene Intents aufgeteilt: Ein Intent, um Ihre Kollgenen/Chef darüber zu informieren, dass Sie aufgrund von Krankheit von X bis Y abwesend sind sowie ein weiterer, um die Dauer (Anzahl von Tagen) anzugeben.
Es ist nützlich zwei verschiedene Intents zu haben, da man zwei verschiedene Sets von Entities definieren kann.
Erste Entity: Ich brauche ein Datum für den ersten und letzten Tag, zumindest der erste Tag sollte existieren, also nehmen wir heute als den ersten Tag an.
Für die zweite Entity benötige ich nur die Dauer (und nehme heute als den ersten Tag an). In diesem Beispiel habe ich auch eine Art von Setting beschrieben, welche Werte möglich sind. Dieses wird während des Trainingsprozesses angereichert.
Obwohl dies wie eine Art Muster oder Algorithmus aussieht, um die Suche nach Intent und Entities durchzuführen, ist es das nicht.
Am Ende sollte die Maschine Sätze erkennen, die nicht auf dieser Liste stehen. Bis dies mit akzeptabler Sicherheit durchgeführt wird, müssen wir weitere Beispiele, wie die oben genannten, nennen.
Tools für den Einsatz – RASA NLU
Es gibt noch andere Software Tools, mit denen NLU betrieben werden kann, aber ich habe mich dazu entschieden, es mit RASA NLU zu machen. Es hat alle Features, die wir für unseren Anwendungsfall benötigen und es ist recht einfach zu installieren:
pip install rasa_nlu # OR (to get a bleeding edge) # git clone https://github.com/RasaHQ/rasa_nlu.git cd rasa_nlu pip install -r requirements.txt pip install -e .
Jetzt kann man einige Konfigurationen weitergeben/erstellen und mit dem Training beginnen. Dieser hier hat aber einen kleinen Nachteil: Es ist in Python geschrieben. Aber was ist, wenn Sie eine PHP-Anwendung ausführen? Dafür empfehle ich, die HTTP-API von RASA zu verwenden und sie in Ihre Anwendung einzubinden, indem Sie einfache Curl-Requests durchführen.
PHP-Integration
Für einen Vortrag bei PHP Central Europe habe ich einen Code vorbereitet, der zeigt, dass es möglich ist, NLU in PHP zu integrieren, ohne NLU in PHP zu implementieren. Sie können sich das Repository ansehen und sollten auch einen Blick auf rasa_client/lib
werfen. Dieser Code sollte ausreichen, um einige grundlegende Anforderungen zu erfüllen und sinnvolle Modelle zurückzubekommen. Für unser Beispiel (Krankheitsbericht) habe ich auch eine Kommandozeilenanwendung in Symfony eingeführt.
Dies ist überhaupt nicht zwingend erforderlich, es ist einfach der schnellste Weg für mich, den angegebenen Code aufzurufen und etwas Lesbares zu erhalten.
Um mit diesem Beispiel zu arbeiten, sollten Sie beide Docker-Container ausführen und den für den App-Code eingeben:
$ cd examples/ $ docker-compose up -d $ docker exec -it rasa-nlu-client sh $ cd /app/src/ $ bin/console
Der Befehl bin/console sollte eine Liste zurückgeben, die so aussieht:
rasa rasa:nlu:parse Parse a given text for its intents. rasa:nlu:remove-model Remove a training model. rasa:nlu:status return the available projects and models rasa:nlu:train Train a project by a well-defined training data. For the training data, you should have a look at https://rasa.com/docs/nlu/dataformat/
….. was eine Übersicht über die gegebenen Befehle ist. Dann mal ran an die Arbeit!
STATUS
$ bin/console rasa:nlu:status Got following projects\ Project: sick_report ======================= currently training:0 ----------------------- Available Model ----------------------- model_20181027-164038 model_20181027-173358 ----------------------- ----------------------- Loaded Model ----------------------- model_20181027-173358 -----------------------
Dies gibt einen Überblick über Modelle und aktuell laufende Trainingssets. Die unter „Geladenes Modell“ aufgeführten Modelle werden in den Speicher geladen, d.h. Sie erhalten die schnellsten Antworten.
TRAIN
rasa:nlu:train --project=illness_report data/config_train_illness_report.yml new model trained ================= Created Model: model_20181029-062412
Dies postet eine gültige Trainingsdatendatei in ein Projekt (ich habe die oben genannte verwendet), um ein neues Modell zu trainieren. Sie können ein Modell auch erwähnen, indem Sie -model
verwenden, um ein bestehendes Modell zu trainieren.
STATUS (NEW MODEL THERE)
# bin/console rasa:nlu:status
Got following projects\
Project: illness_report
=======================
currently training:0
-----------------------
Available Model
-----------------------
model_20181027-164038
model_20181027-173358
model_20181029-062412
-----------------------
-----------------------
Loaded Model
-----------------------
model_20181027-173358
-----------------------
Nachdem Sie neue Trainingsdaten hinzugefügt haben, ohne das Modell zu erwähnen, wird das neu erstellte Modell in der Statusliste angezeigt.
PARSE
$ bin/console rasa:nlu:parse --project=illness_report "I will be absent due to sickness until friday" Intent: report_illness_from_to - Confidence: 0.8078944273721 ============================================================ Entities found: ------ -------- ------- ----- ----------- ------------------ Name Value start end extractor confidence ------ -------- ------- ----- ----------- ------------------ last friday 20 26 ner_crf 0.93667437133644 ------ -------- ------- ----- ----------- ------------------ Ranking: ------------------------- ----------------- ------------ Pos. Name Confidence ------------------------- ----------------- ------------ report_illness_from_to 0.8078944273721 report_illness_duration 0.1921055726279 ------------------------- ----------------- ------------
Jetzt können Sie mit dem Parsen von Text beginnen. Sie erhalten eine statistische Antwort. Das bedeutet, dass jeder Intent, den Sie erhalten, nur einer mit berechnetem Vertrauen ist. „0.8“ ist ziemlich in Ordnung, aber ein wenig mehr Training wird Ihre Bestätigungsstufe erhöhen. Sie erhalten auch eine Entity zurück, wenn sie in Ihren Trainingsdaten definiert wurde.
Fazit
Wie Sie sehen können, ist es möglich, mit PHP NLU in Ihrer Anwendung zu implementieren und nicht auf Python, AWS und dergleichen zurückgreifen zu müssen. Und Sie müssen sich nicht auf Webservices verlassen, bei denen Sie keine Kontrolle über Ihre Daten haben. Stattdessen können Sie Werkzeuge wie RASA NLU verwenden, die sehr einfach zu implementieren sind und es Ihnen ermöglichen, Text über die KI zu analysieren, ohne den PHP-Kontext zu verlassen.
Dieser Artikel erschien zuerst im Englischen, geschrieben von Maximilian Berghoff auf dem Blog von Mayflower.
Steht PHP hier wirklich für die Programmiersprache PHP?
Denn ich habe in den ganzen Listings kein Beispiel gesehen, dass hier PHP verwendet wird.
Lediglich die Konsole, aber auch hier findet keine Verwendung von PHP-Scripten statt?