Luonnolliset kielenkäsittelytekniikat ovat viime vuosina muuttuneet melko kehittyneiksi. Teknisistä jättiläisistä harrastajiin, monet kiirehtivät rakentamaan rikkaita käyttöliittymiä, jotka voivat analysoida, ymmärtää ja vastata luonnolliseen kieleen. Amazonin Alexa, Microsoftin Cortana, Googlen Google Home ja Applen Siri pyrkivät muuttamaan tapaa, jolla olemme vuorovaikutuksessa tietokoneiden kanssa.
Sentiment-analyysi, luonnollisen kielenkäsittelyn osa-alue, koostuu tekniikoista, jotka määrittävät tekstin tai puheen sävyn. Nykyään koneoppimisen ja sosiaalisen median ja arvostelusivustojen kautta kerättävän suuren määrän tietojen avulla voimme kouluttaa malleja tunnistamaan luonnollisen kielenkäytön tunteet kohtuullisella tarkkuudella.
Tässä opetusohjelmassa opit, kuinka voit luoda botin, joka voi analysoida saamiesi sähköpostien ilmapiirin ja ilmoittaa sinulle viesteistä, jotka saattavat tarvita huomiosi välittömästi.
Botti rakennetaan Java- ja Python-sekoituksella. Nämä kaksi prosessia kommunikoivat keskenään Thriftin avulla. Jos et tunne yhtä tai molempia kieliä, voit lukea, sillä tämän artikkelin peruskäsitteet koskevat myös muita kieliä.
Määrittääksesi, tarvitseeko sähköposti sinun huomiota, botti analysoi sen ja määrittää, onko voimakas negatiivinen sävy. Sitten se lähettää tekstihälytyksen tarvittaessa.
Käytämme Sendgridiä yhteyden muodostamiseen postilaatikkoon ja Twilio lähettää tekstihälytyksiä. ## Sentimenttianalyysi: petollisen yksinkertainen ongelma
On sanoja, jotka yhdistämme positiivisiin tunteisiin, kuten rakkaus, ilo ja ilo. Ja on sanoja, jotka yhdistämme negatiivisiin tunteisiin, kuten vihaan, suruun ja tuskaan. Miksi ei kouluttaisi mallia tunnistamaan nämä sanat ja laskemaan kunkin positiivisen ja negatiivisen sanan suhteellinen taajuus ja vahvuus?
No, siinä on pari ongelmaa.
Ensinnäkin on kieltämisongelma. Esimerkiksi lause 'Persikka ei ole huono' viittaa positiivisiin tunteisiin käyttämällä sanaa, jonka usein yhdistämme negatiivisuuteen. Yksinkertainen sanapussimalli ei pysty tunnistamaan tämän lauseen negatiivisuutta.
Lisäksi sekavat tunteet osoittautuvat toisena ongelmana naiivilla mielipiteiden analyysillä. Esimerkiksi lause, kuten 'persikka ei ole huono, mutta omena on todella kauhea', sisältää sekavia voimakkuuden tunteita, jotka ovat vuorovaikutuksessa toistensa kanssa. Yksinkertainen lähestymistapa ei pysty ratkaisemaan sekavia tunteita, erilaista voimakkuutta tai tunteiden välistä vuorovaikutusta.
Kirjasto Stanfordin luonnollinen kielenkäsittely sentimenttianalyysi ratkaisee nämä ongelmat käyttämällä rekursiivista hermotensoriverkkoa (RNTN).
RNTN-algoritmi jakaa ensin lauseen yksittäisiksi sanoiksi. Rakenna sitten hermoverkko, jossa solmut ovat yksittäisiä sanoja. Lopuksi lisätään tensorikerros, jotta malli voi oikein säätää sanojen ja lauseiden välistä vuorovaikutusta.
Löydät algoritmin visuaalisen esityksen omasta virallinen nettisivu .
Stanfordin NLP-ryhmä koulutti rekursiivisen hermosensoriverkoston käyttäen manuaalisesti merkittyjen IMDB-elokuvien arviointeja ja havaitsi, että heidän mallinsa pystyy ennustamaan tunteen erittäin hyvällä tarkkuudella.
Ensimmäinen asia on määrittää sähköpostin integrointi, jotta tiedot voidaan siirtää bottiisi.
Voit saavuttaa tämän monilla tavoilla, mutta yksinkertaisuuden vuoksi perustetaan yksinkertainen verkkopalvelin ja lähetetään sähköpostin palvelimelle Sendgridin syötteen jäsentämiskoukulla. Voimme välittää sähköpostit Sendgridin saapuvaan analytiikkaosoitteeseen. Sendgrid lähettää POST-pyynnön verkkopalvelimellemme, ja sitten voimme käsitellä tietoja palvelimemme kautta.
Palvelimen rakentamiseen käytämme Flaskia, yksinkertaista verkkokehystä Python .
Verkkopalvelimen rakentamisen lisäksi haluamme liittää verkkopalvelun verkkotunnukseen. Lyhyesti sanottuna ohitamme tämän kirjoittamisen artikkelissa. Voit kuitenkin lukea lisää tästä tässä .
Luo verkkopalvelin Pullo se on uskomattoman yksinkertaista.
Luo vain app.py
ja lisää se tiedostoon:
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')
Jos otamme tämän sovelluksen käyttöön verkkotunnuksen takana ja napsautamme päätepistettä '/ analysoi', sinun pitäisi nähdä jotain tällaista:
> >> requests.post ('http://sentiments.shanglunwang.com:5000/analyze') .text 'Lo tengo'
Seuraavaksi haluamme lähettää sähköposteja tähän päätepisteeseen.
Löydät lisää dokumentaatiota tässä mutta pohjimmiltaan haluat määrittää Sendgridin sähköpostiprosessoriksi ja Sendgrid välittää sähköpostit edelleen verkkopalvelimellemme.
Tässä on kokoonpanoni Sendgridissä. Tämä välittää sähköpostit osoitteeseen @sentibot.shanglunwang.com
POST-pyyntöinä osoitteelle “http://sentiments.shanglunwang.com/analyze”:
Voit käyttää mitä tahansa muuta palvelua, joka tukee saapuvien sähköpostien lähettämistä verkkokoukkujen kautta.
Kun olet määrittänyt kaiken, yritä lähettää sähköpostia SendGrid-osoitteeseesi. Sinun pitäisi nähdä jotain tällaista lokeista:
endpoint hit 2017-05-25 14:35:46
Sepä hienoa! Nyt sinulla on botti, joka voi vastaanottaa sähköposteja. Se on puolet siitä, mitä yritämme tehdä.
Nyt haluat antaa tälle botille mahdollisuuden analysoida mielipiteitä sähköposteissa.
Koska Stanfordin NLP-kirjasto on kirjoitettu Java-muodossa, haluamme rakentaa jäsentämiskoneen Java-sovellukseen.
Aloitetaan lataamalla Stanfordin NLP-kirjasto ja mallit Maveniin. Luo uusi projekti Java , lisää seuraavat Maven-riippuvuuksiisi ja tuo:
edu.stanford.nlp stanford-corenlp 3.6.0
Stanfordin NLP-mielipiteiden analysointimoottoriin pääsee määrittämällä tunteen merkinnän putken alustuskoodissa. Huomautus voidaan hakea puurakenteena.
Tässä opetusohjelmassa haluamme tietää vain lauseen yleisen mielipiteen, joten puuta ei tarvitse analysoida. Meidän on vain tarkasteltava perussolmua.
Tämä tekee pääkoodista suhteellisen yksinkertaisen:
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); } } }
Kokeile muutama lause ja sinun pitäisi nähdä sopivat merkinnät. Esimerkkikoodin tulosten suorittaminen:
Muy positivo Negativo
Joten meillä on Java-ohjelmassa kirjoitettu sentimenttianalysaattoriohjelma ja Pythonilla kirjoitettu sähköpostibotti. Kuinka saamme heidät keskustelemaan keskenään?
Tähän ongelmaan on monia mahdollisia ratkaisuja, mutta tässä käytämme Säästäväisyys . Aktivoimme Sentiment Analyzerin Thrift-palvelimena ja sähköpostirobotin Thrift-asiakkaana.
Thrift on koodigeneraattori ja -protokolla, jonka avulla kaksi, usein eri kielillä kirjoitettua sovellusta voivat kommunikoida keskenään määritetyn protokollan avulla. Polyglot-ryhmät rakentavat Thriftillä mikropalveluverkostoja hyödyntääkseen jokaisen käyttämänsä kielen parhaat puolet.
Thriftin käyttämiseen tarvitaan kaksi asiaa: tiedosto .thrift
määritellä palvelun päätepisteet ja tiedosto, joka on määritelty tiedostossa määritetyn protokollan .proto
avulla. Parser-palvelua varten sentiment.thrift
se näyttää tältä:
namespace java sentiment namespace py sentiment service SentimentAnalysisService { string sentimentAnalyze(1:string sentence), }
Voimme luoda asiakas- ja palvelinkoodin tällä .thrift-tiedostolla. Juosta:
thrift-0.10.0.exe --gen py sentiment.thrift thrift-0.10.0.exe --gen java sentiment.thrift
Huomaa: Luo koodi Windows-koneelle. Sinun on käytettävä oikeaa polkua Thrift-suoritettavaan tiedostoon ympäristössäsi.
Tehdään nyt tarvittavat muutokset skannauskoneeseen palvelimen luomiseksi. Java-ohjelmasi pitäisi näyttää tältä:
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); } }
Tämä käsittelijä on paikka, jossa vastaanotamme analyysipyynnön Thrift-protokollasta.
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; } }
Jäsennys käyttää Stanfordin NLP-kirjastoa tekstin tunteen määrittämiseen ja tuottaa merkkijonon, joka sisältää tunteen merkinnät jokaiselle tekstin lauseelle.
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(); } } }
Huomaa, että en sisällyttänyt tiedostoa SentimentAnalysisService.java
täällä, koska se on luotu tiedosto. Laita luotu koodi paikkaan, johon muu koodi pääsee käsiksi.
Nyt kun palvelin on valmiina, kirjoitetaan Python-asiakas palvelinta käyttämään.
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'))
Suorita tämä ja sinun pitäisi nähdä:
Muy positivo
Loistava! Nyt kun palvelin on käynnissä ja puhumme asiakkaan kanssa, integroidaan se sähköpostirobottiin havainnollistamalla asiakas ja yhdistämällä se sähköpostiin.
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'
Ota nyt Java-palvelusi käyttöön samalla koneella, jolla käytät verkkopalvelinta, käynnistä palvelu ja käynnistä sovellus uudelleen. Lähetä botille testilause ja sinun pitäisi nähdä jotain tällaista lokitiedostosta:
Increíblemente maravillosamente positiva y hermosa frase. Muy positivo
Kaikki hyvin! Nyt meillä on sähköpostibotti, joka voi suorittaa mielipiteiden analyysin! Voimme lähettää sähköpostia ja saada mielipiteiden tunnisteen jokaisesta lähettämästämme lauseesta. Tutkitaan nyt, kuinka voimme tehdä älykkyydestä toimintakelpoisen.
Pidämme asiat yksinkertaisina keskittymällä sähköposteihin, joissa on paljon negatiivisia ja erittäin negatiivisia lauseita. Käytetään yksinkertaista pisteytysjärjestelmää ja sanotaan, että jos sähköposti sisältää yli 75% negatiivisia mielipiteitä, merkitsemme sen mahdolliseksi hälytyssähköpostiksi, joka saattaa vaatia välitöntä vastausta. Toteutetaan pisteytyslogiikka jäsennyspolulle:
@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'
Yllä oleva koodi tekee joitain oletuksia, mutta se toimii esittelytarkoituksiin. Lähetä pari sähköpostia botillesi ja sinun pitäisi nähdä sähköpostianalyysi lokeista:
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
Olemme melkein valmista!
Olemme luoneet sähköpostirobotin, joka voi vastaanottaa sähköposteja, suorittaa mielipiteiden analysointia ja määrittää, vaatiiko sähköposti välitöntä huomiota. Nyt meidän on lähetettävä tekstihälytys vain, kun sähköposti on erityisen negatiivinen.
Lähetämme tekstihälytyksen Twilion avulla. Python-sovellusliittymäsi, joka on dokumentoitu tässä , se on melko yksinkertainen. Muutetaan analyysireittiä lähettämään pyyntö, kun saat kiireellisen pyynnön.
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'
Sinun on määritettävä ympäristömuuttujat Twilio-tilisi kirjautumistiedoissa ja asetettava puhelinnumero puhelimeksi, jonka se voi tarkistaa. Kun olet tehnyt sen, lähetä sähköposti skannauksen päätepisteelle ja näet tekstiviestin, joka on lähetetty kyseiseen puhelinnumeroon.
Ja lopetimme!
Tässä artikkelissa opit rakentamaan sähköpostin mielipiteiden analysointibotin Stanfordin NLP-kirjaston avulla. Kirjasto auttaa tiivistämään kaikki luonnollisen kielenkäsittelyn olennaiset yksityiskohdat ja antaa sinun käyttää sitä rakennusmateriaalina NLP-sovelluksillesi.
Toivon, että tämä viesti on osoittanut yhden monista uskomattomista potentiaalisista mielipiteiden analyysin sovelluksista ja että tämä innostaa sinua luomaan oman NLP-sovelluksen.