Loomuliku keele töötlemise tehnoloogiad on viimastel aastatel muutunud üsna keerukaks. Tehnikahiiglastest harrastajateni kiirustavad paljud ehitada rikkalikke liideseid, mis suudaksid loomulikku keelt analüüsida, mõista ja sellele reageerida. Amazoni Alexa, Microsofti Cortana, Google'i Google Home ja Apple'i Siri eesmärk on muuta arvutitega suhtlemise viisi.
Sentimentide analüüs, loomuliku keele töötlemise alaväli, koosneb tehnikatest, mis määravad teksti või kõne tooni. Tänapäeval saame masinõppe ja sotsiaalmeediast ning ülevaadete saitidelt kogutud tohutu hulga andmete abil koolitada mudeleid mõistliku täpsuse tuvastamiseks loomuliku keele lõigu tunde tuvastamiseks.
Selles õpetuses saate teada, kuidas saate luua roboti, mis saab analüüsida saadud e-kirjade meelsust ja teavitada teid e-kirjadest, mis võivad teie tähelepanu kohe vajada.
Robot ehitatakse Java ja Pythoni segu kasutades. Need kaks protsessi suhtlevad omavahel Thrifti abil. Kui te ei tunne üht või mõlemat keelt, saate seda lugeda, kuna selle artikli põhimõisted kehtivad ka teiste keelte kohta.
Selleks, et teha kindlaks, kas e-kiri vajab teie tähelepanu, analüüsib bot seda ja teeb kindlaks, kas selles on tugev negatiivne toon. Seejärel saadab ta vajadusel tekstihoiatuse.
Kasutame oma postkastiga ühenduse loomiseks Sendgridi ja Twilio saadab tekstiteateid. ## Sentimentide analüüs: petlikult lihtne probleem
On sõnu, mida seostame positiivsete emotsioonidega, näiteks armastus, rõõm ja nauding. Ja on sõnu, mida seostame negatiivsete emotsioonidega, nagu vihkamine, kurbus ja valu. Miks mitte treenida mudelit neid sõnu ära tundma ja lugeda iga positiivse ja negatiivse sõna suhteline sagedus ja tugevus?
Noh, sellega on paar probleemi.
Esiteks on eitamisprobleem. Näiteks selline lause nagu 'virsik pole halb' viitab positiivsele emotsioonile, kasutades sõna, mida me seostame sageli negatiivsusega. Lihtne sõnakoti mudel ei suuda selle lause eitust ära tunda.
Samuti osutuvad segased tunded naiivse meeleolude analüüsi teiseks probleemiks. Näiteks selline lause nagu 'virsik pole halb, aga õun on tõesti kohutav', sisaldab segatud intensiivsusega segaseid tundeid, mis suhtlevad omavahel. Lihtne lähenemine ei suuda lahendada segaseid tundeid, erinevat intensiivsust ega tunnete vahelist suhtlemist.
Raamatukogu Stanfordi loomuliku keele töötlemine sentimentide analüüsimiseks lahendab need probleemid rekursiivse närvitensorite võrgu (RNTN) abil.
RNTN-algoritm jagab lause kõigepealt üksikuteks sõnadeks. Seejärel ehitage närvivõrk, kus sõlmed on üksikud sõnad. Lõpuks lisatakse tensorikiht, et mudel saaks sõnade ja fraaside vastasmõju õigesti reguleerida.
Algoritmi visuaalse tutvustuse leiate oma saidilt ametlik koduleht .
Stanfordi NLP rühm koolitas rekursiivset närvitensorite võrku, kasutades käsitsi märgistatud IMDB-filmide hinnanguid, ja leidis, et nende mudel on võimeline ennustama enesetunnet väga täpselt.
Esimene asi, mida teha, on e-posti integreerimise seadistamine, et andmeid saaks teie robotile edastada.
Selle saavutamiseks on mitmeid viise, kuid lihtsuse huvides seadistagem lihtsa veebiserveri ja kasutagem Sendgridi sisendanalüüsi konksu serverisse saadetavate meilide saatmiseks. Saame edastada meilid Sendgridi sissetulevale analüüsiaadressile. Sendgrid saadab POST-päringu meie veebiserverisse ja seejärel saame andmeid oma serveri kaudu töödelda.
Serveri ülesehitamiseks kasutame selleks lihtsat veebiraamistikku Flask Python .
Lisaks veebiserveri loomisele soovime ühendada veebiteenuse ka domeeniga. Lühidalt, jätame sellest artiklis kirjutamise vahele. Selle kohta saate siiski rohkem lugeda siin .
Looge veebiserver veebisaidil Kolb see on uskumatult lihtne.
Looge lihtsalt app.py
ja lisage see faili:
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
' % datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')) return 'Got it' app.run(host='0.0.0.0')
Kui juurutame selle rakenduse domeeninime taha ja klõpsame lõpp-punktil '/ analüüsida', peaksite nägema midagi sellist:
> >> requests.post ('http://sentiments.shanglunwang.com:5000/analyze') .text 'Lo tengo'
Järgmisena tahame saata e-kirju sellesse lõpp-punkti.
Lisateavet leiate dokumentatsioonist siin kuid põhimõtteliselt soovite seadistada Sendgridi oma e-posti protsessoriks ja Sendgrid edastab meilid meie veebiserverile.
Siin on minu konfiguratsioon Sendgridis. See edastab meilid aadressile @sentibot.shanglunwang.com
kui POST taotleb saiti „http://sentiments.shanglunwang.com/analyze”:
Võite kasutada mis tahes muud teenust, mis toetab sissetulevate meilide saatmist veebihookide kaudu.
Pärast kõige seadistamist proovige saata e-kiri oma SendGridi aadressile. Logides peaksite nägema midagi sellist:
endpoint hit 2017-05-25 14:35:46
See on suurepärane! Nüüd on teil robot, mis saab e-kirju vastu võtta. See on pool sellest, mida me proovime teha.
Nüüd soovite anda sellele robotile võimaluse analüüsida meilisõnumeid.
Kuna Stanfordi NLP-teek on kirjutatud Java-keeles, tahame parsimismootori ehitada Java-sse.
Alustame Mavenist Stanfordi NLP teegi ja mudelite allalaadimisega. Looge uus projekt Java , lisage oma Maveni sõltuvustesse järgmised andmed ja importige:
edu.stanford.nlp stanford-corenlp 3.6.0
Stanfordi NLP meeleolude analüüsimootorile pääseb juurde, määrates gaasijuhtme initsialiseerimiskoodis tunde märkija. Annotatsiooni saab leida puustruktuurina.
Selle õpetuse jaoks tahame teada ainult lause üldist meeleolu, nii et puud pole vaja sõeluda. Peame lihtsalt vaatama baassõlme.
See muudab põhikoodi suhteliselt lihtsaks:
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 = 'Los amigos hermosos increíblemente agradecidos están cumpliendo un logro increíblemente alegre. ¡Qué idea verdaderamente terrible!'; 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); } } }
Proovige mõnda lauset ja peaksite nägema sobivaid märkusi. Näidiskoodi tulemuste käitamine:
Muy positivo Negativo
Nii et meil on Java-s kirjutatud meeleoluanalüsaatori programm ja Pythonis kirjutatud e-posti bot. Kuidas panna nad omavahel rääkima?
Sellele probleemile on palju võimalikke lahendusi, kuid siin me seda ka kasutame Säästlikkus . Aktiveerime Sentiment Analyzeri Thrifti serverina ja meiliboti Thrifti kliendina.
Säästlikkus on koodigeneraator ja -protokoll, mida kasutatakse selleks, et kaks sageli erinevates keeltes kirjutatud rakendust saaksid omavahel suhelda määratletud protokolli abil. Polygloti meeskonnad kasutavad Thriftit mikroteenuste võrkude loomiseks, et kasutada ära iga kasutatava keele paremik.
Thrifti kasutamiseks vajame kahte asja: faili .thrift
määratleda teenuse lõpp-punktid ja failis .proto
määratletud protokolli kasutamiseks loodud kood. Parsimisteenuse jaoks sentiment.thrift
see näeb välja selline:
namespace java sentiment namespace py sentiment service SentimentAnalysisService { string sentimentAnalyze(1:string sentence), }
Selle .thrift-faili abil saame genereerida kliendi ja serveri koodi. Käivita:
thrift-0.10.0.exe --gen py sentiment.thrift thrift-0.10.0.exe --gen java sentiment.thrift
Märkus. Ehitage kood Windowsi masinasse. Peate kasutama oma keskkonnas Thrifti käivitatava faili õiget teed.
Nüüd teeme serveri loomiseks skannimismootorisse vastavad muudatused. Teie Java-programm peaks välja nägema selline:
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); } }
See käitleja on koht, kus saame Thrifti protokolli analüüsitaotluse.
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 += '
'; } return output; } }
Parser kasutab Stanfordi NLP-teeki, et määrata teksti sentiment ja loob stringi, mis sisaldab sentimentide märkmeid teksti iga lause kohta.
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(); } } }
Pange tähele, et ma ei lisanud faili SentimentAnalysisService.java
siin, sest see on loodud fail. Peaksite genereeritud koodi panema kohta, kus ülejäänud kood saab sellele juurde pääseda.
Nüüd, kui server on üleval, kirjutame serveri kasutamiseks Pythoni klient.
klient.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'))
Käivitage see ja peaksite nägema:
Muy positivo
Suurepärane! Nüüd, kui server töötab ja kliendiga räägib, integreerime selle e-posti robotiga, kiirendades klienti ja ühendades selle e-kirjaga.
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'
Nüüd juurutage Java-teenus samasse masinasse, kus töötate veebiserveriga, käivitage teenus ja taaskäivitage rakendus. Saatke robotile testlausega meilisõnum ja logifailis peaksite nägema midagi sellist:
Increíblemente maravillosamente positiva y hermosa frase. Muy positivo
Kõik hästi! Nüüd on meil e-posti bot, mis saab teha meeleolude analüüsi! Saame saata meili ja saada arvamusmärgendi iga saadetud lause kohta. Uurime nüüd, kuidas saaksime luuret tegevuskõlblikuks muuta.
Asjade lihtsuse huvides keskendugem e-kirjadele, kus on palju negatiivsete ja väga negatiivsete lausete kontsentratsiooni. Kasutame lihtsat hindamissüsteemi ja ütleme, et kui e-kiri sisaldab rohkem kui 75% negatiivsete meeltelausetega lauseid, siis tähistame selle potentsiaalse häiremeilina, mis võib vajada viivitamatut vastust. Rakendame hindamisloogika sõeluteel:
@app.route('/analyze', methods=['POST']) def analyze(): text = str(request.form.get('text')) sentiment_client = client.SentimentClient() text.replace('
', '') # 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'
Ülaltoodud kood teeb mõned eeldused, kuid see töötab demonstreerimise eesmärgil. Saatke oma robotile paar e-kirja ja peaksite logides nägema e-posti analüüsi:
Recibido: Aquí hay una prueba para el sistema. Se supone que es una solicitud no urgente. ¡Es muy bueno! En su mayor parte esto es positivo o neutral. Grandes cosas están sucediendo! urgente = Falso Recibido: esta es una solicitud urgente. Todo es realmente horrible Esto es un desastre. La gente odia este correo insípido. urgente = True
Oleme peaaegu valmis!
Oleme loonud e-posti roboti, mis saab vastu võtta e-kirju, teha meeleolude analüüsi ja teha kindlaks, kas e-kiri nõuab viivitamatut tähelepanu. Nüüd peame tekstsõnumi saatma ainult siis, kui meil on eriti negatiivne.
Tekstihoiatuse saatmiseks kasutame Twilio. Teie Pythoni API, mis on dokumenteeritud siin , see on üsna lihtne. Muudame analüüsi teed päringu esitamiseks, kui saate kiireloomulise taotluse.
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('
', '') # 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('
') return 'Got it'
Peate oma Twilio konto mandaatides määrama keskkonnamuutujad ja määrama telefoninumbri telefonile, mida see saab kontrollida. Kui olete selle teinud, saatke skannimise lõpp-punktile meilisõnum ja näete kõnesolevale telefoninumbrile saadetud tekstsõnumit.
Ja me saime valmis!
Selles artiklis õppisite meilisõnumite analüüsiboti loomist Stanfordi NLP teegi abil. Raamatukogu aitab abstraktselt mõista kõiki loomuliku keele töötlemise olulisi üksikasju ja võimaldab teil seda kasutada oma NLP-rakenduste ehituskivina.
Loodan, et see postitus on näidanud üht paljudest hämmastavatest potentsiaalsetest sentimentide analüüsi rakendustest ja see inspireerib teid looma oma NLP-rakendust.