As tecnologias de processamento de linguagem natural tornaram-se bastante sofisticadas nos últimos anos. De gigantes da tecnologia a amadores, muitos estão correndo para construir interfaces ricas que possam analisar, entender e responder à linguagem natural. Alexa, da Amazon, Cortana da Microsoft, Google Home do Google e Siri da Apple, todos visam mudar a maneira como interagimos com os computadores.
A análise de sentimento, um subcampo do processamento de linguagem natural, consiste em técnicas que determinam o tom de um texto ou fala. Hoje, com o aprendizado de máquina e a vasta quantidade de dados coletados em mídias sociais e sites de avaliação, podemos treinar modelos para identificar o sentimento de uma passagem de linguagem natural com precisão razoável.
Neste tutorial, você aprenderá como criar um bot que pode analisar o sentimento dos e-mails que você recebe e notificá-lo de e-mails que podem exigir sua atenção imediatamente.
O bot será construído usando uma combinação de Java e Python. Os dois processos irão se comunicar um com o outro usando Thrift. Se não estiver familiarizado com um ou ambos os idiomas, você pode continuar lendo, já que os conceitos fundamentais neste artigo também se aplicam a outros idiomas.
Para determinar se um e-mail precisa de sua atenção, o bot irá analisá-lo e determinar se há um tom negativo forte. Em seguida, ele enviará um alerta de texto, se necessário.
Usaremos Sendgrid para se conectar à nossa caixa de correio e Twilio enviará alertas de texto. ## Análise de sentimento: um problema aparentemente simples
Existem palavras que associamos a emoções positivas, como amor, alegria e prazer. E, existem palavras que associamos a emoções negativas, como ódio, tristeza e dor. Por que não treinar o modelo para reconhecer essas palavras e contar a frequência relativa e a força de cada palavra positiva e negativa?
Bem, existem alguns problemas com isso.
Primeiro, existe um problema de negação. Por exemplo, uma frase como 'O pêssego não é ruim' implica uma emoção positiva usando uma palavra que frequentemente associamos a ser negativa. Um simples modelo de saco de palavras não será capaz de reconhecer a negação nesta frase.
Além disso, sentimentos confusos provam ser outro problema da análise ingênua de sentimentos. Por exemplo, uma frase como 'O pêssego não é ruim, mas a maçã é realmente terrível' contém sentimentos mistos de intensidades misturadas que interagem entre si. Uma abordagem simples não será capaz de resolver sentimentos confusos, intensidades diferentes ou interações entre sentimentos.
como fazer um bot de telegrama
A biblioteca Stanford Natural Language Processing para análise de sentimento resolve esses problemas usando uma rede de tensores neurais recursivos (RNTN).
O algoritmo RNTN primeiro divide uma frase em palavras individuais. Em seguida, construa uma rede neural onde os nós são as palavras individuais. Finalmente, uma camada tensorial é adicionada para que o modelo possa ajustar adequadamente as interações entre palavras e frases.
Você pode encontrar uma demonstração visual do algoritmo em seu website oficial .
O grupo de PNL de Stanford treinou a Rede de Tensores Neurais Recursivos usando avaliações de filmes IMDB marcados manualmente e descobriu que seu modelo é capaz de prever sentimentos com uma precisão muito boa.
A primeira coisa a fazer é configurar a integração do e-mail para que os dados possam ser transferidos para o seu bot.
Há muitas maneiras de fazer isso, mas para simplificar, vamos configurar um servidor web simples e usar o gancho de análise de entrada de Sendgrid para canalizar e-mails para o servidor. Podemos encaminhar emails para o endereço de análise de entrada da Sendgrid. Sendgrid enviará uma solicitação POST para nosso servidor web, e então poderemos processar os dados através de nosso servidor.
Para construir o servidor, usaremos Flask, uma estrutura web simples para Pitão .
Além de construir o servidor web, queremos conectar o serviço web a um domínio. Resumindo, deixaremos de escrever sobre isso no artigo. No entanto, você pode ler mais sobre isso Aqui .
Crie um servidor web em Frasco é incrivelmente simples.
Basta criar um app.py
e adicione-o ao arquivo:
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')
Se implementarmos este aplicativo atrás de um nome de domínio e clicarmos no endpoint '/ analisar', você deverá ver algo assim:
como você conduziria entrevistas com usuários se estivesse tentando testar uma interação específica?
> >> requests.post ('http://sentiments.shanglunwang.com:5000/analyze') .text 'Lo tengo'
Em seguida, queremos enviar e-mails para este ponto final.
Você pode encontrar mais documentação Aqui mas basicamente você deseja configurar o Sendgrid para ser o seu processador de e-mail e o Sendgrid encaminhar os e-mails para o nosso servidor web.
Aqui está minha configuração no Sendgrid. Isso encaminhará emails para @sentibot.shanglunwang.com
como solicitações POST para “http://sentiments.shanglunwang.com/analyze”:
Você pode usar qualquer outro serviço que ofereça suporte ao envio de e-mails recebidos por meio de webhooks.
Depois de configurar tudo, tente enviar um e-mail para o endereço do SendGrid. Você deve ver algo assim nos registros:
endpoint hit 2017-05-25 14:35:46
Isso é genial! Agora você tem um bot que pode receber e-mails. Isso é metade do que estamos tentando fazer.
Agora, você quer dar a este bot a capacidade de analisar sentimentos em e-mails.
Como a biblioteca Stanford NLP é escrita em Java, queremos construir o mecanismo de análise em Java.
Vamos começar baixando a biblioteca e os modelos de PNL de Stanford no Maven. Crie um novo projeto Java , adicione o seguinte às suas dependências Maven e importe:
edu.stanford.nlp stanford-corenlp 3.6.0
O mecanismo de análise de sentimento Stanford NLP pode ser acessado especificando o anotador de sentimento no código de inicialização do pipeline. A anotação pode ser recuperada como uma estrutura de árvore.
Para os fins deste tutorial, queremos apenas saber o sentimento geral de uma frase, portanto, não haverá necessidade de analisar a árvore. Só precisamos olhar para o nó base.
o que é bdd em desenvolvimento de software
Isso torna o código principal relativamente simples:
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); } } }
Experimente algumas frases e você verá as anotações apropriadas. Executando os resultados do código de exemplo:
Muy positivo Negativo
Portanto, temos um programa analisador de sentimento escrito em Java e um bot de e-mail escrito em Python. Como fazemos com que eles falem uns com os outros?
Existem muitas soluções possíveis para este problema, mas aqui vamos usar Thrift . Vamos ativar o Sentiment Analyzer como um servidor Thrift e o bot de e-mail como um cliente Thrift.
Thrift é um gerador de código e protocolo usado para permitir que dois aplicativos, muitas vezes escritos em linguagens diferentes, possam se comunicar usando um protocolo definido. As equipes poliglotas usam o Thrift para construir redes de microsserviços para aproveitar o melhor de cada linguagem que usam.
Para usar o Thrift, precisaremos de duas coisas: um arquivo .thrift
para definir os terminais do serviço e um código gerado para fazer uso do protocolo definido no arquivo .proto
. Para o serviço de analisador, o sentiment.thrift
Se parece com isso:
qual deles é usado como uma medida do valor total do fluxo de caixa disponível de um projeto?
namespace java sentiment namespace py sentiment service SentimentAnalysisService { string sentimentAnalyze(1:string sentence), }
Podemos gerar código de cliente e servidor usando este arquivo .thrift. Corre:
thrift-0.10.0.exe --gen py sentiment.thrift thrift-0.10.0.exe --gen java sentiment.thrift
Nota: Construa o código em uma máquina Windows. Você precisará usar o caminho adequado para o executável Thrift em seu ambiente.
Agora, vamos fazer as alterações apropriadas no mecanismo de varredura para criar um servidor. Seu programa Java deve ser semelhante a este:
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); } }
Este manipulador é onde recebemos a solicitação de análise no protocolo Thrift.
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; } }
O analisador usa a biblioteca Stanford NLP para determinar o sentimento do texto e produz uma string contendo as anotações de sentimento para cada frase do texto.
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(); } } }
Observe que eu não incluí o arquivo SentimentAnalysisService.java
aqui porque é um arquivo gerado. Você deve colocar o código gerado em um local onde o restante do seu código possa acessá-lo.
Agora que temos o servidor ativo, vamos escrever um cliente Python para usar o servidor.
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'))
Execute isso e você verá:
Muy positivo
Ótimo! Agora que temos o servidor em execução e conversando com o cliente, vamos integrá-lo ao robô de e-mail instanciando um cliente e conectando-o ao e-mail.
programação de robô c ++
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'
Agora implante seu serviço Java na mesma máquina em que está executando o servidor da web, inicie o serviço e reinicie o aplicativo. Envie um e-mail para o bot com uma frase de teste e você deverá ver algo assim no arquivo de log:
Increíblemente maravillosamente positiva y hermosa frase. Muy positivo
Tudo bem! Agora temos um bot de e-mail que pode realizar análises de sentimento! Podemos enviar um email e receber uma etiqueta de opinião para cada frase que enviarmos. Agora, vamos explorar como podemos tornar a inteligência acionável.
Para manter as coisas simples, vamos nos concentrar em e-mails onde há uma alta concentração de frases negativas e muito negativas. Vamos usar um sistema de pontuação simples e dizer que se um e-mail contiver mais de 75% de sentenças de sentimento negativo, vamos marcá-lo como um potencial e-mail de alarme que pode exigir uma resposta imediata. Vamos implementar a lógica de pontuação no caminho de análise:
@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'
O código acima faz algumas suposições, mas funcionará para fins de demonstração. Envie alguns e-mails para o seu bot e você verá a análise do e-mail nos logs:
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
Estamos quase terminando!
Criamos um bot de email que pode receber emails, realizar análises de sentimento e determinar se um email requer atenção imediata. Agora, só precisamos enviar um alerta de texto quando um e-mail for particularmente negativo.
Usaremos Twilio para enviar um alerta de texto. Sua API Python, que está documentada Aqui , é bastante simples. Vamos modificar o caminho de análise para enviar uma solicitação quando você receber uma solicitação urgente.
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'
Você precisará definir as variáveis de ambiente nas credenciais da sua conta Twilio e definir o número de chamada para um telefone que ele possa verificar. Depois de fazer isso, envie um e-mail para o endpoint da varredura e você verá uma mensagem de texto enviada para o número de telefone em questão.
E terminamos!
Neste artigo, você aprendeu como construir um bot de análise de sentimento de e-mail usando a biblioteca de PNL de Stanford. A biblioteca ajuda a abstrair todos os detalhes essenciais do processamento de linguagem natural e permite que você a use como um bloco de construção para seus aplicativos de PNL.
Espero que este post tenha demonstrado uma das muitas aplicações potenciais incríveis da análise de sentimento, e que isso inspire você a criar sua própria aplicação de PNL.