So erstellen Sie einen E-Mail-Stimmungsanalyse-Bot: Ein NLP-Tutorial
Veröffentlicht: 2022-03-11Technologien zur Verarbeitung natürlicher Sprache sind in den letzten Jahren ziemlich ausgefeilt geworden. Von Technologiegiganten bis hin zu Hobbyisten beeilen sich viele, reichhaltige Schnittstellen zu entwickeln, die natürliche Sprache analysieren, verstehen und darauf reagieren können. Amazons Alexa, Microsofts Cortana, Googles Google Home und Apples Siri zielen alle darauf ab, die Art und Weise zu verändern, wie wir mit Computern interagieren.
Die Stimmungsanalyse, ein Teilgebiet der Verarbeitung natürlicher Sprache, besteht aus Techniken, die den Tonfall eines Textes oder einer Rede bestimmen. Heute können wir mit maschinellem Lernen und großen Datenmengen aus sozialen Medien und Bewertungsseiten Modelle trainieren, um die Stimmung einer natürlichen Sprachpassage mit ziemlicher Genauigkeit zu identifizieren.
In diesem Tutorial erfahren Sie, wie Sie einen Bot erstellen können, der die Stimmung der empfangenen E-Mails analysiert und Sie über E-Mails benachrichtigt, die möglicherweise sofort Ihre Aufmerksamkeit erfordern.
Stimmungsanalyse in E-Mails
Der Bot wird mit einer Mischung aus Java- und Python-Entwicklung erstellt. Die beiden Prozesse kommunizieren über Thrift miteinander. Wenn Sie mit einer oder beiden dieser Sprachen nicht vertraut sind, können Sie trotzdem weiterlesen, da die grundlegenden Konzepte dieses Artikels auch für andere Sprachen gelten.
Um festzustellen, ob eine E-Mail Ihre Aufmerksamkeit erfordert, analysiert der Bot sie und stellt fest, ob ein stark negativer Ton vorhanden ist. Es sendet dann bei Bedarf eine Textbenachrichtigung.
Wir werden Sendgrid verwenden, um eine Verbindung zu unserer Mailbox herzustellen, und Twilio, um Textbenachrichtigungen zu versenden.
Stimmungsanalyse: Ein täuschend einfaches Problem
Es gibt Wörter, die wir mit positiven Emotionen wie Liebe, Freude und Vergnügen assoziieren. Und es gibt Wörter, die wir mit negativen Emotionen wie Hass, Traurigkeit und Schmerz assoziieren. Warum trainieren Sie das Modell nicht darauf, diese Wörter zu erkennen und die relative Häufigkeit und Stärke jedes positiven und negativen Worts zu zählen?
Nun, es gibt ein paar Probleme damit.
Erstens gibt es ein Negationsproblem. Zum Beispiel impliziert ein Satz wie „Der Pfirsich ist nicht schlecht“ eine positive Emotion, indem er ein Wort verwendet, das wir am häufigsten mit negativ assoziieren. Ein einfaches Bag-of-Words-Modell wird die Negation in diesem Satz nicht erkennen können.
Darüber hinaus erweisen sich gemischte Gefühle als ein weiteres Problem bei der naiven Stimmungsanalyse. Zum Beispiel enthält ein Satz wie „Der Pfirsich ist nicht schlecht, aber der Apfel ist wirklich schrecklich“ gemischte Gefühle unterschiedlicher Intensität, die miteinander interagieren. Ein einfacher Ansatz wird die kombinierten Gefühle, die unterschiedliche Intensität oder die Wechselwirkungen zwischen den Gefühlen nicht auflösen können.
Stimmungsanalyse mit rekursivem neuronalem Tensornetzwerk
Die Stanford Natural Language Processing-Bibliothek für Stimmungsanalysen löst diese Probleme mithilfe eines rekursiven neuralen Tensornetzwerks (RNTN).
Der RNTN-Algorithmus zerlegt einen Satz zunächst in einzelne Wörter. Es baut dann ein neuronales Netzwerk auf, in dem die Knoten die einzelnen Wörter sind. Schließlich wird eine Tensorschicht hinzugefügt, damit sich das Modell richtig an Interaktionen zwischen den Wörtern und Phrasen anpassen kann.
Eine visuelle Demonstration des Algorithmus finden Sie auf der offiziellen Website.
Die Stanford NLP-Gruppe trainierte das Recursive Neural Tensor Network mit manuell markierten IMDB-Filmkritiken und stellte fest, dass ihr Modell Stimmungen mit sehr guter Genauigkeit vorhersagen kann.
Bot, der E-Mails empfängt
Als Erstes sollten Sie die E-Mail-Integration einrichten, damit Daten an Ihren Bot weitergeleitet werden können.
Es gibt viele Möglichkeiten, dies zu erreichen, aber der Einfachheit halber richten wir einen einfachen Webserver ein und verwenden den Eingangs-Parse-Hook von Sendgrid, um E-Mails an den Server zu leiten. Wir können E-Mails an die eingehende Parse-Adresse von Sendgrid weiterleiten. Sendgrid sendet dann eine POST-Anforderung an unseren Webserver, und wir können die Daten dann über unseren Server verarbeiten.
Um den Server zu erstellen, verwenden wir Flask, ein einfaches Web-Framework für Python.
Zusätzlich zum Erstellen des Webservers möchten wir den Webdienst mit einer Domäne verbinden. Der Kürze halber werden wir es überspringen, in diesem Artikel darüber zu schreiben. Sie können jedoch hier mehr darüber lesen.
Das Erstellen eines Webservers in Flask ist unglaublich einfach.
Erstellen Sie einfach eine app.py und fügen Sie diese der Datei hinzu:
from flask import Flask, request import datetime app = Flask(__name__) @app.route('/analyze', methods=['POST']) def analyze(): with open('logfile.txt', 'a') as fp_log: fp_log.write('endpoint hit %s \n' % datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')) return "Got it" app.run(host='0.0.0.0')Wenn wir diese App hinter einem Domänennamen bereitstellen und den Endpunkt „/analyze“ erreichen, sollten Sie so etwas sehen:
> >> requests.post('http://sentiments.shanglunwang.com:5000/analyze').text 'Got it'Als Nächstes möchten wir E-Mails an diesen Endpunkt senden.
Weitere Dokumentation finden Sie hier, aber im Wesentlichen möchten Sie Sendgrid als Ihren E-Mail-Prozessor einrichten und Sendgrid die E-Mails an unseren Webserver weiterleiten lassen.
Hier ist mein Setup auf Sendgrid. Dadurch werden E-Mails an @sentibot.shanglunwang.com als POST-Anforderungen an „http://sentiments.shanglunwang.com/analyze“ weitergeleitet:
Sie können jeden anderen Dienst verwenden, der das Senden eingehender E-Mails über Webhooks unterstützt.
Nachdem Sie alles eingerichtet haben, versuchen Sie, eine E-Mail an Ihre Sendgrid-Adresse zu senden. Sie sollten in den Protokollen so etwas sehen:
endpoint hit 2017-05-25 14:35:46Das ist großartig! Sie haben jetzt einen Bot, der E-Mails empfangen kann. Das ist die Hälfte dessen, was wir versuchen.
Jetzt möchten Sie diesem Bot die Möglichkeit geben, Stimmungen in E-Mails zu analysieren.
E-Mail-Stimmungsanalyse mit Stanford NLP
Da die Stanford-NLP-Bibliothek in Java geschrieben ist, möchten wir die Analyse-Engine in Java erstellen.
Beginnen wir mit dem Herunterladen der Stanford NLP-Bibliothek und -Modelle in Maven. Erstellen Sie ein neues Java-Projekt, fügen Sie Folgendes zu Ihren Maven-Abhängigkeiten hinzu und importieren Sie:
<dependency> <groupId>edu.stanford.nlp</groupId> <artifactId>stanford-corenlp</artifactId> <version>3.6.0</version> </dependency>Auf die Sentiment-Analyse-Engine von Stanford NLP kann zugegriffen werden, indem der Sentiment-Annotator im Pipeline-Initialisierungscode angegeben wird. Die Annotation kann dann als Baumstruktur abgerufen werden.
Für die Zwecke dieses Tutorials möchten wir nur die allgemeine Bedeutung eines Satzes kennen, sodass wir den Baum nicht analysieren müssen. Wir müssen uns nur den Basisknoten ansehen.
Dies macht den Hauptcode relativ einfach:
package seanwang; import edu.stanford.nlp.pipeline.*; import edu.stanford.nlp.util.CoreMap; import edu.stanford.nlp.ling.CoreAnnotations; import edu.stanford.nlp.sentiment.SentimentCoreAnnotations; import java.util.*; public class App { public static void main( String[] args ) { Properties pipelineProps = new Properties(); Properties tokenizerProps = new Properties(); pipelineProps.setProperty("annotators", "parse, sentiment"); pipelineProps.setProperty("parse.binaryTrees", "true"); pipelineProps.setProperty("enforceRequirements", "false"); tokenizerProps.setProperty("annotators", "tokenize ssplit"); StanfordCoreNLP tokenizer = new StanfordCoreNLP(tokenizerProps); StanfordCoreNLP pipeline = new StanfordCoreNLP(pipelineProps); String line = "Amazingly grateful beautiful friends are fulfilling an incredibly joyful accomplishment. What an truly terrible idea."; Annotation annotation = tokenizer.process(line); pipeline.annotate(annotation); // normal output for (CoreMap sentence : annotation.get(CoreAnnotations.SentencesAnnotation.class)) { String output = sentence.get(SentimentCoreAnnotations.SentimentClass.class); System.out.println(output); } } }Probieren Sie einige Sätze aus und Sie sollten die entsprechenden Anmerkungen sehen. Ausführen der Beispielcodeausgaben:
Very Positive NegativeIntegration des Bots und der Analyse-Engine
Wir haben also ein Stimmungsanalyseprogramm, das in Java geschrieben ist, und einen E-Mail-Bot, der in Python geschrieben ist. Wie bringen wir sie dazu, miteinander zu reden?
Es gibt viele mögliche Lösungen für dieses Problem, aber hier verwenden wir Thrift. Wir werden den Sentiment Analyzer als Thrift-Server und den E-Mail-Bot als Thrift-Client einrichten.
Thrift ist ein Code-Generator und ein Protokoll, mit dem zwei Anwendungen, die oft in verschiedenen Sprachen geschrieben sind, über ein definiertes Protokoll miteinander kommunizieren können. Polyglotte Teams verwenden Thrift, um Netzwerke von Microservices aufzubauen, um das Beste aus jeder Sprache, die sie verwenden, zu nutzen.
Um Thrift zu verwenden, benötigen wir zwei Dinge: eine .thrift -Datei, um die Dienstendpunkte zu definieren, und generierten Code, um das in der .proto -Datei definierte Protokoll zu verwenden. Für den Analysedienst sieht die sentiment.thrift wie folgt aus:

namespace java sentiment namespace py sentiment service SentimentAnalysisService { string sentimentAnalyze(1:string sentence), }Mit dieser .thrift-Datei können wir Client- und Servercode generieren. Laufen:
thrift-0.10.0.exe --gen py sentiment.thrift thrift-0.10.0.exe --gen java sentiment.thriftHinweis: Ich habe den Code auf einem Windows-Computer generiert. Sie sollten den entsprechenden Pfad zur ausführbaren Thrift-Datei in Ihrer Umgebung verwenden.
Nehmen wir nun die entsprechenden Änderungen an der Analyse-Engine vor, um einen Server zu erstellen. Ihr Java-Programm sollte wie folgt aussehen:
SentimentHandler.java
package seanwang; public class SentimentHandler implements SentimentAnalysisService.Iface { SentimentAnalyzer analyzer; SentimentHandler() { analyzer = new SentimentAnalyzer(); } public String sentimentAnalyze(String sentence) { System.out.println("got: " + sentence); return analyzer.analyze(sentence); } }Über diesen Handler erhalten wir die Analyseanforderung über das Thrift-Protokoll.
SentimentAnalyzer.java
package seanwang; // ... public class SentimentAnalyzer { StanfordCoreNLP tokenizer; StanfordCoreNLP pipeline; public SentimentAnalyzer() { Properties pipelineProps = new Properties(); Properties tokenizerProps = new Properties(); pipelineProps.setProperty("annotators", "parse, sentiment"); pipelineProps.setProperty("parse.binaryTrees", "true"); pipelineProps.setProperty("enforceRequirements", "false"); tokenizerProps.setProperty("annotators", "tokenize ssplit"); tokenizer = new StanfordCoreNLP(tokenizerProps); pipeline = new StanfordCoreNLP(pipelineProps); } public String analyze(String line) { Annotation annotation = tokenizer.process(line); pipeline.annotate(annotation); String output = ""; for (CoreMap sentence : annotation.get(CoreAnnotations.SentencesAnnotation.class)) { output += sentence.get(SentimentCoreAnnotations.SentimentClass.class); output += "\n"; } return output; } }Der Analysator verwendet die Stanford NLP-Bibliothek, um die Stimmung des Textes zu bestimmen, und erzeugt eine Zeichenfolge, die die Stimmungsanmerkungen für jeden Satz im Text enthält.
SentimentServer.java
package seanwang; // ... public class SentimentServer { public static SentimentHandler handler; public static SentimentAnalysisService.Processor processor; public static void main(String [] args) { try { handler = new SentimentHandler(); processor = new SentimentAnalysisService.Processor(handler); Runnable simple = new Runnable() { public void run() { simple(processor); } }; new Thread(simple).start(); } catch (Exception x) { x.printStackTrace(); } } public static void simple(SentimentAnalysisService.Processor processor) { try { TServerTransport serverTransport = new TServerSocket(9090); TServer server = new TSimpleServer(new Args(serverTransport).processor(processor)); System.out.println("Starting the simple server..."); server.serve(); } catch (Exception e) { e.printStackTrace(); } } } Beachten Sie, dass ich die Datei SentimentAnalysisService.java hier nicht eingefügt habe, da es sich um eine generierte Datei handelt. Sie sollten den generierten Code an einer Stelle ablegen, an der der Rest Ihres Codes darauf zugreifen kann.
Nachdem wir den Server eingerichtet haben, schreiben wir einen Python-Client, um den Server zu verwenden.
client.py
from sentiment import SentimentAnalysisService from thrift.transport import TSocket from thrift.transport import TTransport from thrift.protocol import TBinaryProtocol class SentimentClient: def __init__(self, server='localhost', socket=9090): transport = TSocket.TSocket(server, socket) transport = TTransport.TBufferedTransport(transport) protocol = TBinaryProtocol.TBinaryProtocol(transport) self.transport = transport self.client = SentimentAnalysisService.Client(protocol) self.transport.open() def __del__(self): self.transport.close() def analyze(self, sentence): return self.client.sentimentAnalyze(sentence) if __name__ == '__main__': client = SentimentClient() print(client.analyze('An amazingly wonderful sentence'))Führen Sie dies aus und Sie sollten Folgendes sehen:
Very PositiveToll! Jetzt, da der Server läuft und mit dem Client kommuniziert, integrieren wir ihn in den E-Mail-Bot, indem wir einen Client instanziieren und die E-Mail dorthin leiten.
import client # ... @app.route('/analyze', methods=['POST']) def analyze(): sentiment_client = client.SentimentClient() with open('logfile.txt', 'a') as fp_log: fp_log.write(str(request.form.get('text'))) fp_log.write(request.form.get('text')) fp_log.write(sentiment_client.analyze(request.form.get('text'))) return "Got it"Stellen Sie jetzt Ihren Java-Dienst auf demselben Computer bereit, auf dem Sie den Webserver ausführen, starten Sie den Dienst und starten Sie die App neu. Senden Sie eine E-Mail mit einem Testsatz an den Bot und Sie sollten in der Protokolldatei so etwas sehen:
Amazingly wonderfully positive and beautiful sentence. Very PositiveAnalysieren der E-Mail
Alles klar! Jetzt haben wir einen E-Mail-Bot, der Stimmungsanalysen durchführen kann! Wir können eine E-Mail senden und für jeden von uns gesendeten Satz ein Sentiment-Tag erhalten. Lassen Sie uns nun untersuchen, wie wir die Informationen umsetzbar machen können.
Konzentrieren wir uns der Einfachheit halber auf E-Mails mit einer hohen Konzentration negativer und sehr negativer Sätze. Verwenden wir ein einfaches Bewertungssystem und sagen wir, wenn eine E-Mail mehr als 75 % negative Stimmungssätze enthält, markieren wir dies als potenzielle Alarm-E-Mail, die möglicherweise eine sofortige Reaktion erfordert. Lassen Sie uns die Bewertungslogik in der Analyseroute implementieren:
@app.route('/analyze', methods=['POST']) def analyze(): text = str(request.form.get('text')) sentiment_client = client.SentimentClient() text.replace('\n', '') # remove all new lines sentences = text.rstrip('.').split('.') # remove the last period before splitting negative_sentences = [ sentence for sentence in sentences if sentiment_client.analyze(sentence).rstrip() in ['Negative', 'Very negative'] # remove newline char ] urgent = len(negative_sentences) / len(sentences) > 0.75 with open('logfile.txt', 'a') as fp_log: fp_log.write("Received: %s" % (request.form.get('text'))) fp_log.write("urgent = %s" % (str(urgent))) return "Got it"Der obige Code geht von einigen Annahmen aus, funktioniert aber zu Demonstrationszwecken. Senden Sie ein paar E-Mails an Ihren Bot und Sie sollten die E-Mail-Analyse in den Protokollen sehen:
Received: Here is a test for the system. This is supposed to be a non-urgent request. It's very good! For the most part this is positive or neutral. Great things are happening! urgent = False Received: This is an urgent request. Everything is truly awful. This is a disaster. People hate this tasteless mail. urgent = TrueSenden einer Warnung
Wir sind fast fertig!
Wir haben einen E-Mail-Bot entwickelt, der E-Mails empfangen, Stimmungsanalysen durchführen und feststellen kann, ob eine E-Mail sofortige Aufmerksamkeit erfordert. Jetzt müssen wir nur noch eine SMS versenden, wenn eine E-Mail besonders negativ ist.
Wir werden Twilio verwenden, um eine Textbenachrichtigung zu versenden. Ihre Python-API, die hier dokumentiert ist, ist ziemlich einfach. Lassen Sie uns die Analyseroute ändern, um eine Anfrage zu senden, wenn sie eine dringende Anfrage erhält.
def send_message(body): twilio_client.messages.create( to=on_call, from_=os.getenv('TWILIO_PHONE_NUMBER'), body=body ) app = Flask(__name__) @app.route('/analyze', methods=['POST']) def analyze(): text = str(request.form.get('text')) sentiment_client = client.SentimentClient() text.replace('\n', '') # remove all new lines sentences = text.rstrip('.').split('.') # remove the last period before splitting negative_sentences = [ sentence for sentence in sentences if sentiment_client.analyze(sentence).rstrip() in ['Negative', 'Very negative'] # remove newline char ] urgent = len(negative_sentences) / len(sentences) > 0.75 if urgent: send_message('Highly negative email received. Please take action') with open('logfile.txt', 'a') as fp_log: fp_log.write("Received: " % request.form.get('text')) fp_log.write("urgent = %s" % (str(urgent))) fp_log.write("\n") return "Got it"Sie müssen Ihre Umgebungsvariablen auf die Anmeldeinformationen Ihres Twilio-Kontos und die Bereitschaftsnummer auf ein Telefon festlegen, das Sie überprüfen können. Sobald Sie dies getan haben, senden Sie eine E-Mail an den Analyseendpunkt und Sie sollten sehen, dass ein Text an die betreffende Telefonnummer gesendet wird.
Und wir sind fertig!
Verarbeitung natürlicher Sprache leicht gemacht mit Stanford NLP
In diesem Artikel haben Sie gelernt, wie Sie mit der Stanford NLP-Bibliothek einen E-Mail-Stimmungsanalyse-Bot erstellen. Die Bibliothek hilft dabei, alle wesentlichen Details der Verarbeitung natürlicher Sprache zu abstrahieren, und ermöglicht Ihnen, sie als Baustein für Ihre NLP-Anwendungen zu verwenden.
Ich hoffe, dieser Beitrag hat eine der vielen erstaunlichen potenziellen Anwendungen der Stimmungsanalyse aufgezeigt und Sie dazu inspiriert, eine eigene NLP-Anwendung zu entwickeln.
Den Code für den E-Mail-Stimmungsanalyse-Bot finden Sie in diesem NLP-Tutorial auf GitHub.
