PHP verwenden, um NLU in die eigene Applikation zu implementieren

Natural Language Understanding mit PHP
1 Kommentar

Jeder kann Alexa Skills in PHP schreiben. Wie aber sieht es mit NLU aus, dem Natural Language Understanding? Jetzt gibt es einige Tools dafür, die allerdings in Python geschrieben wurden, was der Normalfall in Umgebungen für das Maschinelle Lernen ist. Im folgenden Teil werde ich Ihnen zeigen, wie man dies mit RASA NLU in PHP machen kann, ohne Python einzubinden.

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.

Unsere Redaktion empfiehlt:

Relevante Beiträge

Hinterlasse einen Kommentar

1 Kommentar auf "Natural Language Understanding mit PHP"

avatar
400
  Subscribe  
Benachrichtige mich zu:
Rob
Gast

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?

X
- Gib Deinen Standort ein -
- or -