Sumit Raj
Novatec
São Paulo | 2019
First published in english under the title Building Chatbots with Python; Using Natural Language
Processing and Machine Learning by Sumit Raj, edition: 1
Copyright © Sumit Raj, 2019
This edition has been translated and published under license from Apress Media, LLC, part of
Springer Nature.
Apress Media, LLC, part of Springer Nature takes no responsibility and shall not be made liable for
the accuracy of the translation.
Cover designed by eStudioCalamar
Cover image designed by Freepik ([Link])
Publicação original em inglês intitulada Building Chatbots with Python; Using Natural Language
Processing and Machine Learning por Sumit Raj, edição: 1
Copyright © Sumit Raj, 2019
Esta edição foi traduzida e publicada com a autorização da Apress Media, LLC, parte da Springer
Nature.
Apress Media, LLC, parte da Springer Nature não assume nenhuma responsabilidade pela exatidão
da tradução.
Capa desenvolvida por eStudioCalamar
Imagem da capa desenvolvida por Freepik ([Link])
© Novatec Editora Ltda. [2019].
Todos os direitos reservados e protegidos pela Lei 9.610 de 19/02/1998. É proibida a reprodução
desta obra, mesmo parcial, por qualquer processo, sem prévia autorização, por escrito, do autor e da
Editora.
Editor: Rubens Prates
Tradução: Aldir Coelho Corrêa da Silva
Revisão gramatical: Tássia Carvalho
Editoração eletrônica: Carolina Kuwabata
ISBN: 978-85-7522-810-4
Histórico de edições impressas:
Outubro/2019 Primeira edição
Novatec Editora Ltda.
Rua Luís Antônio dos Santos 110
02460-000 – São Paulo, SP – Brasil
Tel.: +55 11 2959-6529
Email: novatec@[Link]
Site: [Link]
Twitter: [Link]/novateceditora
Facebook: [Link]/novatec
LinkedIn: [Link]/in/novatec
Quero dedicar este livro e todo o difícil trabalho de reaIização dessa façanha
a meu irmão mais velho Nikhil Raj, que se foi ano passado. Difícil imaginar o
quanto ele ficaria orgulhoso ao ver o livro de seu irmão sendo publicado.
Gostaria de agradecer a meus pais Dinanath Prasad e Shobha Gupta, a meu
irmão e irmã, a meus parentes e a todos os queridos amigos que sempre me
apoiaram, encorajaram e perdoaram minha ausência durante a redação deste
livro.
Informação importante
Os exemplos de chatbots mostrados no livro utilizam o idioma inglês. As
bibliotecas de NLP (Natural Language Processing – Processamento de
Linguagem Natural), fundamentais para a construção de chatbots estão
configuradas em 'en', ou seja, english (inglês), mas essas mesmas
bibliotecas também possuem a opção para o português. Os textos desses
exemplos foram traduzidos para português somente para ajudar o leitor
brasileiro a entender melhor esses exemplos, e não fazem parte da sintaxe
original. A construção de chatbots é um assunto relativamente recente e
muito dinâmico. É possível que algum dos softwares utilizados no livro
tenha uma versão mais recente no momento em que você estiver lendo este
livro. Os leitores podem encaminhar perguntas (em inglês) sobre o livro
através do site [Link]
Sumário
Sobre o autor
Sobre o revisor técnico
Agradecimentos
Introdução
Capítulo 1 ■ Os queridos chatbots
Popularidade do uso dos chatbots
O Zen do Python e por que ele é aplicável aos chatbots
A necessidade do uso de chatbots
Ponto de vista da empresa
Ponto de vista do desenvolvedor
Indústrias beneficiadas pelos chatbots
Resumo cronológico dos chatbots
Que tipo de problemas posso resolver usando chatbots?
Pode ser resolvido por pergunta e resposta ou conversa simples?
Tem tarefas altamente repetitivas que demandem a analise ou a busca de
dados?
A tarefa de seu bot pode ser automatizada e resolvida?
Bot de P&R
Etapas iniciais para a construção de chatbots
Árvores de decisão em chatbots
Usando árvores de decisão em chatbots
Como a árvore de decisão ajuda?
Os melhores frameworks de chatbots/bots
Componentes de um chatbot e terminologias usadas
Intenção
Entidades
Enunciados
Treinando o bot
Pontuação de confiança
Capítulo 2 ■ Natural Language Processing para Chatbots
Por que preciso conhecer NLP para construir um chatbot?
O que é spaCy?
Resultados de avaliações do spaCy
O que o spaCY fornece?
Recursos do spaCy
Instalação e pré-requisitos
O que são os modelos do SpaCy?
Métodos básicos de NLP para a construção de chatbots
Marcação POS
Stemização e lematização
Reconhecimento de entidades nomeadas
Stopwords
Parsing de dependências
Noun chunks
Buscando semelhanças
É bom conhecer os recursos de NLP para chatbots
Tokenização
Expressões regulares
Resumo
Capítulo 3 ■ Construindo chatbots da maneira mais fácil
Introdução ao Dialogflow
Partindo para a ação
Construindo um chatbot de pedido de comida
Definindo o escopo
Listando as intenções
Listando entidades
Construindo um chatbot de pedido de comida
Começando a usar o Dialogflow
Pontos que devemos lembrar ao criar intenções
Criando intenções e adicionando enunciados
Adicionando a resposta padrão à intenção
Intenção de descrição de itens e entidades relacionadas
Entendendo e respondendo para o usuário
Implantando o chatbot do Dialogflow na web
Integre o chatbot do Dialogflow ao Facebook Messenger
Configurando o Facebook
Criando um aplicativo do Facebook
Configurando o console do Dialogflow
Configurando Webhooks
Testando o bot do Messenger
Fulfillment
Ativando o webhook
Verificando a resposta
Resumo
Capítulo 4 ■ Construindo chatbots da maneira mais difícil
O que é Rasa NLU?
Por que devo usar o Rasa NLU?
Passando diretamente à prática com o Rasa NLU
Treinando e construindo um chatbot a partir do zero
Construindo um bot de horóscopo
Conversa entre o bot de horóscopo e o usuário
Preparando dados para o chatbot
Treinando o modelo do chatbot
Fazendo previsões a partir do modelo
Gerenciamento de diálogo com o uso do Rasa Core
Entendendo melhor o Rasa Core e o sistema de diálogo
Entendendo os conceitos do Rasa
Criando o arquivo domain para o chatbot
Criando as ações personalizadas do chatbot
Preparação de dados para treinamento do bot
Criando dados de story
Aprendizado interativo
Exportando conversas como stories
Testando o bot
Caso de teste 1
Caso de teste 2
Resumo
Capítulo 5 ■ Implantando seu chatbot
Primeiras etapas
Gerenciamento de credenciais do Rasa
Implantando o chatbot no Facebook
Criando um aplicativo no Heroku
Instalando o Heroku em seu sistema local
Criando e configurando um aplicativo no Facebook
Criando e implantando o aplicativo de servidor de ações do Rasa no
Heroku
Criando o aplicativo de API do chatbot Rasa
Criando um script independente para o chatbot do Facebook Messenger
Verificando a implantação do aplicativo de gerenciamento de diálogo no
Heroku
Integrando o webhook ao Facebook
Verificação pós-implantação: chatbot do Facebook
Implantando o chatbot no Slack
Criando um script independente para o chatbot do Slack
Editando seu procfile
Implantação final do bot do Slack no Heroku
Inscreva-se em eventos do Slack
Inscreva-se em eventos do bot
Verificação pós-implantação: bot do Slack
Implantando o chatbot por sua própria conta
Escrevendo um script para o canal de seu próprio chatbot
Criando o procfile e implantando-o na web
Verificando as APIs de seu chatbot
Criando a UI do chatbot
Resumo
Sobre o autor
Sumit Raj é um profissional técnico, que adora codificar e construir
aplicações. É especialista em Python e tem muito interesse em Machine
Learning e Natural Language Processing (NLP, Processamento de
Linguagem Natural). Ele acredita na ideia de escrever códigos que afetem
diretamente a receita da empresa.
Sumit trabalhou em várias áreas, como gerenciamento de finanças
pessoais, bens imóveis, e-commerce, e análise de receitas, para as quais
construiu diversas aplicações escaláveis. Ajudou muitas startups novas no
design e na arquitetura iniciais de seus produtos, que acabaram sendo
patrocinados por investidores e governos. Tem boa experiência em
tecnologias de ponta usadas em aplicações de internet/empresas para
escalabilidade, ajuste de desempenho, otimização e redução de custos.
Além disso, tem atuado como mentor de alunos/desenvolvedores de
programação em Python no mundo todo. Foi mentor de mais de 1.000
alunos e profissionais usando várias plataformas e canais online e offline
nas áreas de linguagens de programação, ciência de dados e
aconselhamento de carreira. Sumit gosta de participar de meetups técnicos,
conferências e workshops. Ele não gosta de perder oportunidades de
participar de hackathons. Sua paixão pelo desenvolvimento de aplicações e
pela resolução de problemas o fez ganhar vários prêmios e elogios. Ele é
convidado regularmente para palestrar nos principais institutos
pedagógicos da Índia. Também é orador no grupo meetup PyLadies,
mulheres que codificam em Python, liderado por um dos antigos diretores
da PSF (Python Software Foundation).
Em seu tempo livre, gosta de escrever em seu blog e responder a perguntas
sobre programação de computadores, chatbots, Python/Django,
aconselhamento de carreira e desenvolvimento web no Quora, tendo ao
todo mais de um milhão de visualizações. Fique à vontade para lhe fazer
perguntas em inglês em seu perfil no Quora.
Atualmente, Sumit trabalha como Arquiteto de Soluções Sênior na
GeoSpark R&D em Bangalore, Índia, construindo uma plataforma de
desenvolvedor para rastreamento de localização. Saiba mais sobre ele no
site ([Link] Os leitores também podem fazer perguntas e
discutir assuntos em inglês em [Link]
Sobre o revisor técnico
Nitin Solanki tem vasta experiência em Natural Language Processing,
machine learning e desenvolvimento de chatbots com inteligência artificial
(IA). Desenvolveu chatbots com IA para várias áreas, como assistência
médica, e-commerce, educação, firmas de advocacia e muitas outras. Tem
experiência no trabalho com bibliotecas NLP, mineração de dados, limpeza
de dados, engenharia de recursos, análise e visualização de dados, e
algoritmos de machine learning. Nitin adora simplificar e automatizar as
coisas. Em seu tempo livre, sua mente começa a divagar sobre como
ganhar dinheiro. Logo, ele mantém a mente ocupada com a exploração de
tecnologias e a criação de códigos.
Agradecimentos
Este livro é resultado do trabalho mais difícil e sincero que realizei em
minha carreira. Passei muitas noites sem dormir para concluí-lo. Serei grato
ao meu pai e à minha mãe por toda a minha vida por terem me tornado
quem sou hoje. Quero agradecer a meu irmão Nitish e à minha irmã Prity
por estarem sempre ao meu lado e compartilharem toda a compreensão e
emoção sem que precisasse lhes pedir isso.
Esta seção de agradecimento não estaria completa se eu não agradecesse à
incrível equipe da Apress, inclusive Nikhil e Divya, que foram tão pacientes
e solidários comigo da aquisição à publicação do livro. São as melhores
pessoas com quem já trabalhei. Um agradecimento especial a Matt pela
orientação de que precisei em meu primeiro livro e pelo contínuo feedback
a cada etapa para melhorá-lo. Muito obrigado a Nitin pela revisão técnica e
por sugerir edições.
Introdução
Este livro foi escrito com muito cuidado para que seus ensinamentos
fossem pragmáticos e orientados a resultados. Construir chatbots não é
apenas ler um tutorial ou seguir algumas etapas – trata-se de uma
habilidade. O livro que você tem em mãos certamente não o entediará com
uma quantidade enorme de texto e processos para serem lidos; em vez
disso, ele usa a abordagem de aprender fazendo. Você já deve ter utilizado
pelo menos um chatbot para fazer algo em seu dia a dia. Seja ou não um
programador, ao percorrer este livro você deparará com os blocos de
construção dos chatbots e todos os mistérios serão revelados. Olhando de
fora, pode parecer difícil construir chatbots, mas este texto facilitará muito
as coisas para você. Nosso cérebro não foi projetado para processar
conceitos complexos diretamente; na verdade, aprendemos por etapas.
Quando você estiver lendo este livro, do primeiro ao último capítulo,
perceberá a facilidade com que o processo progride. Embora possa ler
qualquer capítulo, recomendo que comece pelo primeiro, porque com
certeza ele estimulará seu raciocínio.
O livro foi escrito como uma série da web na qual não conseguimos esperar
pelo próximo capítulo após ler o anterior. Qualquer chatbot com o qual
você interagir após a leitura o fará pensar sobre como ele foi projetado e
construído internamente.
Para quem é este livro
O livro servirá como um ótimo recurso para quem quiser conhecer os
conceitos relacionados aos chatbots e aprender como construí-los. Entre
aqueles que o acharão útil estão:
• Desenvolvedores web Python querendo expandir o conhecimento ou
alavancar a carreira com o desenvolvimento de chatbots.
• Alunos e aspirantes a programador que quiserem construir um novo
conjunto de habilidades pela experiência prática para exibir suas
aptidões e se destacar na multidão.
• Entusiastas da linguagem natural querendo aprender a construir um
chatbot a partir do zero.
• Empreendedores iniciantes com uma ótima ideia, mas sem informações
suficientes de viabilidade técnica sobre como criar um chatbot.
• Gerentes de produto/engenharia com planos de criar um projeto
baseado em chatbot.
Como devo usar o livro?
Lembre-se de que este livro não foi escrito como os outros o são, mas, sim,
com a intenção de que, quando terminar de lê-lo, você consiga construir
um chatbot ou ensinar alguém a construí-lo. É muito importante lembrar-
se de alguns pontos antes de ler o livro:
• Ele aborda quase tudo que é necessário para a construção de um
chatbot, e não apenas o que existe.
• É esperado que você se mantenha trabalhando em seu sistema com o
livro ao lado. Certifique-se de executar cada fragmento de código e de
tentar escrevê-lo; não copie e cole.
• Não deixe de seguir as etapas à medida que elas aparecerem no livro;
não se preocupe se não entender algo. Você obterá informações sobre o
assunto posteriormente no capítulo.
• Use o código-fonte e o Jupyter Notebook fornecidos com o livro para
sua referência.
O que você aprenderá neste livro?
Capítulo 1: Os queridos chatbots. Nesse capítulo, você aprenderá
conceitos relacionados aos chatbots do ponto de vista tanto empresarial
quanto do desenvolvedor. Ele o preparará para lidar diretamente com os
conceitos relacionados aos chatbots e convertê-los em código. O esperado
é que, ao terminar o capítulo, você tenha um motivo para construir um
chatbot para si próprio ou sua empresa.
Capítulo 2: Natural Language Processing para Chatbots. Nesse capítulo,
você aprenderá que ferramentas e métodos deve usar quando o NLP for
necessário nos chatbots. Além de ensinar o método de NLP, ele abordará
situações da vida real e fará demonstrações com exemplos de codificação.
Também discutirá por que um método de NLP específico pode ser
necessário em um chatbot. Lembre-se de que o NLP é por si só uma
habilidade que devemos ter.
Capítulo 3: Construindo chatbots de maneira fácil. Esse capítulo ensinará
a construir um chatbot de maneira fácil e descomplicada usando
ferramentas como o Dialogflow. Se você não é programador, certamente
vai gostar, porque será necessária pouca ou nenhuma habilidade em
programação.
Capítulo 4: Construindo chatbots de maneira difícil. Nesse capítulo, você
aprenderá a construir chatbots como as pessoas gostam de construí-los. O
título diz que é da maneira mais difícil, mas, assim que você terminar o
capítulo anterior, vai querer mais, já que esse capítulo ensinará a construir
chatbots em casa a partir do zero e a treiná-los usando algoritmos de
machine learning.
Capítulo 5: Implantando seu chatbot. Esse capítulo foi elaborado
exclusivamente para você dar ao seu aplicativo de chatbot um último
empurrão. Após ter aprendido as maneiras fácil e difícil de construir um
chatbot, certamente você não vai querer guardá-lo para si. Portanto,
aprenderá a lançar seus chatbots para o mundo inteiro usando o Facebook
e o Slack e, por fim, a integrá-los ao seu próprio site.
CAPÍTULO 1
Os queridos chatbots
Para começar a construir um chatbot, é importante sabermos o que eles
fazem e como são.
Você já deve ter ouvido falar no Siri, IBM Watson, Google Allo etc. O
problema básico que esses bots tentam resolver é tornar-se um
intermediário e ajudar os usuários a serem mais produtivos. Eles fazem isso
permitindo ao usuário se preocupar menos com como as informações serão
recuperadas e com o formato de entrada que pode ser necessário para a
obtenção de dados específicos. Os bots tendem a se tornar cada vez mais
inteligentes à medida que manipulam a entrada de dados do usuário e
extraem mais informações dela. Os chatbots são bem-sucedidos porque
nos dão exatamente o que queremos.
Você fica irritado ou frustrado quando tem de inserir o mesmo nome, ID
de email, endereço e pincode em diferentes sites? Imagine um bot
executando suas tarefas – digamos, comprar comida em diferentes
fornecedores, fazer compras online em várias empresas de e-commerce ou
reservar um voo ou passagens de trem – e não ser necessário fornecer
sempre o mesmo ID de email, endereço de entrega ou informações de
pagamento. O bot já conhece essas informações e é suficientemente
inteligente para recuperar o que é necessário quando você solicita em seu
próprio idioma ou no que é conhecido em ciência da computação como
Linguagem Natural.
Desenvolver chatbots é muito mais fácil do que era há alguns anos, mas
eles também existiam décadas atrás; no entanto, a popularidade dos
chatbots aumentou exponencialmente nos últimos anos.
Se você é um técnico ou tem alguma ideia de como uma aplicação web ou
móvel funciona, já deve ter ouvido falar no termo APIs. Qualquer tipo de
dado necessário atualmente está disponível para consumo na forma de
APIs fornecidas por diferentes provedores de serviço e instituições. Se
quisermos informações relacionadas ao clima, à reserva de passagens, à
compra de alimentos, à obtenção de informes de voos, à conversão de uma
linguagem em outra ou à postagem no Facebook ou Twitter, tudo isso
pode ser feito com o uso de APIs. As APIs são utilizadas por aplicações web
ou móveis para executar essas tarefas. Os chatbots também podem usá-las
para executar as mesmas tarefas conforme o que pedirmos.
Os chatbots ganharam vantagem sobre os métodos tradicionais de
execução de tarefas online porque podemos fazer várias coisas com sua
ajuda. Não é apenas um chatbot, é mais como um assistente pessoal
virtual. Seja para reservar um quarto de hotel no [Link] ou uma
mesa em um restaurante próximo, você pode fazer isso usando seu
chatbot. Os chatbots conseguem ser multitarefa e, portanto, economizam
muito tempo e dinheiro.
Neste livro, vamos aprender a construir experiências de conversação
natural usando bots e a ensinar um bot a entender nossa linguagem natural
e fazê-lo executar tarefas para nós a partir de uma única interface.
Os bots em geral são apenas uma máquina suficientemente inteligente para
entender nossa solicitação e formulá-la de tal forma que seja entendida por
outros sistemas de software para a obtenção dos dados solicitados.
Popularidade do uso dos chatbots
Os chatbots se popularizaram como tantas outras coisas do passado
recente. Na Figura 1.1, que mostra a ascensão dos chatbots, podemos
tentar entender por que há uma grande demanda pela sua construção.
Figura 1.1 – Os números do eixo Y representam o interesse em buscas
mundiais em relação ao ponto mais alto do gráfico em todas as categorias
A resposta mais simples que nos vem à mente é que o chatbot não é um
software complexo e pode ser usado por qualquer pessoa. Quando
construímos um software, o destinamos ao público que vai usá-lo, mas,
quando ele é usado por qualquer pessoa, torna-se difícil e inútil. Ao
construir chatbots, temos de nos lembrar de que eles serão usados por
pessoas de todas as faixas etárias. Isso só ocorre no caso dos chatbots, em
que o software tenta se comportar como uma pessoa neutra (mas
inteligente) e permite ao usuário ser quem ele realmente é. Em todos os
outros programas, percebemos que é preciso conhecer a terminologia ou
aprender gradualmente a melhor maneira de usá-los, mas isso não ocorre
com os chatbots. Se você souber como conversar com alguém, não terá
problemas para usar um chatbot.
Há uma demanda crescente e contínua pelos chatbots. No entanto, poucas
pesquisas tentaram descobrir empiricamente as motivações existentes por
trás do seu uso. Em um estudo recente, um questionário online pediu a
usuários de 16 a 55 anos nos Estados Unidos que descrevessem por que
precisavam de chatbots em seu dia a dia. A pesquisa revelou a
"produtividade" como sendo o principal fator motivacional para o uso de
chatbots.
O Zen do Python e por que ele é aplicável aos chatbots
Lembro-me do Zen do Python, que diz "Simples é melhor que complexo",
e isso se aplica a muitos aspectos dos programas.
O Zen do Python é um conjunto de 20 princípios de desenvolvimento
de software que influenciam o design da linguagem de programação
Python.
– Tim Peters
Quer saber "O que é Zen do Python?". Siga as etapas a seguir.
Se você já tem o Python instalado em seu computador, acesse seu
interpretador Python e execute import this:
Python 2.7.15 (default, May 1 2018, 16:44:08)
[GCC 4.2.1 Compatible Apple LLVM 9.1.0 (clang-[Link])] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import this
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one – and preferably only one – obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea – let's do more of those!
Tradução livre:
Nota: O Zen do Python:
Bonito é melhor que feio.
Explícito é melhor que implícito.
Simples é melhor que complexo.
Complexo é melhor que complicado.
Linear é melhor do que aninhado.
Esparso é melhor que denso.
Legibilidade é importante.
Casos especiais não são especiais o bastante para quebrar as regras.
Ainda que praticidade vença a pureza.
Erros nunca devem passar silenciosamente.
A menos que sejam explicitamente silenciados.
Diante da ambiguidade, recuse a tentação de adivinhar.
Deveria haver um — e preferencialmente só um — modo óbvio para fazer algo.
Embora esse modo possa não ser óbvio a princípio a menos que você seja holandês.
Agora é melhor que nunca.
Embora nunca frequentemente seja melhor que *já*.
Se a implementação é difícil de explicar, é uma má ideia.
Se a implementação é fácil de explicar, pode ser uma boa ideia.
Namespaces são uma grande ideia — vamos ter mais dessas!
Talvez nem todos os pontos anteriores façam sentido no que diz respeito
aos chatbots, mas a maioria certamente faz.
Voltando ao nosso tópico, lembro-me de que achei difícil começar a usar a
interface de usuário do Facebook já que minha experiência anterior foi
com o Orkut. Se você nunca usou o Orkut, não vai entender, mas pense
em uma situação em que começou a usar algum software ou aplicação e
teve problemas para dominá-lo. Talvez em uma mudança do Windows
para o MacOS/Linux ou vice-versa. Quando usamos uma aplicação nova,
temos de aprender algumas coisas, e leva tempo para se acostumar e saber
o que ela faz e como funciona. Às vezes só tomamos conhecimento da
existência de alguns recursos da aplicação anos depois de começar a usá-la.
Se você está usando o MacOS, pressione Shift + Option + aumentar/diminuir volume
e veja o que acontece. Diga-me se ficou surpreso, se ainda não conhecia o
recurso.
No caso dos chatbots, a comunicação entre o usuário e o servidor ou o
sistema backend é muito simples. É como falar com outra pessoa usando
um aplicativo de troca de mensagens.
Você só digita o que deseja e o bot tem de fornecer o que foi solicitado ou
mostrar como obtê-lo. Em outras palavras, ele deve conduzi-lo para as
informações corretas fornecendo um link ou documento. Atualmente os
bots podem até mesmo procurar a informação em um artigo ou
documento e fornecê-la aos usuários.
Um progresso significativo na IA de empresas como Google, Facebook e
IBM e de serviços de machine learning como o Amazon Lex, [Link], [Link],
[Link], IBM Watson, Amazon Echo etc. levou a um enorme crescimento e
demanda desses robôs.
A necessidade do uso de chatbots
Agora tentaremos examinar o porquê da necessidade e da demanda de
chatbots nessa crescente era de criação e recuperação de informações a
partir de dois pontos de vista diferentes: o da empresa e o do
desenvolvedor. Logo, se você é um gerente de produto, gerente de vendas
ou é da área de marketing ou de qualquer área relacionada que conduza o
negócio diretamente, não deve pular o ponto de vista empresarial dos
chatbots. Ele fornecerá uma imagem clara do que as empresas atuais
precisam para adotar essa tecnologia e aumentar as receitas.
Ponto de vista da empresa
Tentaremos investigar o ponto de vista empresarial dos chatbots. É bom
para a empresa ter um chatbot ou passar vários serviços para ele?
Chegou a hora de as empresas tratarem os chatbots como uma das
ferramentas de marketing dessa geração.
• Acessibilidade: Eles são fáceis de acessar. O consumidor pode abrir o
site e começar a fazer perguntas ou resolver suas consultas sem ter de
discar um número e seguir as incômodas etapas "Pressione 1 para isso e
2 para aquilo" na Unidade de Resposta Audível (IVR, Interactive Voice
Response). Ele pode chegar rapidamente aonde quer apenas com um
conjunto básico de informações.
• Eficiência: Os clientes podem sentar-se em sua cadeira no escritório ou
em uma poltrona em sua sala de estar enquanto jogam um game e veem
seu status em uma aplicação de cartão de crédito, pesquisam em que
nível está seu pedido de comida ou fazem uma reclamação sobre algum
problema.
Se você tornar seus clientes eficientes e produtivos, eles o adorarão. Os
bots fazem exatamente isso e ajudam a melhorar os negócios.
• Disponibilidade: Os chatbots ficam disponíveis 24 horas por dia, 7 dias
por semana. Eles nunca lhe pedirão que saia mais cedo ou ficarão
cansados como os empregados humanos. Executarão as mesmas tarefas
ou serviços novos sempre com a mesma eficiência e desempenho.
Ficamos frustrados quando a gravação de um serviço de atendimento
ao cliente nos diz "Favor ligar entre 9h e 16h" quando queremos apenas
uma simples informação. Seus bots nunca diriam isso.
• Escalabilidade: Um bot => 1 milhão de funcionários. Entende o que
quero dizer? Sim, se seu bot puder dar o que o cliente deseja,
conseguirá manipular facilmente centenas de milhares de consultas de
clientes ao mesmo tempo sem se cansar. Você não precisa manter seus
clientes esperando na fila até o atendente estar livre.
• Custo: Desnecessário dizer que os chatbots economizam muito
dinheiro para a empresa. Quem não gosta de economizar? Se os bots
fazem isso para nós, não há razão para não gostar deles.
• Insights: Seu consultor de vendas pode não se lembrar do
comportamento do usuário e lhe dar algum insight exclusivo sobre o
padrão comportamental do consumidor, mas os bots podem usar as
técnicas mais recentes de machine learning e ciência de dados.
Os chatbots trazem receita
Os chatbots mostraram-se bem-sucedidos na geração de mais receita para a
empresa. As empresas que começaram a dar suporte a chatbots ou que
criaram um novo chatbot para atender consultas de clientes estão se saindo
bem no mercado em comparação com seus concorrentes.
De acordo com um dos posts do blog [Link], nos 2 primeiros meses
após introduzir seu chatbot do Facebook, a [Link] relatou que
mais de 70% de seus pedidos no Messenger eram de novos clientes. Em
geral, esses novos clientes também eram mais jovens que o consumidor
típico da empresa, já que estavam familiarizados com o aplicativo
Facebook Messenger. Isso aumentou significativamente sua renda anual.
Um dos maiores benefícios que os chatbots podem trazer é quando os
usamos para prospectar clientes. Você pode alcançar possíveis clientes
diretamente onde está sua atenção (mensageiros) e apresentar a eles
seus mais novos produtos, serviços ou mercadorias. Se o cliente quiser
comprar um produto/serviço, ele pode fazer a compra dentro do
chatbot e inclusive processar o pagamento. Bots como o da 1-800-
[Link], eBay e Fynd provaram isso.
– Julien Blancher, cofundador da [Link]
Em um artigo de Stefan Kojouharov, fundador do ChatbotsLife, ele
menciona como diferentes empresas estão ganhando mais dinheiro do que
ganhariam sem os chatbots. Stefan diz:
O espaço de e-commerce começou a usar chatbots de várias maneiras que
estão rapidamente adicionando dólares aos seus resultados. Examinaremos
as primeiras histórias de sucesso:
• 1-800-Flowers: relatou que mais de 70% de seus pedidos no Messenger
são de novos clientes!
• Sephora: aumentou os agendamentos de tratamento de beleza em 11%
por meio de um chatbot no Facebook Messenger.
• Nitro Café: aumentou as vendas em 20% com seu chatbot do
Messenger, que foi projetado para facilitar pedidos, fornecer
pagamentos diretos e possibilitar comunicação bidirecional instantânea.
• Sun's Soccer: os chatbots trouxeram quase 50% dos usuários de volta
ao site nas coberturas de futebol; 45% dos assinantes dos chatbots
clicaram no serviço durante seu melhor período.
• Asos: aumentou os pedidos em 300% usando chatbots do Messenger e
obteve 250% de retorno sobre as despesas alcançando ao mesmo tempo
3,5 vezes mais pessoas.
A Figura 1.2 tenta mostrar por que há uma correlação direta entre os
chatbots e a receita. Examine-a para ter uma ideia do que ocorre.
Figura 1.2 – Os chatbots aumentam a renda.
Visão geral do uso dos chatbots
Tentaremos demonstrar como os chatbots têm sido úteis para os
consumidores devido a sua usabilidade e à eficiência que proporcionam.
Quem está vivenciando essa urgente era de TI quer ser rápido em tudo, e
usar chatbots torna as tarefas diárias mais fáceis e velozes. Os chatbots são
personalizados de forma a não precisarmos repetir coisas óbvias; isso nos
faz repensar o uso tradicional dos programas. A Figura 1.3 fornece uma
ilustração que dá uma boa ideia sobre o uso dos chatbots.
Figura 1.3 – Visão geral do uso de chatbots pelos consumidores.
Os clientes preferem os chatbots
Os chatbots não são apenas software na era moderna. São como nossos
assistentes pessoais que nos entendem e podem ser microconfigurados.
Lembram-se do que gostamos e não gostamos e nunca tendem a nos
desapontar esquecendo-se do que já lhes ensinamos, e é por isso que todos
gostam deles. Na próxima vez que você encontrar uma pessoa ou seu
cliente, não se esqueça de perguntar se ele prefere o software convencional
ou a nova tecnologia de ponta dos chatbots. Examinaremos a Figura 1.4
para entender por que os clientes preferem os chatbots em vez de outros
sistemas de software para interações humano-computador.
Figura 1.4 – Os clientes preferem os chatbots.
Na próxima seção deste capítulo, discutiremos por que os chatbots são a
grande novidade para desenvolvedores iniciantes. Seja você um
desenvolvedor mais novo, de nível médio ou um especialista com
experiência, é preciso saber o que está disponível aos desenvolvedores para
a criação de chatbots.
Ponto de vista do desenvolvedor
Você já se sentiu incomodado quando precisa fazer a atualização do
sistema operacional de seu computador ou telefone, ou de algum outro
aplicativo para utilizar novos recursos? E se não houvesse tanta
necessidade de atualizar o aplicativo para usar esses recursos? Ou
suponhamos que, em vez de ter muitos aplicativos, você pudesse ter apenas
um que fizesse a maioria das coisas que atualmente são feitas por vários?
Para os desenvolvedores, é divertido construir bots. É como ensinar seu
filho a andar, falar, comportar-se e fazer coisas. Gostamos de torná-lo mais
inteligente e autossuficiente. Do ponto de vista do desenvolvedor, os
chatbots são um assunto que é preciso conhecer.
Lançamentos de recursos e correções de bugs
Muitos recursos podem ser adicionados facilmente ao chatbot sem que os
usuários precisem atualizar o aplicativo. Seria um problema se você
lançasse uma versão do aplicativo com algum bug, tivesse de corrigi-lo e
lançar novamente na AppStore para aprovação e, o mais importante,
depois de tudo isso os usuários tivessem de atualizar o aplicativo. Se eles
não o atualizarem, o cliente reclamará do problema, o que resultará em
perda de produtividade para todos. Nos chatbots, tudo é baseado em API,
logo, só corrigimos o problema no backend, implantamos as alterações em
PRODUÇÃO e pronto – problema resolvido para seus usuários sem
qualquer preocupação. Você também economizará muito tempo com bugs
relatados pelo usuário.
Suponhamos que você construísse um bot para encontrar restaurantes e
posteriormente quisesse adicionar o recurso de busca de hotéis, voos etc.
Os usuários poderão solicitar com facilidade essas informações, e o sistema
backend do chatbot se encarregará de tudo.
Agora digamos que você estivesse construindo um chatbot do Facebook
Messenger; poderia controlar quase tudo, inclusive a interface que o
usuário verá no aplicativo, diretamente a partir do backend. Nos bots do
Facebook Messenger, é possível escolher se o usuário clicará em um botão
para selecionar Sim/Não ou apenas inserirá texto.
Demanda de mercado
Cinquenta e quatro por cento dos desenvolvedores do mundo todo
trabalharam em chatbots pela primeira vez em 2016. Há uma grande
demanda pela construção de um chatbot simples que trabalhe para as
empresas e elas estão procurando desenvolvedores que possam construí-lo.
Assim que você terminar o Capítulo 3, aposto que já poderá começar a
vender seus serviços facilmente para as empresas. Você também pode criar
a própria startup na área em que se especializou introduzindo um chatbot
para esse ramo. Conseguir construir um chatbot end-to-end (ponta a
ponta) é uma nova habilidade que precisamos ter, e é por isso que a
remuneração média que o mercado paga é muita boa para desenvolvedores
de chatbots.
A crescente demanda pode ser vista no número de chatbots que estão
sendo desenvolvidos em plataformas de desenvolvedor como o Facebook.
Ele tem 100.000 bots ativos mensalmente na plataforma Messenger,
número que só aumenta. É surpreendente saber que o Messenger tinha 600
milhões de usuários em abril de 2015, os quais aumentaram para 900
milhões em junho de 2016, 1 bilhão em julho de 2016 e 1,2 bilhão em abril
de 2017.
Curva de aprendizado
Tendo você experiência em frontend/backend ou sabendo programar
muito pouco, há grandes oportunidades de aprender coisas novas quando
estamos construindo ou aprendendo a construir um chatbot. Nesse
processo, você deparará com muitos assuntos. Por exemplo, conhecerá
melhor a Interação Humano-Computador (HCI, Human Computer
Interaction), que aborda o design e o uso da tecnologia da computação,
com ênfase nas interfaces entre as pessoas e os computadores. Aprenderá a
construir ou usar APIs ou web services, empregando APIs de terceiros
como as do Google, Twitter, Uber etc. Também terá uma ótima
oportunidade de conhecer o Natural Language Processing, o machine
learning, o comportamento do consumidor e muitos outros assuntos
técnicos e não técnicos.
Indústrias beneficiadas pelos chatbots
Vejamos um resumo das indústrias que se beneficiarão mais com os
chatbots. Um estudo da Mindbowser em conjunto com o Chatbots Journal
coletou dados de mais de 300 pessoas que faziam parte de um amplo grupo
de indústrias, entre elas o comércio varejista online, empresas de aviação,
logística, cadeia de suprimentos (supply chain), e-commerce,
hospitalidade, educação, tecnologia, manufatura, e marketing &
propaganda. Se examinarmos o gráfico da Figura 1.5, fica muito claro que
as indústrias de e-commerce, seguros, assistência médica e comércio
varejista são as que mais se beneficiarão dos chatbots. Essas indústrias
dependem pesadamente de uma resposta eficiente da equipe de
atendimento ao cliente que ajude a economizar tempo. Já que o chatbot faz
isso bem, é claro que ele será adotado nesses segmentos com muita
rapidez.
Atualmente, os chatbots ainda estão sendo avaliados em setores mais
novos de diferentes formas. Os próximos 5 a 10 anos serão cruciais para se
espalharem pelo mundo em vários segmentos sem experiência no seu uso.
Figura 1.5 – Segmentos industriais que se beneficiarão mais dos chatbots.
Resumo cronológico dos chatbots
Veremos um breve histórico com a linha do tempo de como os chatbots
foram formulados. É muito importante saber de onde veio sua tecnologia e
como ela foi modelada. Definitivamente os chatbots ganharam
popularidade nos últimos anos, mas os esforços vêm sendo feitos durante
décadas de trabalho com essa tecnologia. Tenho certeza de que o histórico
dos chatbots o surpreenderá com relação a quanto avançamos desde o
começo.
• 1950 – O teste de Turing foi desenvolvido por Alan Turing. Ele testava
a habilidade de uma máquina exibir comportamento inteligente
equivalente ao, ou indistinguível do, de um humano.
• 1966 – Eliza, o primeiro chatbot, foi criada por Joseph Weizenbaum,
projetada para ser uma terapeuta. Ela simulava uma conversa usando
uma metodologia de "comparação de padrões" e substituição que dava
aos usuários a impressão de compreensão por parte do bot.
• 1972 – Parry, um programa de computador do psiquiatra e cientista de
Stanford Kenneth Colby, modelava o comportamento de esquizofrenia
paranoide.
• 1981 – O chatbot Jabberwocky foi criado pelo programador britânico
Rollo Carpenter. Ele começou a ser criado em 1981 e foi lançado na
internet em 1997.
O objetivo desse chatbot era "simular uma conversa humana natural de
maneira interessante, agradável e bem-humorada".
• 1985 – O robô de brinquedo wireless, Tomy Chatbot, repete
mensagens gravadas em sua fita.
• 1992 – Dr. Sbaitso, um chatbot criado pela Creative Labs para o MS-
DOS, "conversava" com o usuário como se fosse um psicólogo em voz
digitalizada. Palavrões repetidos e entradas mal elaboradas fornecidos
pelos usuários fizeram o Dr. Sbaitso "travar" em um "ERRO DE
PARIDADE" antes que pudesse se reinicializar.
• 1995 – A.L.I.C.E (Artificial Linguistic Internet Computer Entity) foi
desenvolvida pelo ganhador do Prêmio Nobel Richard Wallace.
• 1996 – Hex, desenvolvido por Jason Hutchens, foi baseado na Eliza e
ganhou o Prêmio Loebner em 1996.
• 2001 – Smarterchild, um bot inteligente desenvolvido pela
ActiveBuddy, foi amplamente distribuído em trocas de mensagens
instantâneas globais e redes SMS. A implementação original evoluiu
rapidamente para dar acesso instantâneo a notícias, previsão do tempo,
informações do mercado de ações, horários de sessões de cinema,
listagens de páginas amarelas e dados detalhados de esportes, além de
fornecer várias ferramentas (assistente pessoal, calculadoras, tradutor
etc.).
• 2006 – A ideia do Watson foi concebida em um jantar; ele estava sendo
projetado para competir no programa de TV "Jeopardy". Em sua
primeira tentativa, só acertou cerca de 15% das perguntas, mas depois
conseguiu vencer concorrentes humanos regularmente.
• 2010 – O Siri, um assistente pessoal inteligente, foi lançado como um
aplicativo do iPhone e depois integrado como parte do iOS. Ele é
resultado de um esforço do Centro de Inteligência Artificial da SRI
International. Seu mecanismo de reconhecimento de fala foi fornecido
pela Nuance Communications; o Siri usa tecnologias avançadas de
machine learning para funcionar.
• 2012 – O Google lançou o chatbot Google Now. Originalmente seu
codinome era "Majel" em homenagem a Majel Barrett, esposa de Gene
Roddenberry e voz dos sistemas de computador da franquia Star Trek;
Também recebeu o codinome "Assistant".
• 2014 – A Amazon lançou a Alexa. A palavra "Alexa" tem uma
consoante forte no X, logo, pode ser reconhecida com maior precisão.
Essa foi a principal razão para a Amazon escolher esse nome.
• 2015 – Cortana, assistente virtual criada pela Microsoft. A Cortana
pode criar lembretes, reconhecer voz natural e responder a perguntas
usando informações do mecanismo de busca Bing. Seu nome vem de
um personagem de inteligência artificial fictício da série de videogames
Halo.
• 2016 – Em abril de 2016, o Facebook anunciou uma plataforma de bot
para o Messenger que incluía APIs de construção de chatbots para a
interação com os usuários. Melhorias posteriores incluíram bots que
participam de grupos, telas de pré-visualização e recurso de leitura de
QR por intermédio da funcionalidade de câmera do Messenger para
levar os usuários diretamente para o bot.
Em maior de 2016, o Google revelou seu bot ativado por voz concorrente
do Amazon Echo chamado Google Home na conferência de
desenvolvedores da empresa. Ele permite aos usuários emitir comandos
de voz para interagir com vários serviços.
• 2017 – O Woebot é um agente conversacional que nos ajuda a
monitorar nosso humor, a nos conhecer melhor e a nos sentir bem. Ele
usa uma combinação de técnicas de NLP, habilidades psicológicas
(terapia cognitivo-comportamental [TCC]), ótima redação e senso de
humor para tratar a depressão.
Que tipo de problemas posso resolver usando chatbots?
Essa pergunta é desafiadora quando não conhecemos o escopo do bot ou
não queremos limitá-lo a responder a consultas.
É importante lembrar que há um limite para o que os chatbots podem
fazer. Quase sempre parece que estamos falando com algo semelhante a
um humano que é muito inteligente, mas o bot é projetado e treinado
apenas para comportar-se de maneira específica e resolver determinado
problema. Ele não pode fazer tudo, pelo menos atualmente. O futuro é que
é promissor.
Chegamos então à questão de descobrir se nosso problema é apropriado e
se podemos construir um bot para resolvê-lo.
Se a resposta para essas três perguntas for sim, então siga em frente.
Pode ser resolvido por pergunta e resposta ou conversa simples?
É importante não exagerar ao resolver qualquer problema que seja muito
novo para você. Busque sempre tentar limitar o escopo do problema.
Construa a funcionalidade básica e depois adicione outros recursos a ela.
Não tente torná-la complexa desde o início. Isso não funciona quando
lidamos com software.
Imagine Mark Zuckerberg pensando em voz alta e construindo todos os
recursos do Facebook desde o início. Marcar um amigo, incluir um botão
"curtir", curtir o comentário de um usuário, melhorar a troca de
mensagens, incluir live vídeo, permitir reações a comentários etc. – esses
recursos não existiam quando o Facebook foi criado com mais de 1 milhão
de usuários registrados na plataforma. Ele teria sido bem-sucedido se os
tivesse construído e depois lançado a plataforma?
Devemos sempre tentar criar apenas os recursos necessários naquele
momento sem exagerar no planejamento de funcionalidades.
Voltemos então à primeira pergunta: "O problema pode ser resolvido por
pergunta e resposta ou com uma conversa simples?".
Se você mantiver seu escopo limitado, a resposta será sim. Não estamos de
forma alguma evitando resolver problemas complexos, estamos evitando
resolvê-los de uma só vez.
"Você tem de criar cada detalhe com perfeição. E precisa limitar o
número de detalhes". – Jack Dorsey
Tem tarefas altamente repetitivas que demandem a analise ou a busca de dados?
Essa pergunta é importante porque, do ponto de vista empresarial ou do
desenvolvedor, o que o chatbot faz e a razão para que ele seja criado é
tornar as pessoas que o estão usando eficientes e produtivas. E como fazer
isso? Eliminando a necessidade de o próprio usuário ter de executar tarefas
repetitivas.
Definitivamente os chatbots são capazes de automatizar alguma tarefa
altamente repetitiva, mas o que percebemos é que a maioria tenta resolver
o mesmo problema – seja aprendendo sob supervisão ( "por aprendizado
supervisionado") ou por autoaprendizado ("por aprendizado não
supervisionado").
A tarefa de seu bot pode ser automatizada e resolvida?
A menos que você esteja pensando em construir um chatbot apenas para o
próprio aprendizado, deve certificar-se de que o problema que está
tentando resolver possa ser automatizado. As máquinas já começaram a
aprender e a fazer coisas sozinhas, mas esse ainda é um estágio muito novo.
O que não puder ser automatizado agora talvez o seja daqui a alguns anos.
Bot de P&R
Um bom exemplo de problema para a construção de um chatbot poderia
ser um bot de Perguntas&Respostas. Imagine um bot treinado para
entender perguntas do usuário cujas respostas já estivessem disponíveis na
página de perguntas frequentes do site.
Se você tentar responder às três perguntas que fizemos anteriormente, a
resposta será sim.
Examine a Figura 1.6 e verá o que faz um bot de perguntas frequentes
(FAQ bot).
Figura 1.6 – Exemplo de chatbot de perguntas frequentes.
Essas são apenas perguntas muito comuns que os clientes de uma loja
específica poderiam fazer em uma ligação, assim como também poderiam
tentar encontrar as respostas acessando um site e navegando pelas páginas.
Imagine se você pudesse acessar um chatbot como esse e ele respondesse a
sua pergunta como um humano em segundos e fizesse até mais do que o
esperado. Isso é apenas uma amostra do que os chatbots podem fazer.
Tentaremos analisar as três perguntas feitas anteriormente e suas respostas
no caso do bot de P&R.
• O problema pode ser resolvido por pergunta e resposta ou com uma
conversa simples?
Sim, as FAQs são apenas perguntas frequentes simples e suas respostas.
Podemos encontrar FAQs baseadas em contexto, mas, a menos que
você esteja resolvendo algo que envolva várias áreas usando chatbots,
isso não será um problema. Pode ocorrer uma situação em que duas ou
mais perguntas pareçam semelhantes, mas você pode projetar o bot
para responder fazendo uma pergunta ao usuário quando tiver dúvidas.
• O problema tem tarefas altamente repetitivas que demandem a análise
ou a busca de dados?
Sim, as FAQs demandam a busca de dados no banco de dados e sua
exibição de uma só vez no site ou talvez dinamicamente. No entanto, o
usuário tem de percorrer as perguntas uma a uma para encontrar a que
está procurando e ver sua resposta. O consumidor precisa vasculhar
bem a UI antes de obter a resposta… ou talvez não. Por que não
deixamos nosso bot fazer isso?
• A tarefa de seu bot pode ser automatizada e resolvida?
Sim, um bot de perguntas frequentes precisaria receber a pergunta,
analisá-la, buscar informações no banco de dados e retorná-las para o
usuário. Não há nada aqui que não possa ser feito com o uso de
codificação. E, além disso, o processo que é resolvido não muda em
tempo real.
Etapas iniciais para a construção de chatbots
Há três etapas que devemos seguir antes de construir chatbots.
Discutiremos cada uma resumidamente.
1. Pense em todos os cenários ou tarefas que você deseja que seu chatbot
simule e colete as perguntas relacionadas nos diferentes formatos que
elas podem ser feitas para a execução das tarefas. Cada tarefa que você
quiser que seu chatbot execute definirá uma intenção.
2. Cada pergunta ou intenção listada pode ser representada de várias
formas. Depende de como o usuário a expressar.
Por exemplo: Alexa, switch off the light (Alexa, apague a luz). Alexa,
would you please switch off the light? (Alexa, apague a luz por favor?).
Can you please switch off the light? (Você pode apagar a luz por favor?).
O usuário pode usar qualquer uma dessas frases para instruir o bot a
apagar a luz. Elas expressam a mesma intenção/tarefa de apagar a luz,
mas foram construídas com diferentes enunciados/variações.
3. Escreva a lógica de forma a manter o usuário conectado ao fluxo que
você escolheu após reconhecer sua intenção.
Por exemplo, suponhamos que você estivesse construindo um bot para a
marcação de uma consulta médica. Deve solicitar ao usuário um
número de telefone, um nome e o especialista; em seguida, exibirá os
horários e fará o agendamento.
Nesse caso, sabemos que o usuário conhece os detalhes e não precisamos
tentar acomodar tudo no bot, como o fato de um especialista em
problemas no ouvido chamar-se otorrinolaringologista No entanto, isso
não é grande coisa. Logo, novamente se trata de decidir o escopo de seu
bot, dependendo do tempo e dos recursos disponíveis para a construção da
aplicação.
Árvores de decisão em chatbots
Se você conhece as árvores de decisão, ótimo, porque precisará delas com
frequência ao projetar o fluxo de seus chatbots. Se não as conhece, uma
pesquisa no Google o ajudará a aprender esse conceito simples
amplamente usado na Ciência da Computação.
Usando árvores de decisão em chatbots
No contexto dos chatbots, uma árvore de decisão simplesmente nos ajuda
a encontrar a resposta certa para uma pergunta do usuário.
Uma árvore de decisão (decision tree) é uma ferramenta de apoio à
tomada de decisões que usa um gráfico ou modelo em formato de
árvore contendo as decisões e suas possíveis consequências, inclusive
resultados de eventos fortuitos, custos dos recursos e utilidade. É uma
maneira de exibir um algoritmo que só contém instruções de controle
condicionais. – Wikipedia
A parte mais difícil da construção de um chatbot é fazer o
acompanhamento dos blocos de código if...else. Quanto maior o número
de decisões a serem tomadas, maior a frequência com que if...else surgirá
no código. No entanto, esses blocos são necessários na codificação dos
complicados fluxos conversacionais. Se o problema for complexo e
demandar muitas decisões condicionais na vida real, então, da mesma
forma será preciso uma codificação com if...else que faça esse ajuste.
Como a árvore de decisão ajuda?
As árvores de decisão são fáceis de criar e entender e ao mesmo tempo
constituem uma representação poderosa da solução gerada para o
problema em questão. Elas herdam algo exclusivo que nos ajuda a detectar
muitas coisas.
• Ajuda a criar um cenário geral do problema a ser resolvido. Olhando a
árvore de decisão, podemos perceber facilmente o que está faltando ou
o que precisa ser modificado.
• Ajuda a termos uma depuração mais rápida. As árvores de decisão são
como um guia resumido ou uma representação visual de um
documento de especificação de requisitos de software que pode ser
consultado por desenvolvedores, gerentes de produto ou pela chefia
para explicar o comportamento esperado ou sugerir alterações se
necessário.
• A IA ainda não se encontra no estágio em que pode ser treinada com
muitos dados e ter um desempenho de 100% de precisão. Ela requer
manipulação manual com a criação de lógicas e regras operacionais. As
árvores de decisão serão úteis onde estiver sendo difícil solicitar à
máquina que aprenda e execute.
Veremos um exemplo simples para tentar entender como a árvore de
decisão ajuda na construção de chatbots. Examine o diagrama da Figura
1.7, de um chatbot que começa perguntando se o usuário está procurando
uma camiseta ou uma calça jeans e, de acordo com a entrada, o fluxo
avança fornecendo opções relacionadas ao produto e fazendo mais
perguntas. Você não precisa criar uma árvore de decisão completa, mas é
preciso ter um fluxo de perguntas definidas para cada etapa antes de
começar a construir o chatbot.
Suponhamos que você estivesse construindo um chatbot semelhante que
ajudasse as pessoas a comprar roupas online. A primeira coisa que faria é
criar uma árvore de decisão parecida ou um fluxograma para ajudar seu
chatbot a fazer as perguntas apropriadas na hora certa. Isso é realmente
necessário para definir o escopo de cada etapa e o que tem de ser feito
nesse estágio. Você precisará dos diagramas de estado ou de um
fluxograma simples posteriormente quando codificar seu primeiro chatbot.
Lembre-se de não ser muito rigoroso ao criar um diagrama como o da
Figura 1.7; mantenha-o o mais simples possível e adicione as
funcionalidades estendidas depois. O benefício desse processo é que o
tempo de desenvolvimento é reduzido e mais tarde a funcionalidade é
fracamente acoplada e começa a fazer sentido como componente. Como
no exemplo, após criar a funcionalidade básica, você pode adicionar
opções de cores, variações de preço, avaliações e opções de desconto.
Figura 1.7 – Representação simples de um chatbot de vestuário para a
compra de roupas online.
Certamente é possível adicionar mais coisas ao caso de uso anterior
dependendo de seus requisitos. No entanto, é preciso certificar-se de não o
tornar complexo demais tanto para você quanto para o usuário.
Uma árvore de decisão nos ajuda não só a tornar o usuário parte do fluxo
como também é uma maneira muito eficaz de identificar a próxima
intenção que pode surgir na forma de uma pergunta do cliente.
Seu bot fará uma série de perguntas seguindo a árvore de decisão que você
construiu. Cada nó restringe mais o objetivo do usuário por intermédio das
intenções criadas para o chatbot.
Suponhamos que você estivesse criando um chatbot para uma instituição
financeira – digamos, um banco – que fizesse transferências de dinheiro
com base em uma solicitação após autenticação. Nesse caso, primeiro seu
bot verificaria os detalhes da conta, solicitaria que o usuário confirmasse a
quantia e pediria a validação do nome, número e tipo da conta de destino
etc. Você não pode ou deve chamar uma API OTP (one-time password –
senha dinâmica) a menos que tenha validado se o saldo da conta do
usuário é maior que a quantia solicitada.
Há outra coisa que acontece com todos nós e também com os clientes. Eles
ficam frustrados quando suas perguntas não são respondidas corretamente.
O uso de árvores de decisão para seu chatbot tornará a experiência dos
usuários melhor do que seria se você não as usasse.
Muitas vezes você não conseguirá resolver algumas intenções
programaticamente. A solução é: "Se não pode resolver algo
programaticamente, resolva no design".
Examine a Figura 1.8 em que o bot está fazendo perguntas de cunho
médico e deseja saber se os antibióticos funcionam para tudo.
Figura 1.8 – Exemplo de solução de um caso de uso no design.
Já que a resposta esperada é um booleano (verdadeiro/falso), fornecemos
apenas dois botões para o usuário clicar em vez de ser preciso digitar e
corrigir erros.
Isso é resolver no design em vez de escrever várias linhas de código para
manipular entradas inesperadas. Ao construir o chatbot, você terá muitos
cenários em que fornecendo botões saberá rapidamente a intenção do
usuário. É importante entender esses cenários e fornecer botões tanto para
sua conveniência quanto para a dos usuários que não precisarão digitar
casos óbvios de respostas opcionais.
Os melhores frameworks de chatbots/bots
• [Link]
• Consegue monitorar o humor.
• Ajuda a nos sentirmos melhor.
• Fornece insights detectando nosso padrão de humor.
• Ensina como ser positivo e melhorar a disposição.
• [Link]
• Constrói, treina e publica em minutos um bot simples de perguntas e
respostas baseado em FAQ, URLs e documentos estruturados.
• Testa e aperfeiçoa respostas usando uma interface de chat familiar.
• [Link]
• Anteriormente conhecido como [Link] e muito popular entre
entusiastas dos chatbots.
• Fornece aos usuários novas maneiras de interagir com o produto
construindo interfaces conversacionais interessantes baseadas em
texto e voz e suportadas por IA.
• Conecta-se com usuários do Google Assistant, Amazon Alexa,
Facebook Messenger e outras plataformas e dispositivos populares.
• Analisa e entende a intenção do usuário para ajudá-lo a responder da
maneira mais útil.
• [Link]
• Framework para a construção de software conversacional.
• Você pode implementar as ações que o bot executa em código
Python.
• Em vez de usar várias instruções if…else, a lógica do bot pode se
basear em um modelo probabilístico treinado em exemplos de
conversa.
• [Link]
• O [Link] torna fácil para os desenvolvedores construírem aplicações e
dispositivos com os quais podemos conversar ou trocar mensagens.
• O [Link] foi adquirido pelo Facebook após 21 meses de seu
lançamento e sua equipe faz contribuições para o mecanismo de NLP
dentro do próprio Facebook.
• Você pode usar o [Link] para construir chatbots, automação
residencial etc.
• O [Link] funciona de maneira semelhante ao Dialogflow, contudo não
tem tantos recursos. Inicialmente as pessoas usavam o [Link] porque
ele era gratuito e o Diagflow não, mas depois o Dialogflow também
passou a ser gratuito.
• [Link]
• Serviço baseado em machine learning para a construção de linguagem
natural em aplicações, bots e dispositivos IoT.
• Cria rapidamente modelos personalizados prontos para serem usados
pelas empresas e com melhorias contínuas.
• [Link]
• Gerador de conversação visual.
• Estatísticas e métricas internas.
• Pode ser integrado facilmente ao Facebook, Microsoft, IBM Watson,
Slack, Telegram etc.
Componentes de um chatbot e terminologias usadas
São muito poucos os componentes de um sistema de chatbot. Nesta seção
discutiremos brevemente os componentes dos chatbots que aparecerão nos
capítulos posteriores.
É sempre útil termos um conhecimento teórico básico antes de nos
aprofundarmos em algum assunto. Após ler esta seção, você saberá quais
terminologias técnicas são usadas na construção de chatbots com Python.
Essas terminologias serão empregadas com frequência nos próximos
capítulos quando começarmos de fato a construir nossos chatbots.
Intenção
Quando um usuário interage com um chatbot, qual é a sua intenção
(intent) ao usá-lo/o que ele deseja?
Por exemplo, quando um usuário diz "Book a movie ticket" (compre um
ingresso para um filme) para um chatbot, nós, humanos, entendemos que
ele deseja comprar um ingresso para assistir a um filme. Para o bot isso se
chama intenção. Ela poderia se chamar intenção book_movie.
Outro exemplo poderia ser quando um usuário diz "I want to order food"
(Quero pedir comida) ou "Can you help me order food?" (Pode me ajudar a
pedir comida?). Essas intenções poderiam se chamar order_food. Você pode
definir quantas intenções quiser.
Entidades
As intenções têm metadados sobre elas chamados "entidades". No exemplo
"Book a movie ticket", comprar o ingresso seria a intenção (intent) e a
entidade (entity) seria "movie", que também poderia ser outra coisa como
voo, concerto etc.
Você pode ter entidades gerais rotuladas para serem usadas com todas as
intenções. Elas poderiam ser representadas como uma quantidade,
contagem ou volume. As intenções também podem ter várias entidades.
Por exemplo: Order me a shoe of size 8 (Compre um sapato para mim de
tamanho 8).
Há duas entidades aqui:
Categoria: Shoe (sapato)
Size (Tamanho): 8
Enunciados
Os enunciados são apenas diferentes formas de o usuário expressar a
mesma pergunta/intenção.
• Lembra-se de que discutimos a intenção de apagar a luz? Foi um
exemplo de como um usuário pode empregar diferentes enunciados
para a mesma intenção.
• É recomendável que haja no máximo 10 e no mínimo 5 enunciados por
intenção, mas isso não é obrigatório.
Treinando o bot
Treinar significa construir um modelo que aprenderá como categorizar os
novos enunciados a partir de um conjunto de intenções, entidades e
enunciados predefinidos e fornecer uma pontuação de confiança que o
acompanhe.
Quando treinamos o sistema usando enunciados, isso se chama
aprendizado supervisionado. Em breve aprenderemos mais sobre como
fazê-lo na prática.
Pontuação de confiança
Sempre que você tentar descobrir a que intenção um enunciado pertence,
seu modelo exibirá uma pontuação de confiança. Essa pontuação informa
o nível de confiança com que o modelo de machine learning reconhece a
intenção do usuário.
Isso é tudo que queríamos abordar no primeiro capítulo de introdução aos
chatbots. Você já deve ter uma boa ideia do que são os chatbots dos pontos
de vista empresarial e técnico. Também percorremos a linha do tempo
relacionada a eles. É fascinante ver o quanto evoluíram.
Aprendemos como os chatbots evoluíram ao longo do tempo e por que eles
são obrigatórios para uma empresa crescer nesse implacável mundo
competitivo. Conhecemos os diferentes frameworks de chatbots e também
examinamos a terminologia empregada com exemplos. Vamos usá-los nos
próximos capítulos. Você já deve se encontrar em um estágio em que sabe
que tipo de chatbot deseja construir e como ele se comportará após ser
criado.
Faça todas as suas anotações e crie árvores de decisão, se necessário, e,
após aprendermos os aspectos básicos da compreensão de linguagem
natural no próximo capítulo, poderemos começar, com rapidez, a construir
nosso chatbot.
Não se preocupe se não tiver nada em mente. Tentaremos construir um
chatbot passo a passo com os conceitos aprendidos nos próximos
capítulos.
Até o capítulo seguinte.
CAPÍTULO 2
Natural Language Processing para Chatbots
Este capítulo o apresentará ao Natural Language Processing (NLP) com o
uso de Python, algo importante para a construção de chatbots. Você
aprenderá os métodos e técnicas básicos de NLP usando uma ótima
biblioteca open source chamada spaCy. Se for de nível iniciante ou
intermediário no ecossistema Python, não se preocupe, já que executará
cada etapa necessária para aprender NLP e construir chatbots. O capítulo
não só ensinará os métodos de NLP, mas também utilizará situações da
vida real e as demonstrará com exemplos de codificação. Também
discutiremos por que um método de NLP específico pode ser necessário
para os chatbots. É bom lembrar que o NLP já é por si só uma habilidade.
Examinaremos detalhadamente a marcação de parte da fala (POS tagging),
a stemização, a detecção de entidades, as stopwords, o parsing de
dependências, e os noun chunks (blocos de substantivos), além de
encontrar semelhanças entre palavras. Todos esses métodos serão muito
úteis quando você estiver construindo os chatbots de seu caso de uso.
Há vários outros métodos de NLP além dos abordados neste capítulo.
Dependendo do recurso de que você precisar no chatbot que estiver
construindo, pode tentar conhecê-los. A biblioteca SpaCy que
aprenderemos a usar até o fim do capítulo lhe dará uma boa noção de
como aumentar sua base de conhecimento e compreensão do NLP.
Comecemos então; primeiro tentaremos entender o uso do NLP para
chatbots, o que faremos na próxima seção.
Por que preciso conhecer NLP para construir um chatbot?
Para entender a resposta a essa pergunta, primeiro temos que conhecer o
NLP (Natural Language Processing – Processamento de Linguagem
Natural).
O Natural Language Processing (NLP) é uma área da inteligência artificial
que permite que os computadores analisem e entendam a linguagem
humana.
Para usarmos o NLP, ou a Natural Language Understanding (NLU), temos
vários métodos que discutiremos a seguir. Você conheceu um novo termo,
Natural Language Understanding (NLU) – mas o que é isso?
De um modo geral, a NLU é um subconjunto do cenário maior do NLP,
assim como o machine learning, o deep learning, o NLP e a mineração de
dados são um subconjunto do cenário maior da inteligência artificial (IA),
que é um termo genérico para qualquer programa de computador que faça
algo inteligente.
Uma boa regra prática é usar o termo NLU para expressar a habilidade
de uma máquina entender a linguagem natural em uma forma fornecida
pelos humanos.
Voltando à pergunta de se você precisa realmente conhecer o NLP para
construir um chatbot – a resposta é sim e não. Ficou confuso? Mas é isso
mesmo, você pode construir um chatbot sem conhecer os métodos e as
técnicas de NLP, mas o escopo ficará um pouco limitado. Não será possível
escalar a aplicação e manter ao mesmo tempo o código limpo. O NLP dá
asas para o chatbot voar quando ele só consegue caminhar e correr.
Para uma pessoa comum, os chatbots são apenas uma maneira de se
comunicar com uma máquina inteligente na outra extremidade. Essa
máquina pode ser baseada em voz ou texto, caso em que o usuário
fornecerá a entrada em seu próprio idioma, que geralmente na ciência da
computação é chamado de linguagem natural.
Sabemos que não há uma caixa preta que faça uma mágica e tudo funcione
bem. É preciso saber que não há nada de artificial na IA; na verdade, são
algoritmos de machine learning e deep learning, escritos por excelentes
profissionais, sendo executados em segundo plano. As máquinas não
chegaram ao estágio em que podem pensar de maneira semelhante aos
humanos para ter a própria inteligência. Os sistemas de IA atuais – o que
eles fazem e como se comportam – são resultado de como os treinamos.
Portanto, para entender a linguagem natural do usuário, seja qual for o
idioma ou a forma de entrada (texto, voz, imagem etc.), temos de escrever
algoritmos e usar técnicas de NLP. O NLP, considerado o cérebro dos
chatbots, processa os dados brutos, arruma-os (munging), limpa os dados
e se prepara para tomar as medidas apropriadas.
O NLP é por si só um tópico extenso e são necessários tempo e
perseverança para o dominarmos plenamente, mas há alguns métodos que
o desenvolvedor de chatbots precisa conhecer e que aprenderemos neste
capítulo.
O que é spaCy?
spaCy é uma biblioteca de software open source para NLP avançado escrita
em Python e Cython; ela foi construída por Matthew Honnibal e fornece
APIs intuitivas para o acesso a seus métodos treinados por modelos de
deep learning.
O spaCy oferece o parser sintático mais rápido do mundo. Ele gerou alguns
resultados excelentes em avaliações (benchmarking), os quais são
mostrados a seguir e foram tirados diretamente de sua documentação.
Resultados de avaliações do spaCy
Dois artigos revisados por colegas em 2015 confirmavam que o spaCy
oferece o parser sintático mais rápido do mundo e que sua precisão está
dentro de 1% entre os melhores disponíveis. Os poucos sistemas mais
precisos são 20 vezes mais lentos ou mais. A Figura 2.1 mostra os
resultados de avaliações do spaCy baseados em sua velocidade e precisão
em comparação com outras bibliotecas.
Figura 2.1 – Resultados de avaliações do spaCy.
O spaCy oferece modelos estatísticos de redes neurais para uma ampla
variedade de idiomas como inglês, alemão, espanhol, português, francês,
italiano, holandês e NER para vários idiomas. Ele também fornece
tokenização para muitos idiomas. Essa tabela mostra a velocidade avaliada
por Choi et al., logo, não seria justo comparar o spaCy v2.x avaliado em
hardware diferente. É por isso que não vemos o valor da coluna de
velocidade para o spaCy v2.x.
O que o spaCY fornece?
Há três elementos principais que o spaCy alega fornecer e nos quais ele é
extremamente útil. Vamos examiná-los para entender por que devemos
conhecer e usar o spaCy como um módulo obrigatório para NLP.
Biblioteca mais rápida do mundo
O spaCy se sai muito bem na extração de informações de larga escala. Ele
foi criado desde o início com muita preocupação com a memória que é
auxiliada pela biblioteca Cython.
Conclusão de tarefas
O spaCy foi projetado visando à "conclusão de tarefas". Ele ajuda a
finalizar cenários de NLP do mundo real. A documentação clara economiza
muito tempo dos desenvolvedores e entusiastas da linguística
computacional e os torna mais produtivos. É fácil de instalar, como
qualquer pacote Python.
Deep Learning
O spaCy é uma das melhores bibliotecas disponíveis na comunidade open
source para processar texto para algoritmos de deep learning. Ele se integra
perfeitamente ao TensorFlow, PyTorch, scikit-learn, Gensim e às outras
tecnologias Python relacionadas. Os desenvolvedores de deep learning
podem construir com facilidade modelos estatísticos linguisticamente
sofisticados para vários problemas de NLP/NLU.
Recursos do spaCy
Nenhuma outra biblioteca de NLP fornece uma variedade tão ampla de
APIs que fazem quase tudo, que é o que o spaCy faz. As melhores
qualidades dessa biblioteca são que ela evolui continuamente e fica cada
vez melhor. Veremos um breve resumo dos recursos do spaCy como
descritos em seu site oficial ([Link]
• Tokenização não destrutiva.
• Reconhecimento de entidades nomeadas.
• Suporte a mais de 28 idiomas.
• 13 modelos estatísticos para 8 idiomas.
• Vetores de palavras pré-treinados.
• Fácil integração de deep learning.
• Marcação de parte da fala.
• Parsing de dependências rotuladas.
• Segmentação de frase baseada em sintaxe.
• Visualizadores internos para sintaxe e NER.
• Mapeamento conveniente de string para hash.
• Exportação para arrays de dados numpy.
• Serialização binária eficiente.
• Fácil empacotamento e implantação de modelo.
• Velocidade de ponta.
• Precisão robusta, avaliada rigorosamente.
Agora nos aprofundaremos nesse incrível módulo para NLP em Python: o
spaCy.
Instalação e pré-requisitos
Antes de examinarmos o spaCy e os fragmentos de código, verifique se o
Python está instalado em seu sistema operacional. Se não estiver, consulte
a PSF1.
Você pode usar a versão de Python com a qual se sentir confortável. A
maioria dos sistemas atuais vem com a versão padrão 2.7.x pré-instalada.
Usaremos Python 3 neste capítulo. Logo, se quiser usar Python 3, instale-o
em seu sistema operacional baixando-o de [Link]
Se estiver com o Python 2 instalado, também é possível usá-lo; pode ou
não ser preciso fazer pequenas alterações no código.
Instalaremos o spaCy com o pip2.
Usaremos um ambiente virtual3 e instalaremos o spaCy em um diretório de
usuário.
Se estiver no macOS/OSX/Linux, siga estas etapas:
Etapa 1: python3 -m pip install -U virtualenv
Etapa 2: virtualenv venv -p /usr/local/bin/python3 #Certifique-se de usar o
caminho de seu sistema operacional para o executável do python 3
Etapa 3: source venv/bin/activate
Etapa 4: pip3 install -U spacy # Usaremos o spaCy versão 2.0.11
A última etapa pode demorar, logo, espere pacientemente.
Se estiver no Windows, apenas altere a etapa 3 para
venv\Scripts\activate
Agora instalaremos o Jupyter Notebook dentro de nosso ambiente virtual,
que ativamos na Etapa 3. É muito mais fácil e produtivo usar o Jupyter
Notebook em vez do interpretador Python padrão. Executaremos todos os
fragmentos de código no Jupyter Notebook nos próximos capítulos.
Para instalar o Jupyter Notebook, execute o comando pip a seguir:
pip3 install jupyter
Esse comando instalará o Jupyter Notebook em seu sistema.
Você já deve estar com o spaCy e o Jupyter Notebook instalados em seu
virtualenv. Verificaremos se eles foram instalados com sucesso.
1. Acesse sua interface de linha de comando, digite a linha a seguir e você
deve ver um servidor sendo iniciado e abrindo uma url em seu
navegador padrão.
$ jupyter notebook
A url padrão é [Link] Você deve ver algo parecido com
a Figura 2.2.
Figura 2.2 – Aparência inicial do Jupyter Notebook.
2. Clique em New como mostrado na Figura 2.2 e selecione Python 3. Será
aberta uma nova aba em seu navegador atual e criado um novo
notebook, no qual você poderá manipular o código Python. É possível
executar qualquer código Python, importar bibliotecas, criar gráficos e
usar células Markdown.
3. Digite import spaCy e execute a célula clicando no botão Run ou
pressionando Shift + Enter. Você deve ver algo semelhante à Figura 2.3.
Figura 2.3 – Verificando a Instalação do spaCy.
Se a Etapa 3 não lançar nenhuma mensagem de erro, você instalou com
sucesso o módulo spaCy em seu sistema e deve ver a versão que foi
instalada em seu notebook. Se quiser instalar a mesma versão, pode
especificá-la quando instalar o spaCy com o pip.
pip3 install –U spacy==2.0.11
O que são os modelos do SpaCy?
Os modelos do SpaCy são como qualquer outro modelo de machine
learning ou deep learning. Um modelo é o resultado da execução de um
algoritmo, por exemplo, um objeto que é criado após o treinamento de
dados com o uso de um algoritmo de machine learning. O spaCy tem
vários desses modelos que podem ser inseridos diretamente em nosso
programa ao serem baixados como qualquer pacote Python.
Agora instalaremos os modelos do spaCy como pacotes Python.
Para fazê-lo, executaremos a linha a seguir no notebook empregando seu
comando mágico. Usando o prefixo ! (operador exclamação) antes do
comando, também podemos executar comandos shell a partir de Jupyter
Notebooks. Veja como funciona.
!python3 -m spacy download en # modelo (en)glish
Você pode ter um problema de permissão ao usar o Jupyter Notebook para
baixar modelos do spaCy para Python 3. Vá ao terminal e execute o
comando a seguir:
sudo python3 –m download en # modelo (en)glish
Consulte a Figura 2.4 como referência. Como você pode ver na Figura 2.4,
o spaCy tenta baixar alguns arquivos básicos e os instala como pacotes
Python.
Nota! O operador exclamação só funciona no Jupyter Notebook. Para
instalar modelos do spaCy diretamente a partir do terminal, você
precisa removê-lo; caso contrário, resultará em erro.
Figura 2.4 – Baixando modelos do spaCy.
Métodos básicos de NLP para a construção de chatbots
É muito importante dominar os aspectos básicos para ser um especialista
em algo e ter um desempenho eficaz e eficiente. Para construir chatbots,
precisamos conhecer os métodos básicos de NLP. Esses métodos ajudam a
dividir a entrada em blocos e a lhe dar sentido. Na próxima seção,
aprenderemos alguns dos métodos de NLP mais usados que o ajudarão a
ser eficiente não só no uso do NLP, mas também na construção de
chatbots modernos. Quanto melhor e mais eficientemente processarmos o
texto da entrada, melhor responderemos ao usuário.
Marcação POS
A marcação POS (part-of-speech – parte da fala) é um processo em que
lemos um texto e atribuímos partes da fala a cada palavra ou token, como
substantivos, verbos, adjetivos etc.
A marcação POS torna-se extremamente importante quando queremos
identificar alguma entidade em uma frase específica. A primeira etapa é
executar a marcação e ver o que o texto contém.
Passaremos à prática com alguns exemplos reais de marcação POS.
Exemplo 1:
nlp = [Link]('en') #Carrega o modelo en (english) do spacy em um objeto
python
doc = nlp(u'I am learning how to build chatbots') # Cria um objeto doc
# (Estou aprendendo a construir chatbots)
for token in doc:
print([Link], token.pos_) # exibe o texto e a POS
Saída:
('I', 'PRON') (pronome)
('am', 'VERB') (verbo)
('learning', 'VERB') (verbo)
('how', 'ADV') (advérbio)
('to', 'PART') (partícula)
('build', 'VERB') (verbo)
('chatbots', 'NOUN') (substântivo)
Exemplo 2:
doc = nlp(u'I am going to London next week for a meeting.')
# (Vou a uma reunião em Londres na próxima semana)
for token in doc:
print([Link], token.pos_)
Saída:
('I', 'PRON') (pronome)
('am', 'VERB') (verbo)
('going', 'VERB') (verbo)
('to', 'ADP') (adposição)
('London', 'PROPN') (nome próprio)
('next', 'ADJ') (adjetivo)
('week', 'NOUN') (substântivo)
('for', 'ADP') (adposição)
('a', 'DET') (artigo)
('meeting', 'NOUN') (substântivo)
('.', 'PUNCT') (pontuação)
Como podemos ver, quando exibimos os tokens a partir do objeto Doc
retornado pelo método nlp, que é um contêiner para o acesso às anotações,
obtemos a POS marcada com cada uma das palavras da frase.
Essas marcações são as propriedades pertencentes à palavra que
determinam seu uso em uma frase gramaticalmente correta. Podemos
empregá-las como as características da palavra na filtragem de informações
etc.
Veremos outro exemplo em que tentaremos explorar diferentes atributos
do token fornecido pelo objeto Doc.
Exemplo 3:
doc = nlp(u'Google release "Move Mirror" AI experiment that matches your pose
from 80,000 images')
# (Lançamento do experimento de IA "Move Mirror" do Google que copia uma pose a
partir de 80.000 imagens)
for token in doc:
print([Link], token.lemma_, token.pos_, token.tag_, token.dep_,
token.shape_, token.is_alpha, token.is_stop)
Saída:
TEXT LEMMA POS TAG DEP SHAPE ALPHA STOP
Google google PROPN NNP compound Xxxxx True False
Release release NOUN NN nmod xxxx True False
" " PUNCT `` punct " False False
Move move PROPN NNP nmod Xxxx True False
Mirror mirror PROPN NNP nmod Xxxxx True False
" " PUNCT " punct " False False
AI ai PROPN NNP compound XX True False
Experiment experiment NOUN NN ROOT xxxx True False
That that ADJ WDT nsubj xxxx True True
Matches match VERB VBZ relcl xxxx True False
Your -PRON- ADJ PRP$ poss xxxx True True
Pose pose NOUN NN dobj xxxx True False
From from ADP IN prep xxxx True True
80,000 80,000 NUM CD nummod dd,ddd False False
Images image NOUN NNS pobj xxxx True False
Exemplo 4:
doc = nlp(u'I am learning how to build chatbots')
# (Estou aprendendo a construir chatbots)
for token in doc:
print([Link], token.lemma_, token.pos_, token.tag_, token.dep_,
token.shape_, token.is_alpha, token.is_stop)
Saída:
TEXT LEMMA POS TAG DEP SHAPE ALPHA STOP
I -PRON- PRON PRP nsubj X True False
am be VERB VBP aux xx True True
learning learn VERB VBG ROOT xxxx True False
how how ADV WRB advmod xxx True True
to to PART TO aux xx True True
build build VERB VB xcomp xxxx True False
chatbots chatbot NOUN NNS dobj xxxx True False
Consulte a tabela a seguir para saber o significado de cada atributo que
exibimos no código.
TEXT O texto ou palavra que está sendo processado
LEMMA Forma raiz da palavra que está sendo processada.
POS Parte de fala da palavra.
TAG Expressa a parte da fala (por exemplo, VERB) e algumas informações morfológicas (por
exemplo, que o verbo está no passado).
DEP Dependência sintática (isto é, a relação entre os tokens).
SHAPE Forma da palavra (por exemplo, letras maiúsculas, pontuação, formato de dígitos).
ALPHA O token é um caractere alfabético?
STOP A palavra é uma stopword ou faz parte de uma stop list?
Você pode consultar a tabela a seguir para saber o que significam os valores
de cada um dos atributos POS do objeto de token. Essa lista fornece uma
descrição detalhada das marcações de parte da fala atribuídas pelos
modelos do spaCy.
POS DESCRIÇÃO EXEMPLOS
ADJ adjetivo big, old, green, incomprehensible, first (grande, velho, verde,
incompreensível, primeiro)
ADP adposição in, to, during (em, para, durante)
ADV advérbio very, tomorrow, down, where, there (muito, amanhã, abaixo, onde,
lá)
AUX verbo auxiliar is, has (done), will (do), should (do) (é, fez, fará, deve [fazer])
CONJ conjunção and, or, but (e, ou, mas)
CCONJ conjunção and, or, but (e, ou, mas)
coordenativa
DET artigo a, an, the (um, um, o)
INTJ interjeição psst, ouch, bravo, hello (psiu, ai, bravo, olá)
NOUN substantivo girl, cat, tree, air, beauty (garota, gato, árvore, ar, beleza)
NUM numeral 1, 2017, one, seventy-seven, IV, MMXIV (1, 2017, um, setenta e
sete, IV, MMXIV)
PART partícula 's, not ('s, não)
PRON pronome I, you, he, she, myself, themselves, somebody (eu, você, ele, ela, eu
mesmo, eles mesmos, alguém)
PROPN nome próprio Mary, John, London, NATO, HBO
PUNCT pontuação ., (, ), ?
SCONJ conjunção if, while, that (se, enquanto, que)
subordinativa
SYM símbolo $, %, §, ©, +, −, ×, ÷, =, :), ½
VERB verbo run, runs, running, eat. ate, eating (correr, corre, correndo, comer,
comeu, comendo)
X outros sfpksdpsxmsa
SPACE espaço
Mas por que a marcação POS é necessária em chatbots?
Resposta: para reduzir a complexidade de compreensão de um texto que
não possa ser ensinado ou que seja ensinado com pouca segurança.
Usando a marcação POS, podemos identificar partes da entrada de texto e
executar a comparação de strings só para essas partes. Por exemplo, se
fosse preciso saber se existe uma região geográfica em uma frase, a
marcação POS determinaria a palavra referente à região como NOUN, e
você poderia pegaria todos os substantivos (NOUNs) da lista de marcações
predefinida para ver se ela existe ou não.
Stemização e lematização
Stemização é o processo de reduzir palavras flexionadas à sua forma raiz.
Um algoritmo de stemização reduz a palavra "saying" (dizendo) à palavra
raiz "say" (dizer), enquanto "presumably" (presumivelmente) torna-se
"presum" (presum). Como você pode ver, nem sempre ele está 100%
correto.
A lematização está intimamente relacionada à stemização, mas é o
processo algorítmico que determina o lema de uma palavra de acordo com
o seu significado.
Por exemplo, em inglês, o verbo "to walk" (caminhar) pode aparecer como
"walk" (caminhada), "walked" (caminhava), "walks" (caminha) ou
"walking" (caminhando). A forma básica, "walk", que é possível procurar
no dicionário, chama-se lema da palavra. O spaCy não tem um stemizador
interno, já que a lematização é considerada mais correta e produtiva.
Diferença entre stemização e lematização:
• A stemização executa sua tarefa de maneira crua e heurística que corta
as extremidades das palavras, assumindo que a palavra restante seja a
que estamos procurando, mas com frequência inclui a remoção de
afixos derivacionais.
• A lematização faz o serviço de maneira mais elegante com o uso de uma
análise vocabular e morfológica das palavras. Ela tenta ao máximo
remover apenas as extremidades flexionais e retornar a forma da
palavra encontrada no dicionário, conhecida como lema.
Embora poucas bibliotecas forneçam métodos tanto para stemização
quanto para lematização, é sempre boa prática usar a lematização para a
obtenção correta da palavra raiz.
Examinaremos a lematização usando alguns exemplos:
Exemplo 1:
from [Link] import Lemmatizer
from [Link] import LEMMA_INDEX, LEMMA_EXC, LEMMA_RULES
lemmatizer = Lemmatizer(LEMMA_INDEX, LEMMA_EXC, LEMMA_RULES)
lemmatizer('chuckles', 'NOUN') # (risadas), NOUN é a marcação POS do token
Saída:
[u'chuckle']
Exemplo 2:
lemmatizer('blazing', 'VERB') # (resplandecendo)
Saída:
[u'blaze']
Exemplo 3:
lemmatizer('fastest', 'ADJ') # (mais rápido)
Saída:
[u'fast']
Se você quiser ver a comparação entre um stemizador e o lematizador, terá
de instalar uma das bibliotecas mais populares para Python: o Natural
Language Toolkit (NLTK). O spaCy só ganhou popularidade
recentemente, mas foi o NLTK que fez os entusiastas do NLP se
aprofundarem em seu universo e técnicas.
Veja o próximo exemplo em que usamos duas técnicas de stemização
fornecidas pelo NLTK. Primeiro, tentamos obter a raiz da palavra "fastest"
(mais rápido) usando o PorterStemmer e depois empregando o
SnowBallStemmer. Os dois fornecem o mesmo resultado – ou seja,
"fastest" (mais rápido) –, mas, quando executamos a lematização usando o
método do spaCy, ele fornece "fast" (rápido) como a raiz de "fastest", que é
mais significativo e correto.
from [Link] import *
from [Link] import SnowballStemmer
porter_stemmer = PorterStemmer()
snowball_stemmer = SnowballStemmer("english") # idioma inglês
print(porter_stemmer.stem("fastest"))
print(snowball_stemmer.stem("fastest"))
fastest
fastest
Nota Certifique-se de instalar o pacote nltk usando o pip3 antes de
tentar executar esse código.
Como você já sabe o que a stemização e a lematização fazem no NLP, deve
ter percebido que, sempre que deparar com uma situação em que precisar
da forma raiz da palavra, terá de usar a lematização. Por exemplo, ela é
usada com frequência na construção de mecanismos de busca. Você já
deve ter se perguntado como o Google fornece em seus resultados os
artigos exatos procurados até mesmo quando o texto da busca não foi
apropriadamente formulado.
É nesses casos que a lematização é usada. Imagine fazer uma busca com o
texto "When will the next season of Game of Thrones be releasing?"
(Quando será lançada a próxima temporada de Game of Thrones?).
Suponhamos que o mecanismo de busca executasse uma simples procura
da frequência das palavras nos documentos para fornecer os resultados.
Nesse caso, provavelmente a consulta anterior não encontraria um artigo
com o título "Game of Thrones next season release date" (Data de
lançamento da próxima temporada de Game of Thrones).
Se executarmos a lematização da pergunta original antes de comparar a
entrada com os documentos, podemos obter melhores resultados.
Testaremos essa teoria nas próximas seções.
Reconhecimento de entidades nomeadas
O reconhecimento de entidades nomeadas (NER, Named-Entity
Recognition), também conhecido por outros nomes como identificação ou
extração de entidades, é o processo de encontrar e classificar as entidades
nomeadas existentes no texto fornecido em categorias predefinidas.
A tarefa do NER depende muito da base de conhecimento usada para
treinar o algoritmo de extração de entidade nomeada (NE, named entity),
logo, pode ou não funcionar conforme o conjunto de dados fornecido para
o treinamento.
O spaCy vem com um modelo de reconhecimento de entidades muito
veloz que pode identificar frases de entidades em um documento
fornecido. As entidades podem ser de diferentes tipos, como uma pessoa,
local, empresa, datas, numerais etc. Elas podem ser acessadas por
intermédio da propriedade .ents do objeto doc.
Tentaremos encontrar entidades nomeadas usando alguns exemplos com a
ajuda do poderoso recurso de marcação NER do spaCy.
Exemplo 1:
my_string = u"Google has its headquarters in Mountain View, California having
revenue amounted to 109.65 billion US dollars"
# (A sede do Google é em Mountain View, Califórnia, e a empresa chegou a uma
receita de 189,65 bilhões de dólares americanos)
doc = nlp(my_string)
for ent in [Link]:
print([Link], ent.label_)
Saída:
('Google', 'ORG')
('Mountain View', 'GPE')
('California', 'GPE')
('109.65 billion US dollars', 'MONEY')
Podemos ver que o modelo do spaCy conseguiu identificar facilmente e de
maneira elegante e mágica que a palavra Google define uma Organização
(ORG), Califórnia é uma entidade Geopolítica (GPE)e que na frase dada
estamos falando de 109,65 bilhões de dólares americanos, o que na
verdade é uma informação financeira (MONEY).
Examinaremos mais alguns exemplos.
Exemplo 2:
my_string = u"Mark Zuckerberg born May 14, 1984 in New York is an American
technology entrepreneur and philanthropist best known for co-founding and
leading Facebook as its chairman and CEO."
# (Mark Zuckerberg, nascido em 14 de maio de 1984 em Nova York, é filantropo e
empreendedor da área de tecnologia, famoso por ser cofundador, líder,
presidente de conselho e CEO do Facebook)
doc = nlp(my_string)
for ent in [Link]:
print([Link], ent.label_)
Saída:
('Mark Zuckerberg', 'PERSON')
('May 14, 1984', 'DATE')
('New York', 'GPE')
('American', 'NORP')
('Facebook', 'ORG')
Exemplo 3:
my_string = u"I usually wake up at 9:00 AM. 90% of my daytime goes in learning
new things."
# (Geralmente acordo às 9 da manhã. Todos dia passo 90% de meu tempo aprendendo
coisas novas)
doc = nlp(my_string)
for ent in [Link]:
print([Link], ent.label_)
Saída:
('9:00 AM', 'TIME')
('90%', 'PERCENT')
Como você pode ver, o extrator de entidade conseguiu extrair facilmente a
informação de hora da string fornecida. Além disso, repare que o extrator
não só tenta identificar o número como também o valor PERCENTUAL
exato.
De acordo com a documentação do spaCy, os modelos treinados com o
acervo OntoNotes 54 dão suporte aos tipos de entidade a seguir.
TIPO DESCRIÇÃO
PERSON Pessoas, inclusive fictícias.
NORP Nacionalidades ou grupos religiosos ou políticos.
FAC Prédios, aeroportos, estradas, pontes etc.
ORG Empresas, agências, instituições etc.
GPE Países, cidades, estados.
LOC Locais sem classificação geopolítica (non-GPE locations), cordilheiras,
cursos d'água.
PRODUCT Objetos, veículos, alimentos etc. (serviços não).
EVENT Furacões nomeados, batalhas, guerras, eventos esportivos etc.
WORK_OF_ART Títulos de livros, canções etc.
LAW Documentos nomeados que viraram leis.
LANGUAGE Qualquer idioma nomeado.
DATE Datas ou períodos absolutos ou relativos.
TIME Períodos de tempo menores que um dia.
PERCENT Percentual, incluindo "%".
MONEY Valores monetários, incluindo a unidade.
QUANTITY Medidas, como o peso ou a distância.
ORDINAL "primeiro", "segundo" etc.
CARDINAL Numerais que não se enquadram em outro tipo.
Ao construir um agente conversacional ou chatbot, sempre pensamos em
uma área específica. Por exemplo, queremos que o chatbot agende uma
consulta médica, peça comida, pague uma conta, preencha um formulário
bancário, trabalhe com e-commerce etc. O chatbot também pode resolver
uma combinação desses problemas. Descobrindo a entidade da pergunta,
podemos ter uma boa ideia do contexto em que ela foi feita.
Tentaremos entender isso usando um exemplo de duas frases com palavras
semelhantes e significados diferentes.
my_string1 = u"Imagine Dragons are the best band."
# (Imagine Dragons é a melhor banda)
my_string2 = u"Imagine dragons come and take over the city."
# (Imagine Dragons vai chegar e dominar a cidade)
doc1 = nlp(my_string1)
doc2 = nlp(my_string2)
for ent in [Link]:
print([Link], ent.label_)
O loop for anterior do objeto doc1 fornece essa saída:
('Imagine Dragons', 'ORG')
Incrível, não é mesmo? Você ficará ainda mais surpreso quando perceber
que o reconhecedor de entidades não identifica nenhuma entidade na
segunda string. Execute o código a seguir e doc2 não produzirá nenhuma
saída.
for ent in [Link]:
print([Link], ent.label_)
Agora imagine se você precisasse extrair o contexto das duas strings
anteriores em um ambiente real de produção. O que faria? Com a ajuda do
Extrator de Entidades, podemos descobrir facilmente o contexto da frase e
continuar a conversa de maneira inteligente.
Stopwords
As stopwords são palavras que aparecem com muita frequência como a,
an, the, to e also (um, uma, o, para e também) que podemos querer tirar de
um documento antes de continuar seu processamento. Geralmente elas
têm pouco conteúdo léxico e não apresentam muito significado.
Abaixo temos uma lista das 25 stopwords semanticamente não seletivas
que são comuns no Reuters-RCV1.
a, an, and, are, as, at, be, by, for) # (um, uma, e, são, como, em, ser, por,
para)
from, has, he, in, is, it, its, of, on # (de, tem, ele, em, é, isso, seu, de,
sobre)
that, the, to, was, were, will, with # (que, o, para, foi, era, será, com)
Examinaremos alguns códigos para tentar entender como as coisas
funcionam.
Para ver todas as palavras definidas como stopwords no spaCy, execute as
linhas de código a seguir:
from [Link].stop_words import STOP_WORDS
print(STOP_WORDS)
Você deve ver algo como:
set(['all', 'six', 'just', 'less', 'being', 'indeed', 'over', 'move',
'anyway', 'fifty', 'four', 'not', 'own', 'through', 'using', 'go', 'only',
'its', 'before', 'one', 'whose', 'how',
......................................................................
......................................................................
......................................................................
......................................................................
'whereby', 'third', 'i', 'whole', 'noone', 'sometimes', 'well', 'together',
'yours', 'their', 'rather', 'without', 'so', 'five', 'the', 'otherwise',
'make', 'once'])
Há cerca de 305 stopwords definidas na lista do spaCy. Podemos definir
nossas próprias stopwords se necessário e sobrepor a lista existente.
Para ver se uma palavra é ou não uma stopword, é possível usar o objeto
nlp do spaCy. Podemos usar o atributo is_stop do objeto nlp.
Exemplo 1:
[Link][u'is'].is_stop
Saída:
True
Exemplo 2:
[Link][u'hello'].is_stop
Saída:
False
Exemplo 3:
[Link][u'with'].is_stop
Saída:
True
As stopwords são uma parte muito importante da limpeza de texto. Elas
ajudam na remoção de dados irrelevantes antes de tentarmos executar o
processamento para dar sentido ao texto.
Suponhamos que você deparasse com uma situação em que estivesse
construindo um bot para alegrar as pessoas avaliando seu humor. É preciso
analisar o sentimento existente na entrada de texto fornecida pelo usuário
para que a resposta correta seja formulada. Nesse caso, antes de solicitar a
execução de uma análise básica do sentimento, devemos remover o ruído
existente nos dados na forma de stopwords.
Parsing de dependências
O parsing de dependências é um dos recursos mais interessantes e
poderosos do spaCy e é rápido e preciso. O parser também pode ser usado
na detecção de limite da frase e permite iterar por frases substantivas
básicas, ou "blocos".
Esse recurso do spaCy fornece uma árvore de parsing que explica a relação
pai-filho entre as palavras ou frases independentemente da ordem em que
as palavras ocorrem.
Examinaremos um exemplo em que analisaremos a frase a seguir:
Book me a flight from Bangalore to Goa (Reserve um voo de Bangalore a
Goa)
Exemplo 1:
doc = nlp(u'Book me a flight from Bangalore to Goa')
blr, goa = doc[5], doc[7]
list([Link])
Saída:
[from, flight, Book]
A saída anterior nos diz que o usuário está tentando reservar um voo
partindo de Bangalore.
Tentaremos listar os ancestrais do objeto [Link]:
list([Link])
Saída:
[to, flight, Book]
Essa saída informa que o usuário quer reservar um voo para Goa.
O que são ancestrais no parsing de dependências?
Ancestrais são o token mais à direita entre os descendentes sintáticos desse
token. Como no exemplo anterior em que os ancestrais do objeto blr eram
from, flight e Book.
Lembre-se de que é possível listar os ancestrais de um item do objeto doc
usando o atributo ancestors.
list(doc[4].ancestors) #doc[4]==flight
O código anterior exibirá:
[flight, Book]
Para verificar programaticamente se um item do objeto doc é ancestral de
outro item desse objeto, podemos fazer o seguinte:
doc[3].is_ancestor(doc[5])
O código anterior retorna True porque doc[3] (isto é, flight) é ancestral de
doc[5] (Bangalore). Você pode usar mais exemplos como esse para entender
melhor o parsing de dependências e o conceito de ancestrais.
Se pensássemos em um cenário do mundo real que poderíamos encontrar
ao construir um chatbot, talvez surgisse uma frase como
I want to book a cab to the hotel and a table at a restaurant (Quero
chamar um táxi até o hotel e reservar uma mesa em um restaurante).
Nessa frase, é importante saber que tarefas (tasks) estão sendo solicitadas e
qual é o seu destino (target) (isto é, se o usuário deseja chamar um táxi para
o hotel ou reservar a mesa no restaurante).
Tentaremos fazer isso usando o código a seguir:
Exemplo 1:
doc = nlp(u'Book a table at the restaurant and the taxi to the hotel')
# (Reserve uma mesa no restaurante e o táxi para o hotel)
tasks = doc[2], doc[8] #(table, taxi)
tasks_target = doc[5], doc[11] #(restaurant, hotel)
for task in tasks_target:
for tok in [Link]:
if tok in tasks:
print("Booking of {} belongs to {}".format(tok, task))
break
Saída:
Booking of table belongs to restaurant (A reserva da mesa pertence ao
restaurante)
Booking of taxi belongs to hotel (A reserva do táxi pertence ao hotel)
O que são filhos no parsing de dependências?
Os filhos são os dependentes sintáticos imediatos do token. Podemos ver
os filhos de uma palavra usando o atributo children da mesma forma como
usamos ancestors.
list(doc[3].children)
exibirá
[a, from, to]
Visualização interativa do parsing de dependências
É muito difícil entender já no primeiro contato o conceito completo de
parsing de dependências. O spaCy fornece uma maneira extremamente
fácil e interativa de entendermos seu parsing de dependências. O spaCy
v2.0+ tem um módulo de visualização em que podemos passar um Doc ou
uma lista de objetos Doc para displacy e chamar seu método serve para
executar o servidor web.
A Figura 2.5 mostra como a visualização interativa exibe o parsing de
dependências.
Figura 2.5 – Visualização interativa do parsing de dependências.
Você também pode gerar por conta própria a visualização do parsing de
dependências da Figura 2.5. Para criar uma visualização como essa,
execute o código a seguir e acesse [Link] em seu navegador.
Tentaremos gerar a visualização de nosso exemplo de tarefas e seus
destinos.
from spacy import displacy
doc = nlp(u'Book a table at the restaurant and the taxi to the hotel')
# (Reserve uma mesa no restaurante e chame o táxi para o hotel)
[Link](doc, style='dep')
A execução desse código exibirá uma saída como a da Figura 2.6. Se você
obtiver algo semelhante, acesse outra aba de seu navegador e insira
[Link]
Figura 2.6 – Iniciando o servidor de parsing de dependências em localhost.
Obtivemos uma visualização (mostrada na Figura 2.7) do parsing de
dependências dessa string por meio de código.
Figura 2.7 – Exemplo de parsing de dependências.
Veremos mais um exemplo de parsing de dependências em que o usuário
faz a seguinte pergunta:
What are some places to visit in Berlin and stay in Lubeck? (Que locais
temos para visitar em Berlim e para ficar em Lubeck?)
Primeiro criaremos o objeto doc como mostrado aqui:
doc = nlp(u"What are some places to visit in Berlin and stay in Lubeck")
Agora destacaremos os locais (places) mencionados e as ações (actions)
que o usuário deseja:
places = [doc[7], doc[11]] #[Berlin, Lubeck]
actions = [doc[5], doc[9]] #[visit, stay]
Como você já conhece a marcação POS e a extração de entidades, pode
obter facilmente os locais e as ações de maneira automática.
Já temos os locais, logo, iteraremos por cada um de seus ancestrais e
verificaremos se existe algum em actions. O primeiro pai de place
encontrado na lista de ações deve ser a ação do local em questão.
for place in places:
for tok in [Link]:
if tok in actions:
print("User is referring {} to {}").format(place, tok)
break
Saída:
User is referring: Berlin to visit (O usuário está se referindo a: Berlim para
visitar)
User is referring: Lubeck to stay (O usuário está se referindo a: Lubeck para
ficar)
Como vemos nesses exemplos, o parsing de dependências facilita muito
saber ao que o usuário está se referindo. Também vimos que, no caso de
duas tarefas diferentes, podemos descobrir a expectativa e, com base nela,
formular a próxima resposta.
Para que o parsing de dependências é usado nos chatbots?
O parsing de dependências é uma das partes mais importantes na
construção de chatbots a partir do zero. Torna-se ainda mais importante
quando queremos descobrir o significado de uma entrada de texto feita
pelo usuário. Você pode deparar com situações em que não treinou seus
chatbots, mas mesmo assim não deseja perder os clientes ou responder
como se a máquina não fosse inteligente. Nesses casos, o parsing de
dependências ajuda a encontrar relações e definir um pouco melhor o que
o usuário está solicitando.
Se fizéssemos uma lista das tarefas em que o parsing de dependências
ajuda, algumas delas seriam:
• Ajuda a encontrar relações entre palavras de frases gramaticalmente
corretas.
• Pode ser usado na detecção dos limites da frase.
• É muito útil para descobrirmos se o usuário está se referindo a mais de
um contexto simultaneamente.
Você deve estar se perguntando: e se o usuário do bot construir uma frase
gramaticalmente incorreta ou usar abreviações típicas de mensagens SMS
(textspeak) ao fornecer uma entrada sobre algo? Como discutido no
Capítulo 1, precisamos tomar cuidado com essas situações e manipulá-las
de acordo usando técnicas de NLP.
É preciso que você crie o próprio NLP personalizado para entender o
contexto do usuário ou do chatbot e, baseado nisso, identificar os possíveis
erros gramaticais que o usuário pode cometer.
Seja como for, você deve estar preparado para cenários em que o usuário
insira valores inúteis ou frases gramaticalmente incorretas. Não é possível
manipular todos esses cenários de uma vez só, mas você pode melhorar
continuamente seu chatbot adicionando código NLP personalizado ou
limitando a entrada do usuário já no projeto.
Noun chunks
Os noun chunks, ou NP-chunking, são essencialmente "frases substantivas
básicas". Poderíamos dizer que são frases simples (flat phrases) que têm um
substantivo como head (núcleo). Pense neles como um substantivo com as
palavras que o descrevem. Examinaremos um exemplo para entender
melhor.
Exemplo 1:
doc = nlp(u"Boston Dynamics is gearing up to produce thousands of robot dogs")
# (A Boston Dynamics está se preparando para produzir milhares de cães robôs)
list(doc.noun_chunks)
Saída:
[Boston Dynamics, thousands, robot dogs]
Embora derivar noun chunks a partir de uma frase específica ajude muito,
o spaCy fornece outros atributos que também podem ser úteis. Veremos
alguns deles.
Exemplo 2:
doc = nlp(u"Deep learning cracks the code of messenger RNAs and protein-coding
potential")
# (O deep learning decifra o código de RNAs mensageiros e a potencial codificação
de proteínas)
for chunk in doc.noun_chunks:
print([Link], [Link], [Link].dep_,
[Link])
Saída:
TEXT [Link] ROOT.DEP_ [Link]
deep learning learning nsubj cracks
the code code dobj cracks
messenger RNAs RNAs pobj of
protein-coding potential potential conj RNAs
Como podemos ver nessa tabela, obtivemos os noun chunks e seus
atributos. A tabela a seguir ajuda a entender cada coluna.
Coluna Significado
Texto do noun chunk original.
Text
Root text Texto da palavra original que conecta o noun chunk ao resto do parsing.
Root dep Relação de dependência que conecta a raiz ao head.
Root head text Texto do head raiz do token.
Buscando semelhanças
A busca de semelhanças entre duas palavras é um caso de uso que você
encontrará com frequência ao trabalhar com NLP. Pode ser muito
importante saber se duas palavras são semelhantes. Ao construir chatbots
você deparará com situações em que terá de descobrir não só palavras de
aparência semelhante como também o quanto duas palavras estão
logicamente relacionadas.
O spaCy usa vetores de palavras de alta qualidade para encontrar
semelhanças entre duas palavras com o algoritmo GloVe (Global Vectors
for Word Representation).
GloVe é um algoritmo de aprendizado não supervisionado para a obtenção
de representações vetoriais para palavras. O algoritmo GloVe usa as
estatísticas globais de co-ocorrência agregada de palavra-palavra de um
acervo para treinar o modelo.
Examinaremos os valores existentes nos vetores do spaCy usando o
atributo vector do token.
doc = nlp(u'How are you doing today?')
# (Como você está hoje?)
for token in doc:
print([Link], [Link][:5])
Saída:
(u'How', array([-0.29742685, 0.73939574, -0.04001453, 0.44034013, 2.8967502],
dtype=float32))
(u'are', array([-0.23435134, -1.6145049, 1.0197453, 0.9928169, 0.28227055],
dtype=float32))
(u'you', array([ 0.10252178, -3.564711, 2.4822793, 4.2824993 , 3.590245],
dtype=float32))
(u'doing', array([-0.6240922, -2.0210216, -0.91014993, 2.7051923 , 4.189252],
dtype=float32))
(u'today', array([ 3.5409122, -0.62185854, 2.6274266, 2.0504875 , 0.20191991],
dtype=float32))
(u'?', array([ 2.8914998, -0.25079122, 3.3764176, 1.6942682, 1.9849057 ],
dtype=float32))
Apenas olhar para essa saída não revela muito sentido ou significado. Do
ponto de vista da aplicação, o que importa é quanto os vetores das
diferentes palavras são semelhantes – isto é, o próprio significado da
palavra.
Para encontrar semelhanças entre duas palavras no spaCy, podemos fazer o
seguinte.
Exemplo 1:
hello_doc = nlp(u"hello")
hi_doc = nlp(u"hi")
hella_doc = nlp(u"hella")
print(hello_doc.similarity(hi_doc))
print(hello_doc.similarity(hella_doc))
Saída:
0.7879069442766685 (diferença entre hello e hi)
0.4193425861242359 (diferença entre hello e hella)
No caso da palavra hello, ela tem mais conexão e semelhança com a
palavra hi, ainda que haja a diferença de apenas um caractere entre as
palavras hello e hella.
Veremos mais um exemplo de frase para aprender como o spaCy faz a
comparação de semelhanças. Lembra do exemplo com Game of Thrones
das seções anteriores? Vamos usá-lo para testar a semelhança.
Código:
GoT_str1 = nlp(u"When will next season of Game of Thrones be releasing?")
# (Quando será lançada a próxima temporada de Game of Thrones?)
GoT_str2 = nlp(u"Game of Thrones next season release date?")
# (Data de lançamento da próxima temporada de Game of Thrones?)
GoT_str1.similarity(GoT_str2)
Saída:
0.785019122782813
Como podemos ver nesse exemplo, a semelhança entre as duas frases é de
cerca de 79%, que é suficientemente boa para sabermos que elas são muito
semelhantes, o que é verdade. Isso pode economizar muito tempo na
criação de um código personalizado para a construção de chatbots.
Chegamos à conclusão de que o spaCy demonstra uma semelhança
significativa entre duas palavras usando vetoriais em vez de apenas
examinar sua grafia ou letras.
Usaremos um exemplo muito simples para tentar encontrar a semelhança
entre palavras.
example_doc = nlp(u"car truck google")
# (carro caminhão google)
for t1 in example_doc:
for t2 in example_doc:
similarity_perc = int([Link](t2) * 100)
print "Word {} is {}% similar to word {}".format([Link],
similarity_perc, [Link])
Saída:
Word car is 100% similar to word car (A palavra carro é 100% semelhante à
palavra carro)
Word car is 71% similar to word truck
Word car is 24% similar to word google
Word truck is 71% similar to word car
Word truck is 100% similar to word truck
Word truck is 36% similar to word google
Word google is 24% similar to word car
Word google is 36% similar to word truck
Word google is 100% similar to word google
A busca de semelhança entre palavras ou frases será importante se
construirmos uma aplicação que dependa muito das implementações do
NLP. Se você já usou o StackOverFlow, sabe que, sempre que fazemos uma
nova pergunta, ele lista perguntas semelhantes já feitas na plataforma. Esse
é um dos melhores exemplos em que a busca de semelhança entre dois
conjuntos de frases pode ajudar. A segurança que o spaCy fornece na busca
da semelhança entre duas palavras baseada em um modelo já treinado
depende exclusivamente do tipo de suposição geral feita.
Na construção de chatbots, a busca de semelhanças pode ser muito útil
para as seguintes situações:
• Em chatbots para recomendação.
• Na remoção de cópias.
• Na construção de um verificador ortográfico.
Esses tópicos são muito importantes na construção de chatbots para
sabermos como analisar as entradas do usuário de modo que elas façam
sentido na criação da lógica do negócio dentro do código.
É bom conhecer os recursos de NLP para chatbots
Nesta seção aprenderemos dois tópicos interessantes que costumam ser
úteis na criação de métodos de NLP personalizados para a manipulação de
certos cenários. Não deixe de examiná-los, porque, quando menos esperar,
você pode precisar deles. Discutiremos resumidamente a tokenização e o
uso de expressões regulares em um cenário de chatbot.
Tokenização
A tokenização é um conceito simples, porém básico, do NLP, em que
dividimos um texto em segmentos significativos. A primeira coisa que o
spaCy faz é a tokenização do texto (isto é, ele o segmenta em palavras e
depois em pontuação e outros elementos). Uma pergunta pode lhe ocorrer:
por que não posso usar o método interno split da linguagem Python para
executar a tokenização? O método split de Python é somente um método
bruto que divide a frase em tokens dado um separador. Ele não considera o
significado, enquanto a tokenização tenta preservá-lo.
Examinaremos alguns códigos para ver como a tokenização funciona.
Exemplo 1:
doc = nlp(u'Brexit is the impending withdrawal of the U.K. from the European
Union.')
# (Brexit é a iminente saída do Reino Unido da União Europeia)
for token in doc:
print([Link])
Saída:
Brexit
is
the
impending
withdrawal
of
the
U.K.
from
the
EuropeanUnion
Se você examinar a saída anterior, U.K. aparece como uma única palavra
após o processo de tokenização, o que faz sentido, já que é o nome de um
país e seria errado dividi-lo. Mesmo se depois disso você não estiver
satisfeito com a tokenização do spaCy, pode usar seu método case
add_special_case para adicionar sua própria regra antes de confiar totalmente
no método do spaCy.
Expressões regulares
Você já deve conhecer as expressões regulares e como são usadas. Este livro
presume que, de uma forma geral, você esteja familiarizado com elas.
Nesta seção, apenas percorreremos alguns exemplos e veremos como as
expressões podem ser benéficas e úteis na construção de chatbots.
A análise e o processamento de texto são tópicos por si só extensos. Às
vezes as palavras se unem de tal forma que é extremamente difícil para as
máquinas entenderem e serem treinadas com elas.
A expressão regular pode ser útil como fallback de um modelo de machine
learning. Ela compara padrões, o que pode assegurar que os dados que
estamos processando estão corretos ou incorretos. Quase todos os chatbots
iniciais discutidos no Capítulo 1 na seção de história dos chatbots
dependiam muito da comparação de padrões.
Veremos a seguir dois exemplos que são muito fáceis de entender.
Tentaremos usar a expressão regular para extrair informações de duas
frases.
Book me a metro from Airport Station to Hong Kong Station. (Compre
uma passagem de metrô da estação do aeroporto para a estação de Hong
Kong).
Book me a cab from Hong Kong Airport to AsiaWorld-Expo (Chame
um táxi do aeroporto de Hong Kong para a AsiaWorld-Expo).
Aqui está o código:
sentence1 = "Book me a metro from Airport Station to Hong Kong Station."
sentence2 = "Book me a cab to Hong Kong Airport from AsiaWorld-Expo."
import re
from_to = [Link]('.* from (.*) to (.*)')
to_from = [Link]('.* to (.*) from (.*)')
from_to_match = from_to.match(sentence2)
to_from_match = to_from.match(sentence2)
if from_to_match and from_to_match.groups():
_from = from_to_match.groups()[0]
_to = from_to_match.groups()[1]
print("from_to pattern matched correctly. Printing values\n")
print("From: {}, To: {}".format(_from, _to))
elif to_from_match and to_from_match.groups():
_to = to_from_match.groups()[0]
_from = to_from_match.groups()[1]
print("to_from pattern matched correctly. Printing values\n")
print("From: {}, To: {}".format(_from, _to))
Saída:
to_from pattern matched correctly. Printing values
(o padrão de_para coincidiu corretamente. Exibindo valores)
From: AsiaWorld-Expo., To: Hong Kong Airport
(De: AsiaWorld-Expo., Para: Aeroporto de Hong Kong)
Tente alterar sentence2 para sentence1 e veja se o código funciona bem para
identificar o padrão. Devido ao poder atual do machine learning, a
expressão regular e a comparação de padrões foram deixadas um pouco de
lado, mas certifique-se de se atualizar nesses assuntos porque eles podem
ser necessários em algum momento na análise de detalhes específicos de
palavras, frases ou documentos de texto.
Resumo
A essa altura, você já deve ter uma boa noção de por que precisamos
conhecer NLP antes de começar a construir chatbots. Neste capítulo,
examinamos o módulo spaCy de Python, seus recursos e como instalá-lo.
Estudamos vários métodos de NLP que são muito usados na construção de
chatbots. Conhecemos a marcação POS, a diferença entre stemização e
lematização, o reconhecimento de entidades, o noun-chunking e a busca
de semelhanças entre conjuntos de palavras.
Executamos códigos para todos esses conceitos e aprendemos tudo
fazendo, e não apenas lendo, exatamente o que o livro enfatiza. Também
recapitulamos os aspectos básicos da tokenização e das expressões
regulares. Daremos continuidade e construiremos nosso chatbot no
próximo capítulo usando uma ferramenta disponível gratuitamente
chamada Dialogflow. Aprenderemos como treinar o chatbot para entender
e extrair informações fornecidas pelo usuário.
1 [Link]
2 [Link]
3 [Link]
4 [Link]
CAPÍTULO 3
Construindo chatbots da maneira mais fácil
Este capítulo foi escrito levando em consideração que podemos não querer
construir tudo a partir do zero desejando apenas concluir a tarefa. Este
capítulo não requer muita codificação, mas mesmo assim lhe dará uma boa
noção de como construir chatbots de maneira fácil e torná-los públicos.
A razão que torna este capítulo tão importante para aprendermos a
construir chatbots é que o universo dos programas se move com muita
rapidez para ser adaptado. Há situações em que temos de construir
aplicações rapidamente e procuramos ferramentas disponíveis em
bibliotecas open source que possam ser usadas na construção urgente de
programas, sem a necessidade de reinventar a roda. Podemos não ser tão
bons em codificação para construir tudo a partir do zero. Mesmo se
quisermos construir aplicações a partir do zero, não poderemos porque a
curva de aprendizado é muito íngreme para um iniciante.
Este capítulo o ajudará a construir chatbots muito rapidamente e a torná-
los públicos para todos usarem.
Usaremos uma ferramenta anteriormente conhecida como [Link]. Agora
ela se chama Dialogflow.
Introdução ao Dialogflow
O Dialogflow fornece aos usuários novos métodos para a interação com
seu produto pela construção de interfaces conversacionais interessantes
baseadas em voz e texto, como os aplicativos e chatbots baseados em voz.
O Dialogflow é suportado por IA. Ele ajuda a nos conectarmos com os
usuários no site, aplicativo móvel, Google Assistant, Amazon Alexa,
Facebook Messenger e outras plataformas e dispositivos populares.
O diagrama do Dialogflow a seguir mostra como ele manipula uma
solicitação do usuário.
Figura 3.1 – Diagrama de funcionamento da arquitetura do Dialogflow.
Veja o que acontece:
1. O usuário conversa com o dispositivo de entrada.
2. A consulta do usuário entra no mecanismo do Dialogflow.
3. O Dialogflow tenta reconhecer a intenção.
4. Com base na intenção, um fulfillment é executado e os dados são
retornados pelo banco de dados.
5. Uma reposta é dada para a intenção.
6. A resposta é convertida em dados acionáveis.
7. O pedido de informação do usuário é respondido para o dispositivo de
saída.
Há um conceito de agentes no Dialogflow cuja descrição mais apropriada
seria a de módulos de Natural Language Understanding (NLU). Eles
podem ser incluídos em nosso aplicativo, produto ou serviço e transformar
as solicitações naturais do usuário em dados acionáveis. Essa
transformação ocorre quando a entrada do usuário corresponde a uma das
intenções existentes no agente.
Os agentes também podem ser projetados para gerenciar um fluxo de
conversa de maneira específica. Isso pode ser feito com a ajuda de
contextos, prioridades de intenções, preenchimento de slots,
responsabilidades, e fulfillment por webhook.
Partindo para a ação
O que aprendemos até agora foi e é importante porque nem sempre as
ferramentas e pacotes disponíveis no ambiente open source ajudam na
construção de uma aplicação de chatbot completa.
Muitas vezes deparamos com uma situação em que preferimos construir
tudo por nossa própria conta para termos mais controle sobre a aplicação.
Aprenderemos isso no próximo capítulo e também usaremos as técnicas de
NLP já estudadas.
Neste capítulo criaremos um chatbot como prova de conceito e o
deixaremos pronto para uso com pouca ou nenhuma experiência em
programação.
Construindo um chatbot de pedido de comida
Criaremos um chatbot para um restaurante específico com a ajuda do
Dialogflow. Vamos chamá-lo de OnlineEatsBot, que na abreviação ficará
produto OnlineEats. Você pode escolher outro caso de uso para o qual
queira construir o chatbot. Neste capítulo construiremos um chatbot de
pedido de comida.
Definindo o escopo
Definiremos o escopo do chatbot – isto é, o que ele pode fazer e até que
ponto.
• Deve ser capaz de cumprimentar o usuário dinamicamente.
• Tem que entender os itens do menu e a quantidade solicitada.
• O chatbot precisa fazer um pedido em nome do usuário.
• Tem de fornecer para o usuário o status do pedido quando solicitado.
Listando as intenções
Agora listaremos as intenções com as quais queremos que nosso chatbot
seja treinado para que ele consiga entendê-las quando solicitadas pelo
usuário.
Intenções:
• Intenção de boas-vindas padrão: quando o usuário envia a mensagem
para o chatbot.
• Intenção de pedido de comida: quando o usuário solicita ao bot que
faça o pedido de comida.
• Intenção de descrição de item: quando o usuário informa o item e a
quantidade que deseja.
• Status do pedido: quando o usuário deseja saber o status de seu
pedido.
• ID do pedido (Order_ID): o bot precisa saber o ID do pedido do
usuário para rastreamento.
• Agradecimento do usuário: quando o usuário agradece ao bot.
Listando entidades
Tentaremos listar todas as entidades que podem existir para as intenções.
Mais à frente no capítulo elas serão definidas para qualquer que seja a
intenção a que forem aplicáveis.
Entidades:
• food_items: o prato que o usuário deseja pedir.
• quantities: a quantidade do item que o usuário quer pedir.
• order_id: id do pedido do usuário.
Construindo um chatbot de pedido de comida
Também definiremos o mínimo que esperamos que o chatbot faça. Para
isso, criaremos o roteiro de uma conversa entre nosso chatbot e o usuário.
Esse recurso nos ajudará a seguir o plano de termos um chatbot básico e
funcional pronto, supondo que o usuário converse de maneira apropriada e
correta.
Roteiro de conversa entre o chatbot e o usuário:
Usuário: Hello (Olá)
OnlineEatsBot: Hello and Welcome! How may I help you? (Olá e bem-
vindo! Como posso ajudá-lo?)
Usuário: I am looking to order Chinese food (Quero fazer um pedido de
comida chinesa)
OnlineEatsBot: Sure, what would you like to order today? (Certo, o que
gostaria de pedir hoje?)
Usuário: One chicken dumpling and two spring rolls (Um dumpling de
frango e dois rolinhos primavera)
OnlineEatsBot: Done. Your final amount is XYZ, and your order is
placed for 1 Chicken dumpling and 2 spring rolls (Tudo bem. O preço
final é XYZ e seu pedido de 1 dumpling de frango e 2 rolinhos primavera
foi feito)
Usuário: I haven’t received my order yet. Where is my food? (Ainda não
recebi meu pedido. Cadê a comida?)
OnlineEatsBot: Can you please help me with your order ID? (Pode, por
favor, me passar o número do pedido?)
Usuário: 123456
OnlineEatsBot: Order Status for Order ID: 123456. The delivery guy is
in your locality, your food will arrive in about 5 minutes (Status de ID
de pedido: 123456. O entregador está em sua região, a comida chegará
em cerca de 5 minutos)
Usuário: Thanks (Obrigado)
OnlineEatsBot: Thanks a lot for your cooperation (Obrigado pela
cooperação)
Agora que criamos um roteiro básico para ser seguido na construção de
nosso chatbot, examinaremos o Dialogflow.
Começando a usar o Dialogflow
Executaremos as etapas a seguir para criar uma conta no Dialogflow e
depois criaremos um agente. (Agente é apenas outro nome para chatbot).
1. Crie uma conta em [Link] e faça login com ela.
2. Crie um agente.
Figura 3.2 – Criando um novo agente no Dialogflow.
Insira os detalhes, como o nome do agente, o fuso horário, o idioma
padrão e o Projeto Google que deseja selecionar ou crie um novo
projeto Google.
3. Crie as intenções.
Se você examinar a Figura 3.3, verá que já são fornecidas duas intenções.
• Default fallback intent (Intenção de contingência padrão): As intenções de
contingência são acionadas quando a entrada do usuário não
corresponde a nenhuma das intenções regulares ou bate-papo
internos ativados. Quando criamos um novo agente, uma intenção de
contingência padrão é gerada automaticamente. Você pode modificá-
la ou excluí-la se quiser.
• Default welcome intent (Intenção de boas-vindas padrão): Podemos estender
essa intenção de boas-vindas para nossos próprios chatbots. Você
deve adicionar as próprias expressões de usuário e respostas padrão.
Figura 3.3 – Criando intenções no Dialogflow.
Antes de criarmos nossas próprias intenções, adicionaremos alguns
enunciados à intenção de boas-vindas padrão para deixá-la pronta
executando as etapas a seguir:
1. Clique na intenção de boas-vindas padrão.
2. Adicione as próprias expressões de usuário em Training Phrases (Frases de
Treinamento).
3. Clique em SAVE.
Quando clicarmos em "save", os modelos de machine learning serão
executados em segundo plano e treinados com os dados que fornecemos
(isto é, as expressões do usuário). Ser treinado com os dados significa a
máquina identificar o tipo de intenção de acordo com os dados fornecidos
e detectar quando passarmos novos dados para ela. Por exemplo, se
examinarmos a Figura 3.4, na qual definimos cinco expressões de usuário
que a máquina já sabe que pertencem à "intenção de boas-vindas", o que
acontecerá se o usuário usar a expressão "Hello there" (Olá), que não foi
definida? A máquina também categorizará "Hello there" como intenção de
boas-vindas padrão, já que os recursos usados no treinamento e na
máquina para a intenção de boas-vindas são semelhantes na nova
expressão de usuário.
Figura 3.4 – Definindo uma intenção de boas-vindas ou saudação padrão no
Dialogflow.
Veremos se a intenção de boas-vindas funciona para nós. Com o
Dialogflow podemos fazer isso no próprio dashboard. Consulte a Figura
3.5.
Figura 3.5 – Testando a intenção de boas-vindas no Dialogflow.
Pontos que devemos lembrar ao criar intenções
Examinaremos alguns pontos importantes que precisamos lembrar ao criar
intenções no Dialogflow.
• No Dialogflow também há o recurso de cada intenção ter uma resposta
padrão. A reposta padrão é uma resposta retornada para o usuário
sempre que a intenção é reconhecida. Em nosso exemplo, quando um
usuário diz "Hello there" (Olá), ele recebe "Hello!" (Olá) como resposta
do bot.
• Se quiser, você pode adicionar mais respostas ou excluir respostas
existentes; a existência de mais de uma resposta faz o bot parecer mais
real por não responder sempre com a mesma resposta, e o usuário se
sentirá conversando com um humano ao falar com ele.
• As intenções do Dialogflow também podem ser marcadas como fim da
conversa. Ou seja, você pode permitir que o bot assuma que o usuário
não participará mais da conversa e, baseado nessa informação, execute
a ação necessária para encerrá-la.
Criando intenções e adicionando enunciados
Agora que criamos a intenção de boas-vindas, criaremos a intenção do
pedido. Chamei-a de place_order_intent. A seguir temos as expressões de
usuário que inseri:
I want food (Quero fazer um pedido de comida)
I want to order food asap (Quero fazer um pedido de comida o mais
rápido possível)
Can you please take my order for food? (Você poderia anotar meu
pedido de comida?)
Take my order please (Anote meu pedido por favor)
I want to place an order for Chinese food (Quero pedir comida chinesa)
I want to place an order (Quero fazer um pedido)
Would you please help me to order food? (Você poderia me ajudar a
pedir um prato?)
Can you please order food for me? (Você poderia fazer um pedido de
comida para mim?)
I want to order food (Quero comprar um prato)
I am looking to order Thai food (Quero fazer um pedido de comida
tailandesa)
I am looking to order Chinese food (Quero fazer um pedido de comida
chinesa)
Já construímos a intenção que identificará as expressões de usuário
anteriores ou relacionadas. É hora de adicionar a resposta do usuário
usando a resposta padrão.
Adicionando a resposta padrão à intenção
Adicionaremos as três respostas que poderão ser retornadas para o usuário
uma vez que place_order_intent for encontrada.
Sure, What would you like to order today? (Certo, o que gostaria de
pedir hoje?)
Definitely, What would you like to have today? (Fique à vontade, o que
gostaria de comer hoje?)
Certainly, I'll try to help you with that. What are you feeling like eating
today? (Certo, tentarei ajudá-lo. O que gostaria de comer hoje?)
A próxima etapa é esperar o usuário inserir os itens desejados e analisá-los
(parse).
Criaremos uma nova intenção que nos informe o que o usuário deseja
pedir (isto é, os alimentos).
A nova intenção se chamará items_description.
Primeiro, adicionaremos nossa expressão de usuário padrão.
One chicken dumpling and two spring rolls. (Um bolinho recheado de
frango e dois rolinhos primavera).
Quando adicionarmos a expressão do usuário, poderemos selecionar as
palavras específicas que serão as entidades da intenção. Elas podem ser
quantidade, data ou hora, local etc., que são predefinidas, mas também
podemos criar nossas próprias entidades clicando no botão Create New na
parte inferior direita após ser aberta a caixa pop-up.
Realce a palavra do enunciado para a qual você deseja que a palavra
selecionada seja uma entidade. Em seguida, será aberta a caixa pop-up
para a criação de nossa própria entidade.
Nesse exemplo, temos de analisar os dados em um formato amigável e
legível para podermos usá-los em qualquer linguagem de programação. O
formato JSON é o melhor que podemos usar nas aplicações
multiplataforma atuais. O Dialogflow retorna os dados em formato JSON
por padrão, que podem ser analisados para ficarem parecidos com o
código a seguir. É recomendável que você sempre mantenha os dados com
o menor tamanho possível; não sobrecarregue a resposta da API
fornecendo dados demais. Lembre-se de que em uma escala maior tudo
isso tem um custo.
{
"food_items": {
"chicken dumpling": 1,
"Spring rolls": 2
}
}
Intenção de descrição de itens e entidades relacionadas
Podemos selecionar os valores One e Two e defini-los como @[Link], que é
apenas o tipo de dado. Criaremos uma nova entidade chamada
food_items_entity para identificar os itens de refeição.
Se você examinar a Figura 3.6, verá que temos uma entidade chamada
food_items_entity, mas, quando selecionamos as palavras, nomeamos os
parâmetros com food_items_entity1 e food_items_entity2; isso também ocorre
para a quantidade de comida, que é um número para o qual nomeamos o
primeiro e o segundo parâmetros com quantity1 e quantity2, respectivamente.
Figura 3.6 – Intenção de descrição de itens.
O que definimos aqui nos ajudará a entender a resposta JSON, que
obteremos após a intenção ser acionada. Precisamos ter todos esses valores
para avançar no fluxo do chatbot.
Selecione a palavra ou a combinação de palavras inteira e clique em Create
New. Uma nova tela surgirá para a criação de entidades; apenas insira o
nome dessa nova entidade e salve.
Agora volte à intenção items_description e deve ver algo como a Figura 3.6.
Continue a adicionar expressões de usuário às frases de treinamento e
defina as entidades existentes nelas.
Adicionamos quatro enunciados até agora que ficaram com a aparência
que vimos. Adicionaremos o máximo possível para melhorar a precisão de
nosso agente na classificação de intenções.
O Dialogflow também tem um recurso de compartilhamento dos dados de
treinamento do agente. Os dados de treinamento usados neste livro podem
ser acessados no site da Apress, [Link]
with-python. Como você pode ver na Figura 3.7, estamos adicionando mais
exemplos à intenção de descrição de itens de nosso agente do Dialogflow.
Figura 3.7 – Adicionando mais enunciados à intenção de descrição de itens.
Já salvamos nossa intenção e o agente terminou de treinar os modelos. Se
inserirmos a frase a seguir no lado direito, devemos ver esta resposta JSON:
One chicken dumpling and two spring rolls
Resposta da intenção:
{
"id": "e8cf4a44-6ec9-49ae-9da8-a5542a80d742",
"timestamp": "2018-04-01T21:22:42.846Z",
"lang": "en",
"result": {
"source": "agent",
"resolvedQuery": "One chicken dumpling and two spring rolls",
"action": "",
"actionIncomplete": false,
"parameters": {
"quantity1": 1,
"food_items_entity1": "chicken dumpling",
"quantity2": 2,
"food_items_entity2": "spring rolls"
},
"contexts": [],
"metadata": {
"intentId": "0b478407-1b37-4f9a-8779-1866714dd44f",
"webhookUsed": "false",
"webhookForSlotFillingUsed": "false",
"intentName": "items_description"
},
"fulfillment": {
"speech": "",
"messages": [
{
"type": 0,
"speech": ""
}
]
},
"score": 1
},
"status": {
"code": 200,
"errorType": "success",
"webhookTimedOut": false
},
"sessionId": "e1ee1860-06a7-4ca1-acae-f92c6e4a023e"
}
Se você examinar a seção parameters da resposta JSON, verá
{
"quantity1": 1,
"food_items_entity1": "chicken dumpling",
"quantity2": 2,
"food_items_entity2": "spring rolls"
}
Podemos escrever facilmente um código Python para converter a resposta
JSON para o formato desejado que discutimos.
CONSEGUE FAZÊ-LO?
Teste suas habilidades em Python e tente escrever um código que leia uma resposta JSON como
a anterior e retorne a quantidade e o item de refeição relacionado a ela no outro formato JSON
já discutido.
Entendendo e respondendo para o usuário
A próxima etapa da conversa é fazer o bot responder para o usuário que o
pedido foi entendido e incluir informações novas. As novas informações
podem ser o order_id gerado, a quantidade pedida ou o tempo de espera
estimado. Esses itens serão fornecidos na extremidade do seu servidor e
você pode formulá-los com a resposta do bot para retorná-la para o
usuário.
Agora tentaremos adicionar o preço do pedido de nosso exemplo; para
fazê-lo, podemos usar o recurso de resposta padrão do Dialogflow e
adicionar essa informação dentro da intenção. Por enquanto, embutiremos
o preço no código, porque ele vai variar de acordo com os itens de refeição,
sua quantidade ou o restaurante. Posteriormente neste mesmo capítulo,
discutiremos como fazer isso dinamicamente chamando uma API.
O interessante aqui é que podemos acessar os parâmetros obtidos a partir
da intenção (isto é, os itens de refeição e suas quantidades).
As respostas podem conter referências a valores de parâmetros. Já vamos
entender isso.
Se um parâmetro estiver presente na tabela de parâmetros, podemos usar o
formato a seguir para referenciar seu vaIor em 'Text response'field:
$parameter_name.
Podemos usar esses parâmetros na resposta padrão para que o bot
confirme o pedido para o usuário.
Adicione "Done. Your final amount is XYZ and your order is placed for $quantity1
$food_items_entity1 and $quantity2 $food_items_entity2" (Tudo bem. O preço final
é XYZ e seu pedido de $quantity1 $food_items_entity1 e $quantity2
$food_items_entity2 foi feito) como resposta.
Nota Se nossa intenção não puder analisar os itens de refeição ou sua
quantidade, temos de fornecer uma resposta padrão diferente que
peça explicações sobre o que o bot não conseguiu entender ou pelo
menos para confirmar. Já aprendemos como adicionar a resposta
padrão a uma intenção na seção "Adicionando a resposta padrão à intenção".
Intenção de status do pedido
Agora criaremos a intenção order_status, na qual o usuário tentará saber o
status do pedido após ele ser feito.
A Figura 3.8 fornece algumas frases de treinamento que adicionamos à
intenção de status do pedido, que chamamos de order_status.
Figura 3.8 – Criando a intenção de status do pedido.
Tentaremos criar alguns enunciados aleatórios de solicitação de status do
pedido e veremos se nosso agente é inteligente o bastante para identificar a
intenção.
Fiz o teste com "Haven't received my food yet" (Ainda não recebi minha
comida) e vejam só – meu agente entendeu perfeitamente que se trata de
uma intenção order_status.
Consulte resolvedQuery e intentName no código JSON da Figura 3.9.
Figura 3.9 – Resposta JSON do Dialogflow após a consulta ser resolvida.
Intenção User_Order_ID
A próxima etapa é solicitar ao usuário o ID do pedido, logo, definiremos a
resposta padrão dessa intenção para a pergunta a seguir.
Can you please help me with your order ID? (Pode, por favor, me passar
o número do pedido?)
O usuário fornecerá o ID do pedido e nossa tarefa é identificar isso e
fornecer uma resposta novamente.
Para fazê-lo, precisamos criar outra intenção a fim de identificar que o
usuário está fornecendo o ID do pedido.
Observe que as intenções que estamos criando são independentes umas
das outras. Nesse caso, sabemos que o usuário fornecerá o ID do pedido,
que quase sempre é o ID correto. Se estiver errado, você pode voltar ao
usuário e perguntar novamente.
Também é preciso lembrar que, em alguns casos, order_id e o número do
telefone podem ser números inteiros. Nesses casos, temos de executar uma
validação, para o número de dígitos de order_id ou o número do telefone.
Além disso, de acordo com o contexto da pergunta anterior, temos como
saber se o usuário está fornecendo um order_id ou um número de telefone.
Como discutido no Capítulo 1, podemos usar árvores de decisão para ter
um gerenciamento melhor do fluxo do chatbot. Também podemos rastrear
programaticamente que estamos solicitando o ID do pedido após
order_status e que o usuário enviará um ID (algum número), o que é mais
fácil de analisar em código do que em uma nova intenção.
Nesse exemplo, criaremos a intenção user_order_id, já que não há nenhum
conflito.
Criaremos, então, uma nova intenção chamada user_order_id.
A Figura 3.10 mostra como ficou a intenção.
Figura 3.10 – Definindo a intenção de ID de pedido de usuário em nosso
agente.
Testei algumas expressões, tudo funcionou bem, e elas foram classificadas
corretamente como pertencentes à intenção user_order_id. Teste sempre
usando o console do Dialogflow para ver se sua intenção está se
comportando como esperado.
Agora definiremos a resposta padrão da intenção user_order_id com a
seguinte frase do bot:
Order Status for Order ID: $order_id .The delivery guy is in your locality,
(Status de ID de pedido: $order_id.
your food will arrive in about 5 minutes
O entregador está em sua região, a comida chegará em cerca de 5
minutos).
Estamos usando novamente o parâmetro analisado da intenção
user_order_id para preparar uma resposta para o usuário.
Intenção User_Thanks
Provavelmente o usuário agradecerá, ou fará alguma outra coisa, logo,
criaremos uma nova intenção chamada user_thanks para identificar as
maneiras pelas quais ele dirá obrigado. Isso é importante porque, uma vez
que o usuário disser thanks (obrigado), independentemente de como o
disser, nosso bot deve responder o mesmo.
Não devemos apenas esperar o usuário agradecer após a resposta padrão
de status da entrega e responder cegamente; temos de tentar identificar isso
usando intenções personalizadas.
A Figura 3.11 mostra a aparência de nossa intenção user_thanks.
Figura 3.11 – Definindo uma intenção para quando o usuário agradecer.
É hora de agradecer ao usuário usando o recurso de resposta padrão e
marcar essa intenção como fim da conversa.
Adicionaremos algum texto, por exemplo, "Thanks a lot for your
cooperation" (Obrigado pela cooperação), como nossa resposta padrão.
Podemos adicionar outras respostas desse tipo para que o bot pareça mais
realista (Figura 3.12).
Examine a Figura 3.12 e verá que marcamos essa intenção como fim da
conversa.
Se integrarmos nosso bot ao Google Assistant, essa marcação significará o
desligamento do microfone quando a intenção for concluída.
Já criamos o bot, o construímos de acordo com o design e o roteiro iniciais
e o treinamos. Hora de implantá-lo na web e ver como ficou.
Figura 3.12 – Adicionando uma resposta a uma intenção do usuário no
agente.
Implantando o chatbot do Dialogflow na web
Nessa parte, integraremos nosso bot a várias plataformas famosas como o
Facebook Messenger, Twitter, Slack etc., e veremos se funciona. Há muitas
outras plataformas às quais você pode integrar esse bot facilmente.
Por enquanto, testaremos o bot com a Web Demo e o Facebook
Messenger.
Acessaremos a página Integrations de nossa conta do Dialogflow e
ativaremos a Web Demo. Você verá um pop-up como o da Figura 3.13.
Clique no link do pop-up.
Figura 3.13 – Link de web demo do Dialogflow.
Aparecerá algo semelhante ao exibido entre as Figuras 3.14.1 e 3.14.4.
Testei meu bot com a conversa que criamos e ele funcionou muito bem.
Figura 3.14.1 – Tela I da conversa com a demo do OnlineEatsBot.
Figura 3.14.2 – Tela II da conversa com a demo do OnlineEatsBot.
Figura 3.14.3 – Tela III da conversa com a demo do OnlineEatsBot.
Também podemos embutir esse bot em nosso próprio site usando o código
iframe encontrado na janela pop-up.
Você pode conversar com meu OnlineEatsBot aqui:
[Link]
Figura 3.14.4 – Tela IV da conversa com a demo do OnlineEatsBot.
Compartilhe seu bot com seus amigos e família e veja como eles interagem
com o bot de maneira legítima. Se o chatbot não estiver fazendo algo
esperado, tente resolver o problema.
Integre o chatbot do Dialogflow ao Facebook Messenger
Nesta seção, tentaremos integrar o mesmo chatbot ao Facebook Messenger
para que os usuários da plataforma Facebook também possam usá-lo sem
precisar acessar nosso site.
Voltaremos à página de integrações no dashboard do Dialogflow e
ativaremos o ícone do Facebook Messenger; agora clique nele e deve
aparecer um pop-up semelhante ao anterior.
Precisamos ir ao Facebook, registrar um aplicativo e obter o token
requerido.
• Token de verificação (qualquer string, somente para nossa finalidade).
• Token de acesso à página (insira o token gerado no Console de
Desenvolvedor do Facebook).
A integração do Facebook ao Dialogflow é muito útil para facilitar a
criação de um bot do Facebook Messenger com NLU, baseada na
tecnologia do Dialogflow.
Configurando o Facebook
Para fazer nosso bot funcionar no Facebook da mesma forma que já vinha
funcionando, temos de fazer o seguinte:
1. Crie uma conta do Facebook, se ainda não a tiver.
2. Crie uma página no Facebook para poder adicionar seu bot.
Quando um usuário visitar sua página no Facebook e lhe enviar uma
mensagem, falará diretamente com seu bot.
Criando um aplicativo do Facebook
As etapas a seguir são para a criação de um aplicativo:
1. Faça login no Console de Desenvolvedor do Facebook.
2. Clique em My Apps no canto superior direito.
3. Clique em Add a New App e insira um nome e um endereço de email.
4. Clique em Create App ID como mostrado na Figura 3.15.
Figura 3.15 – Criando um novo aplicativo na Plataforma de Desenvolvedor
do Facebook.
5. Na próxima página, clique no botão Set Up da opção Messenger.
6. Na seção Token Generation, selecionaremos a página do Facebook à qual
queremos que nosso bot se conecte (Figura 3.16).
Isso gerará um Token de Acesso à Página. Permaneça com esse token,
porque teremos de inseri-lo no Dialogflow.
Figura 3.16 – Gerando o token pela seleção da página do bot no Facebook.
Configurando o console do Dialogflow
Aqui estão as etapas:
1. Clique na opção Integrations no menu esquerdo do console do
Dialogflow e ative Facebook Messenger se ainda não o fez. No pop-up que
abrirá, insira as informações a seguir como mostrado na Figura 3.17 –
Configurando e integrando o Dialogflow ao Facebook Messenger:
• Verify Token (Token de verificação): pode ser a string que você quiser que
atenda à sua finalidade.
• Page Access Token (Token de acesso à página): insira o token gerado no
Console de Desenvolvedor do Facebook.
2. Clique no botão Start.
Figura 3.17 – Configurando e integrando o Dialogflow ao Facebook
Messenger.
Deve aparecer uma mensagem dizendo "Bot was started" (O bot foi iniciado).
Isso significa que podemos prosseguir.
Você deve estar se perguntando o que são URL de callback, token de
verificação e token de acesso à página. Tentarei explicar.
URLs de callback
A URL de callback é apenas uma URL acessada publicamente para a qual o
Facebook envia solicitações em tempo real vindas de nossa página.
Suponhamos que você estivesse tentando fazer o pagamento da comida no
OnlineEats e fosse redirecionado para a página de pagamentos de um
banco. O OnlineEats deve estar fornecendo a URL de callback dos bancos
aos quais ele poderá redirecionar o usuário após o pagamento ser feito.
Em nosso exemplo, o Facebook não fará um redirecionamento; ele pegará
tudo que nosso usuário informou no chatbox e enviará para o webhook ou
URL de callback.
Quando recebermos a mensagem em nosso servidor, faremos a
classificação de intenções e o parsing de entidades e formularemos o que
será respondido para o usuário.
Token de verificação
Um token de verificação é uma string arbitrária enviada para nosso
endpoint quando a assinatura é verificada. Isso é necessário para nos
certificarmos de que o servidor sabe que a solicitação está sendo feita pelo
Facebook e se refere à assinatura que acabamos de configurar.
Suponhamos que alguém tomasse conhecimento de seu webhook e
postasse mensagens como se fosse o Facebook; verify_token entraria em
ação e você verificaria se a origem está ou não correta. Com base nesse
token, você também pode manipular solicitações POST de várias origens
porque haverá diversos tokens definidos para diferentes origens, mas com a
mesma URL de callback.
Tokens de acesso
As APIs do Facebook requerem tokens de acesso para gerenciar páginas.
Eles são exclusivos de cada página, administrador e aplicativo e têm data
de expiração.
Nota Mantenha a URL de callback e o token de verificação à mão
porque agora configuraremos o webhook.
Configurando Webhooks
Para configurar o webhook de nosso bot, voltaremos ao Console de
Desenvolvedor do Facebook:
1. Clique no botão Setup da seção Add a product dos webhooks quando clicar
no dashboard. Se ainda não tiver se cadastrado nos webhooks, verá
uma opção com o texto "subscribe to this object". Clique nela e verá um novo
pop-up para inserir as informações a seguir:
• Callback URL: URL fornecida na página de integração do Facebook
Messenger.
• Verify Token: é o token que você criou.
2. Acesse Messenger > Settings > Setup Webhooks. Você verá um pop-up como o
da Figura 3.18. Adicione a URL de callback e o token de verificação.
Figura 3.18 – Definindo webhooks no Facebook para o bot do Dialogflow.
3. Marque as opções messages e messaging_postbacks em Subscription Fields. Você
pode selecionar qualquer opção que seja necessária para seu caso de
uso.
4. Clique no botão Verify and Save. Consulte a Figura 3.18 como referência.
Você será levado de volta à página de configurações, e Webhooks deve
exibir o status "Complete". Certifique-se de selecionar uma página para a qual
possa cadastrar seu webhook para eventos de página.
Testando o bot do Messenger
Para disponibilizarmos nosso bot para teste, precisamos tornar nosso
aplicativo público:
1. Clique em App Review no menu esquerdo do Console de Desenvolvedor
do Facebook.
2. Clique no botão de ativação em Make <nome do aplicativo> public?. Se for
aberto o prompt Invalid Privacy Policy URL, vá até o link Basic Settings na caixa de
diálogo e, se ainda não tiver feito isso, insira qualquer URL como URL
de política de privacidade; clique em Save Changes. Volte à página App
Review e tente mudar o aplicativo para público novamente.
3. Você será solicitado a selecionar uma categoria para seu aplicativo.
4. Selecione Education na lista. Fique à vontade para selecionar o que
melhor atender seu bot.
5. Clique no botão Confirm como mostrado na Figura 3.19 e tornará seu
aplicativo do Facebook público.
Figura 3.19 – Tornando seu aplicativo do Facebook público.
Também precisamos criar um nome de usuário para nossa página. Será o
nome com o qual os usuários conversarão ao usar o bot. Para definir o
nome de usuário, clique no link Create Page @Username na seção About de sua
página, como mostrado na Figura 3.20. Isso será útil para o
compartilhamento da página ou do bot com as pessoas com o uso apenas
de um nome abreviado.
Figura 3.20 – Criando o nome de usuário da página de seu bot do Facebook.
Testaremos no bot do Facebook Messenger o mesmo fluxo que testamos
no site do Dialogflow. Você pode ver como meu bot do Facebook
Messenger respondeu examinando as Figuras 3.21.1 a 3.21.4.
Figura 3.21.1 – Tela I da demo do OnlineEatsBot no Facebook Messenger.
Figura 3.21.2 – Tela II da demo do OnlineEatsBot no Facebook Messenger.
E é assim que se constrói um bot.
O Capítulo 4 será ainda mais interessante. Tentaremos fazer o mesmo sem
depender da API ou do dashboard do Dialogflow.
Figura 3.21.3 – Tela III da demo do OnlineEatsBot no Facebook Messenger.
É sempre bom quando temos controle total sobre tudo, não é mesmo?
Nota: Podemos acessar as configurações de nossa conta e exportar ou importar agentes
diretamente. Se quiser, baixe o arquivo zip ([Link]). Use-o para fazer a
importação para o Dialogflow e examinar o chatbot que construímos neste capítulo.
Figura 3.21.4 – Tela IV da demo do OnlineEatsBot no Facebook Messenger.
Você deve estar se perguntando o que seria preciso se quisesse fazer o
pedido em tempo real, saber seu status usando APIs do
fornecedor/restaurante e responder para o usuário de acordo. Poderia ser
qualquer chamada de API para recuperar os dados em tempo real e
formular a resposta do bot. É hora de saber como fazê-lo antes de terminar
este capítulo e nos prepararmos para o próximo.
Conheceremos algo chamado "fulfillment" no Dialogflow.
Fulfillment
Para fornecer em tempo real as informações solicitadas pelo usuário,
precisamos desenvolver uma API ou usar as que já existem. Para fazer isso
usando o Dialogflow, temos de configurar o fulfillment, que requer a
implantação de um serviço e a chamada a uma API.
Não examinaremos os detalhes da construção de APIs e como implantá-
las, mas, se você já tentou usar alguma API do Google ou Facebook, deve
saber pelo menos como chamá-las.
Construí uma pequena API baseada em Flask e a implantei no Heroku.
Vou usá-la para executar o fulfillment, que apenas obterá o order_id na URL
e retornará um order_status aleatório. Se não estiver familiarizado com o
Heroku, não se preocupe, você pode executar o código fornecido em seu
sistema local e testá-lo. No próximo capítulo, implantaremos várias
aplicações usando o Heroku e veremos mais detalhes sobre ele.
O código mostra como order_identity, intentName etc. são analisados.
Ele pode ser encontrado aqui: flask_onlineeats_demo.zip.
URL da solicitação: [Link]
[Link]/onlineeatsbot/api/v1.0/order_status/
No Dialogflow, o fulfillment enviará a resposta JSON da intenção para essa
URL, e você terá de fazer o parsing para obter as entidades relevantes e
seus valores e executar ações específicas.
Você também pode tentar implantar o exemplo de código de aplicativo
Flask no Heroku e ter o próprio endpoint funcionando no bot para o
fulfillment.
O Dialogflow enviará a resposta JSON da intenção para a qual a chamada
ao webhook estiver ativada em nosso endpoint. Ela terá o código para a
análise da entidade order_id e a execução de ações a partir daí. Atualmente,
o código só retorna um status selecionado aleatoriamente em uma lista.
Para verificar se a API está funcionando, vá até o POSTMAN e teste-a
usando os exemplos de dados da Figura 3.22. Se estiver executando o
aplicativo Flask localmente, use a URL local.
Figura 3.22 – Testando no POSTMAN a API de fulfillment implantada no
Heroku.
Ativando o webhook
Acesse a página de fulfillment no Dialogflow e tente ativar o webhook
(Figura 3.23).
Figura 3.23 – Configurando o webhook para o fulfillment no Dialogflow.
Certifique-se de ativar a chamada ao webhook para a intenção user_order_id
(Fig. 3.24).
Figura 3.24 – Ativando a chamada ao webhook para uma intenção
específica.
O Dialogflow enviará um corpo JSON para a URL de seu webhook com
um conteúdo como o da Figura 3.25.
Figura 3.25 – Dados JSON enviados do Dialogflow para o endpoint de nosso
webhook.
Verificando a resposta
O Dialogflow esperará uma resposta do web service no formato mostrado
na Figura 3.26 sempre que enviar para ele a resposta JSON de uma
intenção (mostrada na Figura 3.25).
Se você acha que a resposta de sua API deve ter o mesmo formato da
Figura 3.26, calma – não é esse o caso. Sua intenção não lançará erros
porque todas as chaves do corpo JSON são opcionais.
Figura 3.26 – Resposta da URL do webhook esperada pelo Dialogflow.
Veja como ficou a resposta de minha API. Ela funciona perfeitamente:
{
"fulfillmentText": "Order ID: 9999. It's on the way",
"payload": {
"facebook": {
"text": "Order ID: 9999. It's on the way"
}
} }
Quando tento executar a API novamente, obtenho um texto de status de
pedido diferente, mas com o mesmo formato esperado pelo mecanismo do
Dialogflow.
{
"fulfillmentText": "Order ID: 9999. Rider has picked up your food, please
wait for another 10-15 minutes",
"payload": {
"facebook": {
"text": "Order ID: 9999. Rider has picked up your food, please wait
for another 10-15 minutes"
}
}
}
fulfillmentText é a chave que importa para o agente responder algo para o
usuário.
Agora teste o bot com a URL pública ou no próprio agente do Dialogflow
para ver as respostas fornecidas pela API em vez das respostas estáticas
padrão que adicionamos anteriormente.
É assim que podemos integrar uma API externa ou nossa própria API
usando o recurso fulfillment do Dialogflow em nosso chatbot para termos
ações dinâmicas e em tempo real.
Resumo
Neste capítulo, conhecemos o Dialogflow e aprendemos como usá-lo para
construir um chatbot. Aprendemos a definir intenções e suas respectivas
entidades. Construímos um chatbot simples que entende a intenção de
pedir comida e os itens de refeição que o usuário solicitou, assim como a
quantidade. Melhoramos o chatbot que agora permite que os usuários
perguntem sobre o status de seu pedido, obtém com eles o ID da
solicitação e formula uma resposta com diferentes status.
Também conhecemos o recurso fulfillment do Dialogflow, com o qual
obtivemos o status do pedido a partir de nossa própria API e fornecemos a
resposta para o usuário com base nessa informação. Aprendemos a criar
uma web demo de nosso chatbot e o integramos ao Messenger. Você já
deve ter uma boa ideia de como um chatbot funciona de ponta a ponta.
No próximo capítulo, usaremos a maneira mais difícil de construir
chatbots. Sim, é isso mesmo que você leu. Eliminaremos a dependência de
ferramentas como o Dialogflow e construiremos tudo nós mesmos
programaticamente. Prepare-se para essa nova etapa, porque será ainda
mais divertido quando você tiver construído tudo por conta própria a
partir do zero. Você treinará e domará os próprios chatbots.
CAPÍTULO 4
Construindo chatbots da maneira mais difícil
Não é tão complexo aprender a "construir chatbots da maneira mais
difícil". É com a maneira difícil que ganhamos controle total sobre os
chatbots que construímos. Se decidir que você mesmo vai construir algo,
estará tomando o caminho difícil. Ele é duro de percorrer, mas bonito e
límpido quando olhamos em retrospecto.
É uma estrada dura que leva às alturas da grandeza.
– Lucius Annaeus Seneca
Se você conhece bem Python e tem alguma habilidade para definir pacotes
etc., não terá problemas para estudar este capítulo. Se é desenvolvedor, vai
ser fácil entendê-lo. Se é gerente ou uma pessoa não técnica, mesmo assim
poderá executar as etapas individualmente conforme mencionadas nas
seções e concluir as tarefas necessárias. Recomendo que todos leiam o
capítulo até o fim para aprender tópicos básicos sobre a construção de
chatbots.
Este capítulo não só lhe ensinará a construir chatbots a partir do zero, mas
também mostrará como o machine learning (ML) básico funciona com o
NLP com a ajuda do Rasa NLU. Como mencionado no primeiro capítulo,
é sempre bom termos árvores de decisão quando estamos construindo
chatbots. Neste capítulo, quase não usaremos regras, mas o ML ainda não
está no estágio de ser 100% confiável. Logo, essa decisão deve ser tomada
dependendo de seu caso de uso e de se você deseja ou não aplicar alguma
lógica operacional junto com seus modelos de ML. Pode ocorrer de seu ML
estar funcionando tão bem que você não precise de nenhuma heurística.
No entanto, pelo que aprendi com a experiência, ao vender chatbots ou
comercializá-los, é preciso tomar cuidado. É melhor uma funcionalidade
não existir do que ela existir e não fazer sentido.
Usaremos uma biblioteca open source chamada Rasa NLU para aprender
como construir chatbots a partir do zero sem usar nenhum serviço de
nuvem como o Dialogflow, Watson, [Link] etc. Lembre-se de que o Rasa
NLU é uma biblioteca muito sofisticada e tem vários recursos.
Examinaremos apenas os conceitos e recursos que forem importantes para
construirmos nosso chatbot.
O que é Rasa NLU?
O Rasa NLU é uma biblioteca open source de NLP para a classificação de
intenções e a extração de entidades em chatbots. Ela ajuda a construir e
escrever um NLP personalizado para os bots.
Há duas partes do Rasa que abordaremos neste capítulo.
• Rasa NLU: Com o Rasa NLU aprenderemos a preparar os dados de
treinamento para o chatbot, criaremos arquivos de configuração,
selecionaremos um pipeline e treinaremos o modelo. Para concluir,
descobriremos a intenção de um texto usando nosso modelo. Também
aprenderemos como analisar entidades usando o Rasa NLU.
• Rasa Core: Na segunda parte, aprenderemos a treinar o modelo de
gerenciamento de diálogo do Rasa Core para preparar as respostas
dadas ao usuário. Esta seção será importante quando você tiver muitas
intenções em seu chatbot com suas perguntas ou respostas de
acompanhamento. Em vez de incluir várias condições em nossa árvore
de decisão e passar horas depurando-a no caso de uma grande aplicação
de nível empresarial, é melhor ensinar o modelo a criar respostas. Será
interessante ver como o modelo treinado se sai ao fazer isso. Não
podemos dizer qualquer coisa para o usuário na forma de texto; precisa
fazer sentido.
Por que devo usar o Rasa NLU?
O Rasa NLU não é apenas outra biblioteca com vários métodos para a
execução de ações. Ele pode construir quase qualquer tipo de chatbot
imaginável. O Rasa faz a mágica de treinar a máquina para que ela entenda
o significado de um texto em vez de precisarmos escrever regras para isso.
Os itens a seguir explicam por que devemos usar o Rasa NLU:
• O Rasa NLU é um projeto que conta com manutenção ativa e tem o
suporte de uma boa comunidade.
• Se não quisermos compartilhar os dados sigilosos do usuário com
terceiros, devemos usar ferramentas open source como o Rasa NLU
para construir chatbots a partir do zero. Dessa forma, todos os dados
permanecerão e serão processados em nossos próprios servidores.
• Depender de serviços de terceiros para criar dados de treinamento e
descobrir as intenções nos enunciados do usuário requer chamar APIs
que podem não ser confiáveis. O que acontecerá com sua aplicação de
chatbot se o servidor deles sofrer uma interrupção?
• Usar o Rasa NLU para construir chatbots lhe dará controle total sobre
os bots. Você pode treinar, ajustar e otimizar o chatbot da maneira e
com os dados que quiser. Com o Rasa NLU podemos fazer testes com o
algoritmo de ML que funcionar melhor para nosso conjunto de dados
em vez de depender de um único algoritmo.
Passando diretamente à prática com o Rasa NLU
Nesta seção passaremos diretamente para a parte prática instalando a stack
Rasa e trabalhando na construção de modelos de ML com a preparação de
dados de treinamento. Usaremos algumas bibliotecas open source mais
modernas para facilitar nossa vida.
Instalando o Rasa
Para instalar o Rasa, execute o comando pip a seguir que usamos em
capítulos anteriores para instalar o spaCy. Observe que usaremos o Rasa
versão 0.13.2.
pip install rasa-nlu==0.13.2
O Rasa NLU tem vários componentes para a classificação de intenções e o
reconhecimento de entidades. Os diferentes componentes do Rasa têm os
próprios conjuntos de dependências.
Quando treinarmos nosso modelo, o Rasa NLU verificará se as
dependências requeridas estão instaladas. Se quiser instalar todos os
requisitos necessários para usar a biblioteca Rasa em sua totalidade,
execute as etapas a seguir:
git clone [Link] #Clona o repositório
cd rasa_nlu #Entra no diretório rasa
pip install -r alt_requirements/requirements_full.txt #Instala todos os
requisitos
A primeira etapa pode demorar um pouco. Seja paciente e espere que
termine.
Definindo um pipeline no Rasa
O pipeline é apenas o conjunto de algoritmos que será utilizado para
treinar o modelo. O Rasa NLU tem dois pipelines muito usados chamados
spacy_sklearn e tensorflow_embedding (ver Informação Importante no ínicio do
livro).
Examinaremos alguns detalhes dos dois.
spacy_sklearn
• O pipeline spacy_sklearn faz uso de vetores de palavras pré-treinados do
algoritmo GloVe ou de um algoritmo desenvolvido pela equipe de IA
do Facebook chamado fastText.
• O spacy_sklearn funciona muito bem em situações como a seguinte:
suponhamos que você tivesse o enunciado "What is the weather in
Boston?" (Como está o tempo em Boston?). Se treinar o modelo com esse
enunciado e solicitar que identifique sua intenção, ele terá inteligência
suficiente para saber que as palavras "Boston" e "London" são
semelhantes e pertencem à mesma intenção.
• Esse pipeline é muito útil com pequenos conjuntos de dados.
tensorflow_embedding
• O pipeline tensorflow_embedding não faz uso de vetores de palavras pré-
treinados como o spacy_sklearn, mas se adapta ao conjunto de dados
fornecido.
• O que é bom no pipeline tensorflow_embedding é que os vetores de palavras
usados são correspondentes à área desejada.
• Para explicar com um exemplo como o tensorflow_embedding funciona, no
idioma inglês a palavra "play" (praticar) pode estar relacionada a "a
sport" (um esporte) ou "an activity of enjoyment or recreation" (uma
atividade prazerosa ou recreativa) e parecer distante da palavra "an act"
(um ato teatral). Na área teatral, os termos "play" (apresentar) e "an act"
(um ato) estão intimamente relacionados; "play" (que também pode ser
peça) significa "um tipo de literatura escrita por um dramaturgo", e é
necessário informar ao modelo que aprenda comportamentos
específicos da área e não se confunda seguindo modelos pré-treinados.
Treinando e construindo um chatbot a partir do zero
Se você leu o Capítulo 3 deste livro, deve estar familiarizado com o
"chatbot de pedido de comida" que construímos usando o Dialogflow. Já
deve conhecer as intenções, as entidades e as respostas retornadas para o
usuário final por um chatbot.
Da mesma forma, escolheremos um exemplo de chatbot e o construiremos
a partir do zero neste capítulo. Você não precisa usar o mesmo exemplo.
Fique à vontade para escolher o caso de uso que preferir, siga as etapas e
construa seu chatbot até terminar o capítulo.
Construiremos um bot de horóscopo que entende as consultas do usuário e
retorna para ele o horóscopo do dia. Comecemos então.
Construindo um bot de horóscopo
Nesse exemplo de construção de um chatbot inteiro por nossa própria
conta usando a biblioteca open source Rasa NLU, criaremos um bot de
horóscopo. Definiremos o escopo do chatbot e veremos o que ele faz e o
que poderia fazer.
• O bot de horóscopo tem de conseguir entender saudações e responder
com uma.
• Ele tem de conseguir entender se o usuário está solicitando uma
consulta ao horóscopo.
• Tem de poder perguntar o signo do usuário se ele não o fornecer.
• Se o usuário não souber seu signo, o bot deve perguntar sua data de
nascimento (DOB, date of birth) e encontrá-lo para ele.
• O bot deve cadastrar/descadastrar o usuário para receber o horóscopo
diário.
• O bot deve aprender com respostas existentes para formular uma nova
resposta.
• O bot tem de poder manipular erros de grafia cometidos pelo usuário.
É muito simples o que nosso bot deve fazer.
Intenções possíveis:
• Intenção de saudação: o usuário começa a interação com uma
saudação.
• Intenção de consulta ao horóscopo: o usuário solicita a consulta.
• Intenção de fornecimento do signo: o usuário informa seu signo.
• Intenção de fornecimento de DOB: o usuário informa sua DOB.
• Intenção de assinatura: o usuário pede para assinar.
Dependendo da maneira como você projetar seu bot e escrever o código,
pode ou não precisar de todas as intenções anteriores, ou talvez precise
definir intenções adicionais e abordar todos os casos de uso que queremos
que o bot abranja. Ao avançar no capítulo, tentaremos construir um bot
que execute a tarefa básica de fazer a precisão astrológica; posteriormente,
como parte do exercício, adicionaremos mais casos de uso.
Bem, isso é basicamente o que fizemos até agora, ou seja, reconhecer as
possíveis intenções de acordo com uma conversa simples entre um bot e
um usuário.
Conversa entre o bot de horóscopo e o usuário
Criaremos um roteiro da conversa que pode ocorrer entre nosso chatbot e
o usuário. Como mencionado no primeiro capítulo, escrever um roteiro de
conversa é como preparar o documento de requisitos de um software antes
de construí-lo. Depois ele pode mudar, mas você terá uma visão geral do
que ocorre na aplicação final.
Podemos ver a seguir como ficaria nossa conversa entre o usuário e o bot:
Usuário: Hello (Olá).
Bot de horóscopo: Hello! Hope you are doing well. (Olá! Espero que
esteja tudo bem).
Usuário: I want to know my horoscope. (Quero saber meu horóscopo).
Bot de horóscopo: Sure, may I know your horoscope sign? (Certo, pode
me dizer seu signo?).
Usuário: Capricorm (Capricórmio).
Bot de horóscopo: Sorry, did you mean Capricorn? (Desculpe, você quer
dizer capricórnio?).
Usuário: Yes. (Sim).
Bot de horóscopo: Alright, Here is your horoscope for today. Chances
are that you'll feel upbeat and positive today. Share this energy with
others who feel less than content. Your attitude can have a profound
effect on friends, partners, spouse, and children. Neighbors and
extended family can pick up on your spirit without you even realizing
it. If someone is hurt or angry, be encouraging. Everything will
eventually work out. (Certo, esse é seu horóscopo para hoje. Você deve se
sentir feliz e confiante. Compartilhe essa energia com quem estiver se
sentindo apenas bem-disposto. Sua atitude pode ter um efeito profundo
sobre amigos, sócios, seu cônjuge e filhos. Os vizinhos e parentes serão
contagiados pelo seu estado de espírito sem que você perceba. Se alguém
se machucar ou ficar com raiva, ajude. Tudo acabará dando certo).
Bort de horóscopo: Would you like to subscribe for the daily updates?
If yes, just say subscribe. (Gostaria de se cadastrar para atualizações
diárias? Se a resposta for sim, apenas responda com cadastre-me).
Usuário: Yes, please subscribe. (Sim, cadastre-me).
Bot de horóscopo: Great, you are subscribed now. Have a good day.
(Ótimo, você está cadastrado. Tenha um bom-dia).
Esse texto é apenas para você ter uma ideia de como será a conversa do
chatbot. Podemos ou não mudar o fluxo dependendo de nossas
necessidades.
Nosso modelo de chatbot pode treinar a si próprio para preparar uma
resposta válida em vez de precisarmos escrever várias instruções if…else.
Preparando dados para o chatbot
Com o Rasa NLU temos várias maneiras de definir as intenções e entidades
de nossos dados personalizados. Ele dá suporte a dados no formato
Markdown, em JSON como um arquivo individual, ou como um diretório
contendo vários arquivos.
Primeiro discutiremos o método mais difícil, mas que é altamente
escalável. É difícil criar arquivos JSON manualmente, mas
programaticamente é muito fácil e escalável.
Criando dados para o modelo no formato JSON
O formato de dados JSON que o Rasa NLU demanda tem um objeto de
nível superior chamado rasa_nlu_data, com as chaves common_examples,
entity_synonyms e regex_features.
A mais importante, e com a qual trabalharemos, é common_examples. O esboço
de como ficarão nossos dados JSON pode ser visto a seguir:
{
"rasa_nlu_data": {
"common_examples": [],
"regex_features" : [],
"entity_synonyms": []
}
}
A chave common_examples dos dados JSON é o local básico que será usado no
treinamento do modelo. Adicionaremos todos os nossos exemplos de
treinamento ao array common_examples.
regex_features é uma ferramenta que ajuda o classificador de intenções a
reconhecer entidades ou intenções e a melhorar a precisão da classificação.
Começaremos a criar nosso arquivo JSON. Vamos chamá-lo de [Link].
1. Crie uma pasta chamada horoscope_bot.
2. Altere o diretório de trabalho atual para horoscope_bot.
3. Inicie o Jupyter Notebook.
4. Crie uma nova pasta chamada data.
5. Clique na pasta data e vá até "Text File" no menu New do Jupyter
Notebook.
6. Clique no nome do arquivo criado, altere o nome para [Link] e crie
as intenções de seus chatbots.
Nas Etapas 5 e 6, fique à vontade para usar seus editores favoritos, como o
Sublime, Notepad++, PyCharm etc., para trabalhar com o arquivo JSON.
Veja a seguir como ficou o conteúdo de [Link] na pasta data:
{
"rasa_nlu_data": {
"common_examples": [
{
"text": "Hello", (Olá)
"intent": "greeting",
"entities": []
},
{
"text": "I want to know my Horoscope", (Quero conhecer meu horóscopo)
"intent": "get_horoscope",
"entities": []
},
{
"text": "Can you please tell me my horoscope?", (Pode por favor me dizer
meu horóscopo)
"intent": "get_horoscope",
"entities": []
},
{
"text": "Please subscribe me", (Cadastre-me por favor)
"intent": "subscription"
}
],
"regex_features": [],
"entity_synonyms": []
}
}
Como você pode ver, parece difícil preparar esses dados manualmente.
Você deve se lembrar do método fácil e descomplicado que usamos no
Dialogflow. Examinaremos uma ferramenta moderna e interessante para a
criação de dados de treinamento no formato que o RASA espera. Ela foi
criada por Polgár András e também ajudará na inspeção e na modificação
dos dados existentes que preparamos anteriormente. Essa ferramenta
economizará muito tempo se estivermos trabalhando em um projeto
pequeno em que tivermos de criar os dados manualmente. É sempre uma
boa ideia visualizar os dados de qualquer aplicação que você esteja
construindo que seja totalmente baseada em dados.
Salve o arquivo [Link] que criamos até estendermos o conjunto de dados
usando um método melhor.
Visualizando e modificando o formato de dados JSON do Rasa
Nesta seção, faremos uso de uma ferramenta chamada Rasa NLU trainer
para visualizar nossos dados (isto é, os dados que criamos até agora). Essa
ferramenta também nos ajudará na anotação dos dados. Você deve se
lembrar de que, quando descrevemos a interface do Dialogflow no
Capítulo 3, foi muito fácil definir entidades, seus nomes e os tipos.
Faremos o mesmo usando uma ferramenta open source.
O Rasa NLU trainer é uma ferramenta muito fácil e útil para a edição de
dados de treinamento a partir do próprio navegador. É complicado
manipular dados JSON e também pode levar a erros. Com essa ferramenta
útil podemos adicionar facilmente mais exemplos aos nossos dados de
treinamento ou editar os existentes. Ela economiza muito tempo se
comparada com a anotação manual dos dados. O rasa-nlu-trainer é uma
ferramenta baseada em JavaScript, logo, teremos de instalar o [Link] para
executá-la em nosso sistema. Isso não demorará mais do que 5 minutos.
Para fazê-lo, siga estas etapas:
1. Acesse [Link] e baixe o [Link].
2. Instale o pacote em seu sistema como instruído no site. Após instalar,
acesse uma nova interface de linha de comando/terminal do sistema e
digite "npm" para ver se funciona.
Instalei a versão LTS 8.11.4. Depois da instalação, execute o comando a
seguir para instalar o rasa-nlu-trainer:
sudo npm i -g rasa-nlu-trainer
Após a execução bem-sucedida do comando, você verá logs semelhantes
aos seguintes:
[fsevents] Success: "/usr/local/lib/node_modules/rasa-nlu-
trainer/node_modules/fsevents/lib/binding/Release/node-v57-darwin-x64/[Link]"
already installed
Pass --update-binary to reinstall or --build-from-source to recompile
npm WARN slick-carousel@1.8.1 requires a peer of jquery@>=1.8.0 but none is
installed. You must install peer dependencies yourself.
+ rasa-nlu-trainer@0.2.7
added 492 packages in 10.14s
Mesmo se sua mensagem não tiver essa aparência, se ela não lançar
nenhum erro não se preocupe. Já saberemos se nosso rasa-nlu-trainer foi
instalado com sucesso e está funcionando bem.
Acessaremos a pasta data que criamos anteriormente em nosso terminal e
executaremos o comando a seguir:
rasa-nlu-trainer
A digitação desse comando acionará um servidor local na porta 55703 e o
abrirá no navegador padrão. Sua aparência será semelhante à da Figura 4.1.
Figura 4.1 – rasa-nlu-trainer em localhost.
Como você pode ver, todos os dados existentes em [Link] foram exibidos
por essa excelente ferramenta para excluirmos ou editarmos; também
podemos adicionar novos exemplos aqui e ela continuará estendendo o
arquivo [Link].
Sugiro adicionar mais dados às suas intenções para treinar melhor o
modelo. Você pode obter esse arquivo [Link] no arquivo zip do código-
fonte ou no repositório fornecido pela editora (o código-fonte está
disponível em [Link] se
estiver tentando construir o mesmo chatbot descrito neste capítulo.
Da mesma forma que selecionamos as entidades dentro dos enunciados
para defini-las no Capítulo 3 usando o Dialogflow, podemos fazer o
mesmo usando essa ferramenta e fornecer nomes para nossas entidades
para o parsing posterior. Clique no botão de ativação do exemplo,
selecione o texto e adicione uma entidade dando a ela um nome.
Adicionei de cinco a seis exemplos de enunciados em cada uma das
intenções que defini. Quanto maior o número de exemplos adicionados,
melhor será o treinamento do modelo e a precisão fornecida.
Se você examinar o arquivo [Link] agora, ele terá mais exemplos
adicionados automaticamente. Logo, siga em frente e verifique seu arquivo
[Link] para saber se ele está com todos os exemplos que você adicionou
na UI do rasa-nlu-trainer.
Você também notará no arquivo [Link] que as entidades que definiu
usando a UI do rasa-nlu-trainer foram capturadas na lista common_examples
como tendo chaves de início e fim que informarão ao modelo em que
ponto o valor específico da entidade começa e termina no exemplo.
O mesmo objeto de dicionário também exibe o valor da entidade e o nome
que definimos. Em nosso exemplo, ficou assim:
{
"text": "19-01",
"intent": "dob_intent",
"entities": [
{
"start": 0,
"end": 2,
"value": "19",
"entity": "DD"
},
{
"start": 3,
"end": 5,
"value": "01",
"entity": "MM"
}
]
}
Treinando o modelo do chatbot
Nesta seção, treinaremos um modelo com os dados que preparamos. Já
que estamos usando o Jupyter Notebook para o gerenciamento e a criação
de arquivos, criaremos um novo arquivo .ipynb e começaremos a escrever
nosso código Python para treinar o modelo selecionando um dos pipelines
que discutimos anteriormente neste capítulo.
Criando um arquivo de configuração
Criaremos um arquivo JSON novamente da mesma forma que criamos o
anterior, usando o Jupyter, e o chamaremos de [Link]. Vamos mantê-lo
fora de nossa pasta data (isto é, em horoscope_bot que é o diretório do
projeto).
Adicione a ele a configuração a seguir:
{
"pipeline":"tensorflow_embedding",
"path":"./models/nlu",
"data":"./data/[Link]"
}
Como você pode ver, há alguns parâmetros de configuração importantes
em nosso arquivo [Link]. Tentaremos entendê-los.
• pipeline:Especifica que featurizers ou extratores de recursos serão
usados para vasculhar e extrair as informações necessárias. Em nosso
caso, estamos usando o tensorflow_embedding.
• path: É o diretório em que manteremos nosso modelo após o
treinamento. Manteremos o modelo na pasta /models/nlu.
• data: É o caminho que precisamos especificar; é onde nossos dados de
treinamento residem.
Já que terminamos de trabalhar com nosso arquivo [Link], lidaremos
com o código Python que treinará o modelo de ML.
CONFIGURAÇÃO YAML
Você também pode usar um arquivo .yml para a configuração como mostrado a seguir. Se
quiser, obtenha os exemplos de arquivos [Link] no repositório do github.
• Exemplo 1:
language: "en"
pipeline: "tensorflow_embedding"
• Exemplo 2:
language: "en"
pipeline:
- name: "nlp_spacy"
- name: "tokenizer_spacy"
- name: "intent_entity_featurizer_regex"
- name: "intent_featurizer_spacy"
- name: "ner_crf"
- name: "ner_synonyms"
- name: "intent_classifier_sklearn"
Todas as mensagens recebidas são processadas conforme a sequência de
componentes definida. Os componentes definidos são executados de
maneira sequencial, um a um, e é daí que vem o nome pipeline de
processamento. Diferentes componentes são usados para diferentes
propósitos, como a extração de entidades, a classificação de intenções, o
pré-processamento etc.
O benefício desse formato é que podemos especificar os pipelines
predefinidos pelo Rasa de maneira clara.
Escrevendo o código Python que treinará o modelo e fará previsões
Abriremos um novo arquivo .ipynb e começaremos a escrever nosso código.
Vamos chamá-lo de [Link]. Verifique se rasa-nlu==0.13.2 foi instalado
com sucesso para a versão de Python que está usando.
Veja como ficou nosso código para usar [Link] e [Link] em Python e
treinar um modelo com o pipeline tensorflow_embedding.
from rasa_nlu.training_data import load_data
from rasa_nlu.model import Trainer
from rasa_nlu import config
from rasa_nlu.model import Interpreter
def train_horoscopebot(data_json, config_file, model_dir):
training_data = load_data(data_json)
trainer = Trainer([Link](config_file))
[Link](training_data)
model_directory = [Link](model_dir, fixed_model_name =
'horoscopebot')
def predict_intent(text):
interpreter = [Link]('./models/nlu/default/horoscopebot')
print([Link](text))
Na primeira seção do código, importamos todas as bibliotecas necessárias
do pacote rasa_nlu. Em seguida, definimos dois métodos chamados
train_horoscopebot e predict_intent; o primeiro método treina o modelo de
acordo com os dados, com config_file e com model_directory (local para
armazenamento dos modelos) e o método predict_intent usa o modelo
Interpreter do rasa_nlu para carregar os arquivos de modelo pré-treinados
e permitir que novos exemplos de texto do usuário sejam previstos.
Treinando o modelo
Executamos o fragmento de código a seguir para chamar nosso método
train_horoscopebot com os respectivos parâmetros:
train_horoscopebot('./data/[Link]', '[Link]', './models/nlu')
Após a execução desse código em [Link], obteremos uma saída
como:
Epochs: 100%|██████████| 300/300 [00:01<00:00, 175.69it/s,
loss=0.075, acc=1.000]
O código para treinamento do modelo do chatbot criará a pasta models, que
você poderá ver usando o Jupyter, seu explorador de arquivos ou um
aplicativo de busca. Ele criará vários arquivos index, meta e pickle no
diretório de destino do modelo que fornecemos.
Fazendo previsões a partir do modelo
Chamaremos o método predict_intent passando um texto para ver como
nosso modelo treinado se sai.
predict_intent("I am looking for my horoscope for today. I am wondering if you
can tell me that.") (Quero saber meu horóscopo para hoje. Poderia me dizer?)
O próprio método exibe a saída. Para o texto anterior, minha saída foi:
INFO:tensorflow:Restoring parameters from
./models/nlu/default/horoscopebot/intent_classifier_tensorflow_embedding.ckpt
{
"intent": {
"name": "get_horoscope",
"confidence": 0.9636583924293518
},
"entities": [],
"intent_ranking": [
{
"name": "get_horoscope",
"confidence": 0.9636583924293518
},
{
"name": "dob_intent",
"confidence": 0.03462183475494385
},
{
"name": "greeting",
"confidence": 0
},
{
"name": "subscription",
"confidence": 0
}
],
"text": "I am looking for my horoscope for today. I am wondering if you can
tell me that." (Quero saber meu horóscopo para hoje. Poderia me dizer?)
}
Excelente! Parece mágica. Nosso modelo previu esse texto com 96% de
segurança. Podemos ver no arquivo ipynb fornecido que o modelo também
se sai bem na previsão de outras intenções. Esse é o poder do trabalho
conjunto do TensorFlow e do ML. A biblioteca rasa_nlu facilita tanto que
é difícil acreditar. É hora de fazermos uma recapitulação; se você leu o
Capítulo 3 deste livro, deve se lembrar de que, sempre que adicionávamos
um novo exemplo, o Dialogflow treinava novamente o modelo. Na
verdade, ele estava fazendo em segundo plano o mesmo que acabamos de
fazer. Não poderíamos ter alterado o modelo ou ajustado algum parâmetro
naquela situação, mas podemos fazer tudo isso agora com controle total.
Já que construímos e treinamos um modelo com sucesso usando o
TensorFlow e também o testamos, passaremos para o próximo tópico do
gerenciamento de diálogo. Sugiro que você teste todos os cenários que seu
bot pode encontrar para saber os pontos em que o modelo não está se
saindo bem e, de acordo com o detectado, adicione mais dados ou ajuste
os parâmetros se necessário.
Lembre-se também de que você só precisa retreinar o modelo quando
houver uma alteração nos dados de treinamento. Se não houver alteração,
podemos carregar o modelo de treinamento existente para continuar
prevendo novos exemplos.
Gerenciamento de diálogo com o uso do Rasa Core
Nesta seção, faremos mais exercícios treinando outro modelo com o uso
do gerenciamento de diálogo do Rasa Core. Lembre-se, já temos um
modelo que prevê a intenção do texto e podemos escrever o código Python
para formular respostas e retorná-las para o cliente. No entanto, e se
quisermos adicionar mais intenções ao nosso bot? Isso seria possível no
caso de uma aplicação maior com muitos recursos? A resposta é não. Nesse
caso, o gerenciamento de diálogo do Rasa Core pode ajudar.
Se você já tentou usar um bot em alguma plataforma, deve tê-lo visto falhar
em certas condições. Sim, todos nós já passamos por isso e ainda passamos
já que os bots atuais não conseguem gerenciar os contextos da conversa ou
seguir seu fluxo. Com a ajuda do framework de diálogo baseado em ML do
Rasa Core, podemos resolver facilmente esse problema. O Rasa Core tem
eficiência comprovada para aplicações de nível empresarial e é usado por
milhares de desenvolvedores porque foi projetado para o ambiente de
produção, é fácil de usar e estender e, o mais importante, é open source.
Entendendo melhor o Rasa Core e o sistema de diálogo
Antes de passarmos à parte de codificação do Rasa Core para nosso
modelo de gerenciamento de diálogo, é importante entender por que e de
onde esse recurso surgiu.
Tentaremos entender como agimos até agora para construir os chatbots e
como isso deve mudar de forma permanente.
Vejamos um exemplo:
Se quiséssemos construir um chatbot simples para ajudar os usuários a
comprar passagens aéreas, de ônibus, entradas para o cinema e passagens
de trem, a maneira mais fácil seria criar uma máquina de estados ou
árvores de decisão, escrever várias instruções if…else e o problema estaria
resolvido. Isso funcionaria, mas não seria escalável. Se inicialmente o
cliente tiver uma boa experiência ao usar algo, ele vai querer usá-lo
novamente. Com um pouco de heurística, podemos ensinar um chatbot a
ser inteligente, mas não por muito tempo. Quando o fluxo de controle do
código passa do bloco try para o bloco except, começamos a nos preocupar.
A Figura 4.2 é uma representação simples de como ficaria uma máquina de
estados para a construção desse chatbot.
Figura 4.2 – Representação de um diagrama de estados para o chatbot de
compra de tíquetes.
Se examinarmos nosso diagrama de estados, ele pode funcionar para uma
conversa comum em que o usuário esteja procurando tíquetes para o
cinema, ônibus ou trem ou queira comprar uma passagem de ônibus após
comprar ingressos para o cinema. E se o usuário quiser solicitar ao mesmo
tempo tanto a passagem de ônibus quanto o ingresso para o cinema? Você
poderia dizer que podemos adicionar mais algumas instruções if…else em
nosso código já aninhado para manipular isso. Se você for um bom
desenvolvedor, não demorará muito para escrever um novo trajeto em uma
máquina de estados ou estender sua árvore de decisão. No entanto,
considere a situação em que essas condições começarem a crescer
exponencialmente, você tiver que adicionar casos para manipulá-las e elas
também começarem a afetar umas às outras.
Nosso cérebro funciona de tal forma que aprendemos e reaprendemos. Se
uma criança não sabe que o fogo pode machucá-la, ela toca nele, mas
quando se machuca, não o faz novamente. Ela aprende que é perigoso. O
mesmo ocorre no caso de recompensas – quando você faz algo e obtém
alguma coisa em troca, associa o fato de que o que fez traz recompensas ou
coisas ainda melhores e quer fazê-lo novamente. Em ML isso se chama
aprendizado por reforço, no qual uma máquina aprende como comportar-
se em uma situação específica executando ações e entendendo os
resultados. Às vezes o aprendizado por reforço não é a melhor abordagem,
como em situações em que os dados não são suficientes para o
aprendizado, sua qualidade não é boa para o conhecimento dos cenários de
recompensa etc.
A Figura 4.3 é um diagrama que o ajudará a ver como o Rasa Core se
encaixa bem dentro da Stack Rasa e entender seu papel junto ao Rasa
NLU, que estudamos até agora.
Figura 4.3 – Diagrama representando a função do Rasa NLU e do Rasa
Core.
Com o Rasa Core, podemos especificar todas as coisas que nosso bot deve
dizer ou fazer, que são chamadas de ações. Uma ação poderia ser saudar o
usuário ou consultar um banco de dados, ou também recuperar
informações usando algum web service ou API.
O Rasa Core fornece o recurso de treinarmos nosso modelo probabilístico
para prever que ação tem de ser executada de acordo com o histórico de
conversa do usuário ou usuários. Imagine fazer isso sem um modelo de ML
e escrever centenas de casos de uso para saber que resposta ou ação deve
ser enviada ou executada. O Rasa Core resolve esse problema.
Examinaremos lado a lado a conversa entre o usuário e o bot que
construímos no Capítulo 3 ao criar um OnlineEatsBot.
Usuário OnlineEatsBot
Hello OnlineEats (Olá OnlineEats) Hello! How may I help you? (Olá! Como posso
ajudá-lo?)
I am looking to order food (Quero Sure, What would you like to order today? (Certo, o
fazer um pedido de comida) que gostaria de pedir hoje?)
One chicken burger (Um hambúrguer Done. Your final amount is $3.99 (Tudo bem. O
de frango) preço final é $3.99 dólares)
Thank you (Obrigado) Thanks a lot (Muito obrigado)
Essa conversa é muito simples e pode ser feita sem um modelo de ML,
ainda que tenhamos usado um modelo treinado para reconhecer a intenção
e suas entidades.
Uma pergunta importante que pode lhe ocorrer é "E se eu quiser que meu
bot possa mudar o pedido? Se quiser que ele possa remover ou adicionar
uma quantidade maior de itens de refeição?". Como discutimos, adicione
mais casos de uso, mais complexidade, mais intenções e seus enunciados,
mais instruções if…else ao código para manipular casos alternativos, mas, se
estiver construindo um chatbot para uma empresa, terá de escalá-lo para
gerar mais receita com ele. Todos os sistemas de software fazem isso, e os
que não fazem não sobrevivem. Ou seja, não podemos continuar alterando
e implantando o código.
Em vez de manipular todos os casos à medida que ocorrerem e fazer isso
repetidamente, podemos adotar o uso de ML para resolver esse problema,
com a ajuda da Stack Rasa, que nos dirá o que o bot deve fazer a seguir de
acordo com o contexto do usuário e o estado da conversa. Já que o modelo
aprende sozinho conforme o contexto dos dados anteriores da conversa,
fica mais fácil para o bot mantê-la em um tom mais natural e amigável para
o usuário em vez de selecionar aleatoriamente de quatro a cinco frases
fixas.
O Rasa faz recomendações aos usuários com pouco ou nenhum
aprendizado interativo de uso de dados. Conheceremos melhor o
aprendizado interativo posteriormente neste capítulo.
Antes de começarmos a usar o Stack Rasa para criar a parte básica de nosso
bot, temos de entender alguns conceitos.
Entendendo os conceitos do Rasa
É muito importante entendermos alguns conceitos específicos relacionados
ao Rasa antes de tentar usá-los no código. Nesta seção, aprenderemos
conceitos relevantes e úteis do Rasa NLU. Certifique-se de entendê-los
plenamente, já que vamos usá-los em nosso primeiro bot construído por
conta própria empregando o formato de arquivo domain do Rasa. Se você
não entender o que esses conceitos significam, será difícil passar para a
próxima etapa.
Ação
Como o nome sugere, é uma ação específica que pode ser executada. A
documentação do Rasa explica que é a "próxima ação a ser executada em
resposta a um estado do diálogo".
Por exemplo, se um usuário solicitasse o horóscopo de hoje, nosso bot
poderia executar a ação "GetTodaysHoroscope". Vejamos como uma ação
"GetTodaysHoroscope" ficaria em forma de código.
from rasa_core.actions import Action
from rasa_core.events import SlotSet
class GetTodaysHoroscope(Action):
def name(self):
return "get_todays_horoscope"
def run(self, dispatcher, tracker, domain):
# type: (Dispatcher, DialogueStateTracker, Domain) -> List[Event]
user_horoscope_sign = tracker.get_slot('horoscope_sign')
"""Escreva sua lógica para obter os detalhes de hoje
do signo fornecido baseado em algumas chamadas de API
ou recuperação no banco de dados"""
return [SlotSet("horoscope_sign", user_horoscope_sign)]
O método name retorna o nome da ação que referenciaremos no arquivo
domain como nome do método personalizado.
O método run faz o trabalho principal de executar a ação – isto é, a lógica
operacional básica reside aqui. Como você pode ver, ele recebe três
parâmetros: dispatch, tracker e domain.
Vejamos esses parâmetros individualmente:
• dispatcher: dispatcher é usado para retornarmos mensagens para nossos
usuários. Também podemos usar dipatcher.utter_message() para fazer isso.
• tracker: rastreador de estado do usuário atual. Podemos acessar valores
de slots usando tracker.get_slot(slot_name), e para acessar a mensagem
mais recente do usuário podemos usar tracker.latest_message.text.
• domain: domíno do bot. Discutiremos o domínio com mais detalhes
posteriormente neste capítulo.
Nota O método run retorna uma lista de instâncias de eventos.
Slots
São os slots que fazem o bot funcionar como um humano. Eles são como
um espaço de armazenamento em que as informações fornecidas pelo
usuário podem ser guardadas ou uma informação buscada previamente em
um banco de dados ou API também pode ser usada.
Há diferentes tipos de slots para casos de uso distintos:
Por exemplo, em nosso caso de uso no qual queremos construir um
HoroscopeBot, poderíamos usar o tipo de slot text para o signo
(horoscope_sign) fornecido pelo usuário.
Dependendo do tipo de slot que você quiser, o Rasa já fornece alguns
predefinidos.
Além de text, ele tem os tipos de slot a seguir:
• Boolean ⇒ Usado para True/False (Verdadeiro/Falso).
• Categorical ⇒ Usado para situações em que é preciso selecionar um
entre alguns valores.
• Float ⇒ Usado para valores contínuos.
• List ⇒ Usado para listas de valores.
• Featurized ⇒ Usado para o armazenamento de um valor interno que
não afeta a conversa.
Templates
Template é uma palavra que você já deve ter ouvido pelo menos uma vez
na vida, ao procurar um template para enviar um email, preparar um
documento, construir um site de portfólio ou acompanhar um processo.
No Rasa, os templates são usados para enunciados. Um template de
enunciado contém um conjunto de textos predefinidos para serem
enviados para o usuário quando alguma ação é acionada. Dando para a
ação o mesmo nome do enunciado ou por intermédio de uma ação com
código personalizado, podemos enviar nossa mensagem formatada em
templates para o usuário.
Uma representação simples dos templates dentro de um arquivo domain
poderia ser como a mostrada a seguir:
templates:
utter_greet:
- "hello {name}!" # name pode ser preenchido por um slot ou código
personalizado
utter_goodbye:
- "goodbye"
- "take care bye" # a existência de vários templates permite
# que o bot selecione um aleatoriamente
utter_default:
- "Sorry, I didn't get that."
Agora que examinamos os três conceitos de ações, slots e templates e já
sabemos o que são intenções e entidades pelo aprendido no Capítulo 3,
estamos prontos para começar a usar o Rasa e escrever o código de nosso
primeiro chatbot.
Criando o arquivo domain para o chatbot
A primeira tarefa que devemos executar ao construir um chatbot usando a
stack Rasa é criar um arquivo domain.
De acordo com a documentação do Rasa, "O domínio define o universo
em que o bot operará. Ele especifica as intenções, entidades, slots e ações
que o bot deve conhecer. Opcionalmente, também pode incluir templates
para o que o bot dirá".
Ficou claro por que tivemos de nos preparar para essa situação
previamente entendendo os conceitos básicos do Rasa.
Criaremos um arquivo DefaultDomain com definição de YAML. O Rasa
usa arquivos .yml para definir o formato do domínio.
Originalmente YAML significava Yet Another Markup Language,
demonstrando seu uso como linguagem de marcação, mas depois isso foi
mudado para ser entendido como YAML Ain't Markup Language, um
acrônimo recursivo para definir seu fim como orientada a dados, e não
como linguagem de marcação de documentos.
Voltaremos ao diretório rasa-nlu do Jupyter Notebook e começaremos a
criar os arquivos. Observe que podemos escrever todo o código em
arquivos separados usando uma linha de comando e utilizar um editor para
alterá-lo. Acho o Jupyter Notebook mais interativo e de fácil acesso para a
navegação pelos arquivos. Você pode usar o que achar mais apropriado, no
entanto é bom conhecer a maioria dos recursos que o Jupyter Notebook
fornece.
Vá até o diretório principal horoscope_bot e crie um arquivo; vamos chamá-lo
de horoscope_domain.yml.
A seguir temos o conteúdo do arquivo horoscope_domain.yml de nosso bot:
slots:
horoscope_sign:
type: text
DD:
type: text
MM:
type: text
subscribe:
type: bool
intents:
- greeting
- get_horoscope
- subscription
- dob_intent
entities:
- horoscope_sign
- DD
- MM
- subscribe
- dob_intent
templates:
utter_greet:
- 'Hello! How are you doing today?' (Olá! Como você está hoje?)
utter_ask_horoscope_sign:
- 'What is your horoscope sign?' (Qual é o seu signo?)
utter_ask_dob:
- 'What is your DOB in DD-MM format?' (Qual é sua data de nascimento no
formato DD-MM?)
utter_subscribe:
- 'Do you want to subscribe for daily updates?' (Deseja se cadastrar
para atualizações diárias?)
actions:
- utter_greet
- utter_ask_horoscope_sign
- utter_ask_dob
- utter_subscribe
- get_todays_horoscope
- subscribe_user
Como você pode ver, o arquivo domain é composto de cinco partes
importantes, intents, entities, slots, templates e actions, que já discutimos.
Observe que para cada template é definida uma utterAction, como
utter_greet, utter_ask_horoscope_sign e utter_ask_dob; precisamos ter um
template definido na seção de templates com o mesmo nome.
É possível ver em nosso exemplo que foram definidas principalmente cinco
ações; as três primeiras são apenas para exibir o texto de um template para
o usuário, mas as duas últimas demandam que recuperemos os dados no
banco de dados ou façamos uma chamada de API para obter o horóscopo
do dia e retorná-lo.
No caso da ação subscribe_user, temos de executar uma operação para
adicionar o usuário atual à lista de assinaturas no banco de dados. Essas
ações definidas pelo usuário chamam-se ações personalizadas. Para termos
ações personalizadas, precisamos escrever o que o bot deve fazer quando
elas forem acionadas.
Na próxima seção aprenderemos a criar ações personalizadas.
Criando as ações personalizadas do chatbot
Como sabemos, sempre que uma UtterAction for acionada, nosso bot
responderá com o texto definido no template dessa ação. No entanto, o
que ocorrerá quando uma ação personalizada for acionada? Nesta seção,
escreveremos o código Python para a criação de ações personalizadas, que
usaremos para fazer chamadas de API ou qualquer outra coisa que possa
ser feita com Python.
Criaremos um novo arquivo chamado [Link] no diretório do projeto
(isto é, em nosso caso dentro da pasta horoscope_bot).
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
import requests
from rasa_core_sdk import Action
from rasa_core_sdk.events import SlotSet
class GetTodaysHoroscope(Action):
def name(self):
return "get_todays_horoscope"
def run(self, dispatcher, tracker, domain):
# type: (Dispatcher, DialogueStateTracker, Domain) -> List[Event]
user_horoscope_sign = tracker.get_slot('horoscope_sign')
base_url = [Link]
url = base_url.format(**{'day': "today", 'sign': user_horoscope_sign})
#[Link]
res = [Link](url)
todays_horoscope = [Link]()['horoscope']
response = "Your today's horoscope:\n{}".format(todays_horoscope)
dispatcher.utter_message(response)
return [SlotSet("horoscope_sign", user_horoscope_sign)]
Podemos ver que há dois métodos em nossa ação chamada
GetTodaysHoroscope. O método name apenas retorna o nome da ação. O outro
método é run e, como discutido anteriormente, é ele que executa a tarefa
processando a lógica operacional que escrevemos.
Em nosso método, estamos fazendo uso de uma API open source com
código hospedado no github ([Link]
API).
A url da API é esta:
[Link]
que retorna os dados em formato JSON:
{
"date": "2018-08-29",
"horoscope": "You will be overpowered with nostalgia and may long to get in
touch with old pals. And as Ganesha says, chances are that you may take a
liking to your ex-lover, while simultaneously strengthening your social
standing. All in all, the day will be a productive one.",
"sunsign": "capricorn"
}
Tradução da mensagem:
(Você sentirá saudades e pode querer entrar em contato com velhos amigos. E como
diz Ganesha, há chances de que você sinta falta de sua ex-namorada e reforce ao
mesmo tempo seu convívio social. O dia acabará sendo produtivo. )
Como você pode ver no método run, convertemos a resposta da API para o
objeto JSON em Python e acessamos a chave 'horoscope' no código JSON
para obter o horóscopo. Após obter o horóscopo no código JSON,
formulamos uma resposta e a retornamos para o usuário usando o objeto
dispatcher e seu método utter_message.
Para concluir, definimos o slot usando o método SlotSet. SlotSet salva as
variáveis obtidas nas respostas do usuário para que possamos usá-las a
qualquer momento no código durante o fluxo da conversa.
Nota Usando a API anterior, podemos obter o horóscopo de hoje
fornecendo o signo. Fique à vontade para utilizar sua própria API ou
banco de dados. Basta substituir a chamada de API por alguma outra
fonte que queira usar.
Assim como adicionamos a ação GetTodaysHoroscope ao arquivo [Link],
também adicionaremos a ação SubscribeUser. Não usaremos nenhum banco
de dados para armazenar as preferências de assinatura do usuário, mas,
quando você estiver construindo um chatbot para usuários reais, pode
precisar de user_ids para vincular às assinaturas no banco de dados.
Veja a seguir como ficou a ação SubscribeUser:
class SubscribeUser(Action):
def name(self):
return "subscribe_user"
def run(self, dispatcher, tracker, domain):
# type: (Dispatcher, DialogueStateTracker, Domain) -> List[Event]
subscribe = tracker.get_slot('subscribe')
if subscribe == "True":
response = "You're successfully subscribed"
if subscribe == "False":
response = "You're successfully unsubscribed"
dispatcher.utter_message(response)
return [SlotSet("subscribe", subscribe)]
Da mesma forma, podemos criar quantas ações personalizadas forem
necessárias.
A próxima etapa são os dados. O modelo de gerenciamento de diálogo do
Rasa é treinado com conversas reais entre o usuário e o chatbot. O
importante aqui é que essas conversas sejam convertidas para o formato
story.
Uma story é apenas uma conversa real entre um usuário e um chatbot na
qual as entradas do usuário são convertidas em intenções e entidades
enquanto as respostas retornadas pelo chatbot são tratadas como ações
que ele deve acionar quando necessário.
Um exemplo de como uma conversa real entre um usuário e um chatbot
ficaria no formato story é fornecido na tabela a seguir.
Cenário I
Usuário HoroscopeBot
Hello there! (Olá!) utter_greet
I want to know my horoscope for today (Quero saber o utter_ask_horoscope_sign
horóscopo de hoje)
My sign is Capricorn (Meu signo é capricórnio) [Link]
Can you subscribe me for updates? (Pode me cadastrar [Link]
para atualizações?)
Cenário II
Usuário HoroscopeBot
Hello there! (Olá!) utter_greet
I want to know my horoscope for today (Quero saber o utter_ask_horoscope_sign
horóscopo de hoje)
I don't know my sign (Não sei meu signo) utter_ask_dob
12-12 [Link]
Ainda não abordamos o cenário do código em que o usuário não sabe seu
signo, mas sabe sua DOB. Nesse caso, nosso código precisa de uma
modificação para obter as entidades DIA e MÊS quando o valor de
horoscope_sign não for encontrado.
Podemos usar os valores das entidades DD-MM para verificar o signo e, em
seguida, chamar o método GetTodaysHoroscope explicitamente ou treinar o
modelo dessa forma.
Preparação de dados para treinamento do bot
É sempre importante termos dados de boa qualidade antes de usarmos
qualquer tipo de ML. Para treinar nosso chatbot também precisamos de
dados; a conversa entre um usuário e um chatbot são os dados de que
precisamos para treinar os modelos. Às vezes é difícil encontrar um
conjunto de dados gratuitamente na web que atenda às necessidades.
Devemos gastar o tempo que for necessário para coletar dados. Podemos
pedir a nossos amigos e família que forneçam exemplos de texto da
conversa que usariam para interagir com o tipo de bot que estamos
construindo. Algumas pessoas criam aplicativos fictícios para fazer isso e
obtêm dados por crowdsourcing. Com dados melhores, melhores também
serão o modelo e as respostas do chatbot.
No que se refere a preparar dados, o Rasa se supera e vem com um recurso
de ponta chamado aprendizado interativo. Ele ajuda a gerar dados de story
facilmente e também treina o modelo de gerenciamento de diálogo à
medida que adicionamos os dados. Poderíamos chamar de treinamento de
ML em tempo real. Conforme adicionamos os dados da story, sabemos se
nosso modelo está ou não produzindo a saída correta. O mais importante é
que podemos ver se o modelo está melhorando ou piorando quando
adicionamos novas stories. Quase sempre, ele melhora porque estamos
fazendo uma espécie de aprendizado por reforço em que dizemos ao
modelo de ML que aprenda e reaprenda – semelhante ao que ocorre com
os seres humanos.
Criando dados de story
Como sabemos, os dados de story são apenas um tipo de conversa entre
um usuário e um chatbot mostrando como eles chegariam a um final
lógico. Geralmente, todos os chatbots são projetados para ajudar os
usuários a realizar um conjunto predefinido de tarefas; as stories apenas
representam como elas serão executadas.
Tentaremos preparar alguns diálogos simples no formato que o Rasa
espera. Esses diálogos serão stateless – isto é, não dependem de diálogos
anteriores. Usaremos nossas stories stateless no aprendizado interativo.
Reservaremos alguns minutos para preparar manualmente algumas stories
que conhecemos para nos acostumar com como os dados de story são
criados.
Primeiro criaremos um arquivo chamado [Link] em nossa pasta data.
## story_001
* greeting
- utter_greet
* get_horoscope
- utter_ask_horoscope_sign
* get_horoscope{"horoscope_sign": "Capricorn"}
- slot{"horoscope_sign": "Aries"}
- get_todays_horoscope
- utter_subscribe
## story_002
* greeting
- utter_greet
* get_horoscope{"horoscope_sign": "Capricorn"}
- slot{"horoscope_sign": "Cancer"}
- get_todays_horoscope
- utter_subscribe
* subscription
- slot{"subscribe": "True"}
- subscribe_user
## Consulta ao horócopo com horoscope_sign
* greeting
- utter_greet
* get_horoscope
- utter_ask_horoscope_sign
* get_horoscope{"horoscope_sign": "capricorn"}
- slot{"horoscope_sign": "capricorn"}
- get_todays_horoscope
- slot{"horoscope_sign": "capricorn"}
- utter_subscribe
* subscription{"subscribe": "True"}
- slot{"subscribe": "True"}
- subscribe_user
- slot{"subscribe": true}
## Horóscopo com fornecimento do signo
* greeting
- utter_greet
* get_horoscope{"horoscope_sign": "leo"}
- slot{"horoscope_sign": "leo"}
- get_todays_horoscope
- slot{"horoscope_sign": "leo"}
- utter_subscribe
* subscription{"subscribe": "True"}
- slot{"subscribe": "True"}
- subscribe_user
- slot{"subscribe": true}
## Quando o usuário solicitar diretamente a assinatura
* greeting
- utter_greet
* subscription{"subscribe": "True"}
- slot{"subscribe": "True"}
- subscribe_user
- slot{"subscribe": true}
Se você examinar as stories por alguns instantes, entenderá o que
significam; não deve ser difícil saber o que está ocorrendo. A principal
diferença entre as duas primeiras stories é que na primeira o usuário não
menciona seu signo e o bot precisa pedi-lo para prosseguir.
Na segunda story, o próprio usuário informa o signo e conclui a story com
um diálogo sobre a assinatura. Adicionamos mais algumas stories
abordando outros casos de uso. Fique à vontade para adicionar as próprias
stories ao mesmo arquivo.
Basicamente, as stories são arquivos Markdown em que podemos criar
quantas stories forem necessárias no formato Markdown já mostrado. É
difícil executar essa tarefa manualmente, portanto, tentaremos aprender a
usar a ferramenta de aprendizado interativo do Rasa para gerar mais stories
como essa.
Mãos à obra.
Aprendizado interativo
Até agora, falamos sobre o aprendizado interativo de maneira fragmentada,
mas é hora de escrever realmente o código e colocar o conceito em prática.
O aprendizado interativo é um dos recursos mais interessantes que o Rasa
fornece, no qual ele torna a parte referente ao ML fácil e divertida. Serão
duas etapas: na primeira, treinaremos um modelo fornecendo o conjunto
de dados inicial usando várias políticas, e na segunda etapa vamos testar o
modelo, corrigi-lo e treiná-lo novamente de maneira interativa.
Treinando o modelo de agente de chatbot
Criaremos um novo arquivo chamado train_initialize.py no diretório
principal de nosso projeto. O conteúdo de train_initialize.py é este:
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
from rasa_core import utils
from rasa_core.agent import Agent
from rasa_core.policies.keras_policy import KerasPolicy
from rasa_core.[Link] import MemoizationPolicy
from rasa_core.policies.sklearn_policy import SklearnPolicy
if __name__ == '__main__':
utils.configure_colored_logging(loglevel="DEBUG")
training_data_file = './data/[Link]'
model_path = './models/dialogue'
agent = Agent("horoscope_domain.yml",
policies=[MemoizationPolicy(), KerasPolicy()])
training_data = agent.load_data(training_data_file)
[Link](
training_data,
augmentation_factor=50,
epochs=500,
batch_size=10,
validation_split=0.2
)
[Link](model_path)
Esse é o código que criamos no arquivo train_initialize.py. Antes de
passarmos para o próximo arquivo de código, tentaremos entender os
pontos importantes do atual.
1. Primeiro, importamos alguns métodos do módulo __future__.
Declarações desse módulo têm uso especial, alteram como o módulo
Python é analisado (parsed), e mudam a maneira como o seu método se
comporta.
É uma pessoa curiosa? Teste o código a seguir em seu interpretador
Python:
from __future__ import braces
2. Importamos o método utils dos módulos rasa_core para configurar o
logging.
3. Importamos a classe agent do módulo agent para criar o objeto de
agente.
4. KerasPolicy e MemoizationPolicy serão passados como parâmetros de
políticas para a classe agent.
5. configure_colored_logging: Método utilitário definido em [Link] para
logging colorido usando o pacote coloredlogs do Python.
6. Agent: Classe definida pelo Rasa que fornece uma interface para uso das
funcionalidades mais importantes do Rasa Core, como treinamento,
manipulação de mensagens, carregamento de um modelo de diálogo,
obtenção da próxima ação e manipulação de um canal.
7. load_data: carrega dados de treinamento a partir do caminho fornecido.
8. train: treina as políticas usando dados do arquivo fornecido.
9. training_data: objeto retornado pelo método load_data. Lista de
DialogueStateTracker. É apenas nosso arquivo de dados de treinamento.
10. augmentation_factor: informa ao Rasa quantas stories fictícias devem ser
criadas dado nosso conjunto inicial de stories. Um fator igual a 10 vezes
é a heurística da sucessão de aumentos para o gerador de dados de
treinamento.
11. epochs: 1 epoch é um ciclo de treinamento com um conjunto de dados
inteiro. É a quantidade total de vezes que os dados de treinamento são
percorridos para a frente e para trás.
12. batch_size: informa a quantidade de exemplos de treinamento a ser
usada em cada passagem. Demoraremos 10 epochs para percorrer o
conjunto de dados inteiro se tivermos 100 exemplos em um lote de
tamanho 10.
13. validation_split: percentual de dados para a validação da precisão
imparcial de um modelo.
14. persist: esse método é usado para manter o objeto de agente em
determinado diretório para reutilização.
Agora você já sabe o que cada método faz e o que está acontecendo no
código.
Antes de executar o script, certifique-se de instalar a biblioteca rasa_core.
Você pode instalar o rasa_core usando o comando a seguir:
pip install rasa_core==0.11.1
Se estiver seguindo o exemplo de chatbot deste livro, instale apenas a
versão mencionada, já que o Rasa pode não ter compatibilidade regressiva.
Eles não demoram a lançar métodos novos e mais otimizados.
O RASA_CORE MAIS RECENTE
Você também pode instalar a versão mais recente do rasa_core a partir do repositório do
github. Basta executar o conjunto de comandos a seguir, os quais obterão o código mais recente
no github diretamente antes da instalação.
git clone [Link]
cd rasa_core
pip install -r [Link]
pip install -e .
Executaremos o arquivo do código para treinar nosso modelo com os
parâmetros fornecidos.
$python train_initialize.py
Você também pode executar esse script a partir do próprio Jupyter
Notebook, usando o comando mágico do Jupyter, como mostrado aqui:
!python train_initialize.py #Use python3 se instalou o rasa para essa versão
python
Deve demorar de 25 a 30 segundos para o modelo ser treinado com um
conjunto de dados tão pequeno como o nosso. Adicionei SklearnPolicy na
lista de políticas junto com MemoizationPolicy e KerasPolicy para treinar meu
modelo. Diferentes políticas têm benefícios específicos. Leia mais sobre
elas para saber qual funcionará melhor para seu caso de uso; para meu
conjunto de dados, às vezes SklearnPolicy parece se sair melhor do que
KerasPolicy.
Após a execução do script terminar, você deve ver algumas mensagens de
sucesso como estas:
2018-08-30 04:24:31 INFO rasa_core.policies.keras_policy - Done fitting keras
policy model
2018-08-30 04:24:31 INFO rasa_core.featurizers - Creating states and action
examples from collected trackers (by MaxHistoryTrackerFeaturizer)...
Processed trackers: 100%|████████| 96/96 [00:00<00:00, 898.31it/s, #
actions=75]
2018-08-30 04:24:31 INFO rasa_core.featurizers - Created 75 action examples.
2018-08-30 04:24:31 INFO rasa_core.policies.sklearn_policy - Done fitting sklearn
policy model
2018-08-30 04:24:31 INFO rasa_core.agent - Model directory models/nlu exists and
contains old model files. All files will be overwritten.
2018-08-30 04:24:31 INFO rasa_core.agent - Persisted model to
'/Users/sumit/apress_all/Chapter IV/horoscope_bot/models/nlu'
Você também verá algumas pastas criadas a partir do nome do modelo.
Verifique se elas estão no caminho de modelo que você forneceu no script.
A seguir temos as pastas/arquivos que vi dentro de minha pasta model_path.
policy_0_MemoizationPolicy
policy_1_KerasPolicy
policy_2_SklearnPolicy
[Link]
[Link]
Policy_metadata.json
Se você verificou que o modelo terminou com sucesso a execução, e o fez
persistir no sistema local, podemos passar para a próxima etapa do
treinamento interativo.
Treinamento por reforço em tempo real
Nesta seção, escreveremos mais um código para treinar nosso modelo de
diálogo e retreiná-lo quando ele fornecer uma saída incorreta.
Quando nosso bot faz algo errado, interferimos imediatamente e
informamos ao modelo que a previsão está errada e dizemos a ele qual é a
certa. Sem precisar parar, o modelo retreina a si próprio, e, ao terminar, a
interação entre o usuário e o bot é capturada em um arquivo e adicionada
aos dados de treinamento existentes. Funciona mais como um sistema de
feedback a cada etapa, em vez de ser uma espera de recompensa ao final.
A próxima etapa é criar um novo arquivo chamado [Link] com o
conteúdo a seguir. Usaremos esse arquivo em nosso arquivo de código
Python train_online.py. Com essa configuração podemos expor o método
Rasa como APIs HTTP.
action_endpoint:
url: [Link]
#nlg:
# url: [Link]
core_endpoint:
url: [Link]
Agora criaremos train_online.py para fins de treinamento online/interativo.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
import logging
from rasa_core import utils, train
from rasa_core.training import online
from rasa_core.interpreter import NaturalLanguageInterpreter
logger = [Link](__name__)
def train_agent(interpreter):
return train.train_dialog_model(domain_file="horoscope_domain.yml",
stories_file="data/[Link]",
output_path="models/dialog",
nlu_model_path=interpreter,
endpoints="[Link]",
max_history=2,
kwargs={"batch_size": 50,
"epochs": 200,
"max_training_samples": 300
})
if __name__ == '__main__':
utils.configure_colored_logging(loglevel="DEBUG")
nlu_model_path = "./models/nlu/default/horoscopebot"
interpreter = [Link](nlu_model_path)
agent = train_agent(interpreter)
online.serve_agent(agent)
é o número de estados a serem rastreados pelo modelo.
max_history
Antes de executar nosso script final, train_online.py, devemos conhecer e
nos preparar para algo chamado rasa-nlu-sdk.
rasa-nlu-sdk
A stack Rasa NLU vem com o rasa-nlu-sdk, que é um SDK Python para o
desenvolvimento de ações personalizadas para o Rasa Core. Em nosso
exemplo de chatbot, precisamos definir algumas ações personalizadas,
como acessar a API para obter o horóscopo de hoje ou as operações de
gravação de um banco de dados para adicionar o usuário à lista de
assinaturas.
A boa notícia é que há uma biblioteca separada para isso, e podemos
instalá-la usando o pip.
Vamos instalá-la usando o comando a seguir:
pip install rasa-core-sdk==0.11.0
Agora temos de acessar outra aba de nosso terminal ou uma linha de
comando nova e executar o comando a seguir no diretório do projeto (o
lugar onde está o arquivo [Link]):
python -m rasa_core_sdk.endpoint --actions actions
INFO:__main__:Starting action endpoint server...
INFO:rasa_core_sdk.executor:Registered function for 'get_todays_horoscope'.
INFO:rasa_core_sdk.executor:Registered function for 'subscribe_user'.
INFO:__main__:Action endpoint is up and running. on ('[Link]', 5055)
Esse comando iniciará um servidor de ações que escutará as ações
personalizadas previstas pelo modelo. Assim que alguma ação for
acionada, ele a executará e fornecerá a resposta de acordo com o método.
A porta padrão do endpoint do servidor de ações é 5055 em localhost. Se
quiser alterá-la, adicione o argumento --port à linha de comando.
Uma pergunta repentina vem à mente: por quê? Por que preciso de um
servidor separado para isso? Por que não usar apenas Python? Sim,
podemos usar apenas Python, mas suponhamos que você quisesse
desenvolver as ações requeridas em outra linguagem ou tivesse algumas
ações expostas como APIs. Você só precisa ir até o arquivo [Link],
que já criamos, e usá-lo para mencionar a partir de que local seu servidor
de ações deve ser utilizado e onde está o servidor core_endpoint. Em um
sistema de produção, os dois podem ser servidores diferentes com urls
distintas.
Quando executarmos nosso próximo script, no qual mencionamos o
arquivo [Link], o Rasa lerá o arquivo e obterá a configuração de
action_server, que já está sendo executado de acordo com a configuração
que criamos anteriormente.
action_endpoint:
url: [Link]
Executaremos train_online.py em um novo terminal de linha de comando.
$python3 train_online.py
Após o treinamento bem-sucedido do modelo de diálogo, veremos uma
mensagem como esta:
2018-08-30 07:09:37 INFO rasa_core.policies.keras_policy - Done fitting keras
policy model
2018-08-30 07:09:37 INFO rasa_core.agent - Model directory models/nlu exists and
contains old model files. All files will be overwritten.
2018-08-30 07:09:37 INFO rasa_core.agent - Persisted model to
'/Users/sumit/apress_all/Chapter IV/horoscope_bot/models/nlu'
2018-08-30 07:09:37 INFO rasa_core.[Link] - Rasa Core server is up and
running on [Link]
Bot loaded. Type a message and press enter (use '/stop' to exit).
[Link] - - [2018-08-30 07:09:37] "GET /domain HTTP/1.1" 200 996 0.001847
Agora você pode começar a conversar com o bot que acabou de ser criado.
A partir de então, dependerá de você a maneira como vai treiná-lo. Você
pode corrigi-lo sempre que ele responder com algo inadequado ou
inesperado.
Faremos isso para ver se ele melhora.
Inseri "Hi" (xxx) como a primeira mensagem e o bot retornou o seguinte:
---------------------------------------------------------------------------
Chat history:
bot did: action_listen
user said: hi
whose intent is: {'confidence': 0.8472929307505297, 'name': 'greeting'}
we currently have slots: DD: None, MM: None, horoscope_sign: None, subscribe:
None
------
The bot wants to [utter_greet] due to the intent. Is this correct?
1. Yes
2. No, intent is right but the action is wrong
3. The intent is wrong
0. Export current conversations as stories and quit
---------------------------------------------------------------------------
Agora o bot está me dizendo o que fez de acordo com o que o usuário disse
e como ele entendeu. Ele também fornece quatro opções. Falaremos sobre
isso em breve.
Aqui, bot_did (o que o robô fez) é igual a action_listen (escutar ação); ele só
estava esperando o usuário inserir algo, o que está correto.
O bot forneceu a intenção {'confidence': 0.8472929307505297, 'name':
'greeting'}, que está correta, logo, pressionaremos 1, que significa que ele
está entendendo e tentando fazer o que é certo.
1
---------------------------------------------------------------------------
Chat history:
bot did: action_listen
user said: hi
whose intent is: {'confidence': 0.8472929307505297, 'name': 'greeting'}
bot did: utter_greet
we currently have slots: DD: None, MM: None, horoscope_sign: None, subscribe:
None
------
The bot wants to [action_listen]. Is this correct?
1. Yes.
2. No, the action is wrong.
0. Export current conversations as stories and quit
---------------------------------------------------------------------------
E aí está, pelo menos nosso bot saudou o usuário apropriadamente. Se
você deparar com a resposta anterior, saberá o que o bot fez; ele está
registrando tudo enquanto o treinamos.
bot did: utter_greet
Agora o bot está dizendo que a próxima etapa é esperar e escutar o que o
usuário vai dizer (isto é, esperar a entrada do usuário). Isso está correto?
Sim, está correto, logo, pressione 1 novamente e o bot fornecerá um
prompt para o usuário.
Inseri "What's my horoscope for today?" (Qual é o meu horóscopo para
hoje?)
---------------------------------------------------------------------------
Chat history:
bot did: action_listen
user said: hi
whose intent is: {'confidence': 0.8472929307505297, 'name': 'greeting'}
bot did: utter_greet
bot did: action_listen
user said: what's my horoscope for today?
whose intent is: {'confidence': 0.8902154738608781, 'name': 'get_horoscope'}
we currently have slots: DD: None, MM: None, horoscope_sign: None, subscribe:
None
------
The bot wants to [utter_ask_horoscope_sign] due to the intent. Is this correct?
1. Yes
2. No, intent is right but the action is wrong
3. The intent is wrong
0. Export current conversations as stories and quit
---------------------------------------------------------------------------
O bot identificou corretamente, com 89% de precisão, que a intenção é
"get_horoscope", o que é muito bom. Ele também disse que deseja saber o
signo (utter_ask_horoscope_sign), o que novamente está correto porque o
usuário não mencionou nenhum signo ainda e o slot continua sendo None,
como mostrado.
Pressionaremos 1 novamente.
---------------------------------------------------------------------------
Chat history:
bot did: action_listen
user said: hi
whose intent is: {'confidence': 0.8472929307505297, 'name': 'greeting'}
bot did: utter_greet
bot did: action_listen
user said: what's my horoscope for today?
whose intent is: {'confidence': 0.8902154738608781, 'name': 'get_horoscope'}
bot did: utter_ask_horoscope_sign
we currently have slots: DD: None, MM: None, horoscope_sign: None, subscribe:
None
------
The bot wants to [action_listen]. Is this correct?
1. Yes.
2. No, the action is wrong.
0. Export current conversations as stories and quit
---------------------------------------------------------------------------
O bot está perguntando se é hora de esperar a entrada do usuário. Sim, o
usuário precisa fornecer o signo.
Pressionaremos 1 mais uma vez e, quando solicitados, inseriremos
"Capricorn" como entrada.
---------------------------------------------------------------------------
Chat history:
bot did: action_listen
user said: hi
whose intent is: {'confidence': 0.8472929307505297, 'name': 'greeting'}
bot did: utter_greet
bot did: action_listen
user said: what's my horoscope for today?
whose intent is: {'confidence': 0.8902154738608781, 'name': 'get_horoscope'}
bot did: utter_ask_horoscope_sign
bot did: action_listen
user said: Capricorn
whose intent is: {'confidence': 0.8456705103362621, 'name': 'get_horoscope'}
with horoscope_sign: capricorn
we currently have slots: DD: None, MM: None, horoscope_sign: capricorn,
subscribe: None
The bot wants to [get_todays_horoscope] due to the intent. Is this correct?
1. Yes
2. No, intent is right but the action is wrong
3. The intent is wrong
0. Export current conversations as stories and quit
---------------------------------------------------------------------------
Como podemos ver, o slot horoscope_sign foi configurado automaticamente
com "Capricorn".
A próxima etapa é ensinar o bot a chamar get_todays_horoscope e a executar a
ação associada. Nosso slot já está configurado com a variável horoscope_sign
que definimos em horoscope_domain.yml, logo, se essa ação for chamada
novamente, o chatbot deve retornar o horóscopo do dia. Vejamos se
funciona.
Inseri "Capricorn".
O bot acessará o endpoint do servidor de ações e retornará o resultado
para o usuário como definimos em nossa ação personalizada.
Your today's horoscope:
Horóscopo de hoje:
The journey from defeat to success is driven by optimism. You will be
very optimistic today—about your work, future, and everything that
can lead you to success, says Ganesha. You will also be very careful
while dealing with day-to-day work, and will capitalize on every
opportunity that can get you a step closer to your goals. Determination
and good luck is all you need to realize your dreams; you will have both
today.
(A jornada da derrota ao sucesso é conduzida pelo otimismo. Você estará
muito otimista hoje – sobre seu trabalho, futuro e tudo que pode levá-lo
ao sucesso, diz Ganesha. Também terá muito cuidado ao lidar com o
trabalho cotidiano e se beneficiará de todas as oportunidades que
puderem levá-lo para mais perto de seus objetivos. Você só precisa de
determinação e boa sorte para realizar seus sonhos; terá os dois hoje.)
Parece justo, já que perdi o prazo final de conclusão deste capítulo, e no
momento são 6 da manhã e ainda não dormi. Estou fazendo de tudo para
que você ache que valeu a pena gastar seu dinheiro com este livro.
Voltemos, então, para ver o que nosso bot está tentando fazer agora.
------
The bot wants to [action_listen]. Is this correct?
1. Yes.
2. No, the action is wrong.
0. Export current conversations as stories and quit
Podemos não querer que o bot continue escutando após ter informado o
horóscopo de hoje. Queremos que solicite ao usuário que se inscreva para
receber atualizações de acordo com o roteiro da conversa e também com as
stories que criamos.
Portanto, pressionarei 2 e ele dirá
------
what is the next action for the bot?
0 action_listen 1.00
1 action_restart 0.00
2 action_default_fallback 0.00
3 utter_greet 0.00
4 utter_ask_horoscope_sign 0.00
5 utter_ask_dob 0.00
6 utter_subscribe 0.00
7 get_todays_horoscope 0.00
8 subscribe_user 0.00
Já que queremos que nosso usuário se cadastre, devemos pressionar 6 para
que o bot pergunte se ele/ela quer se cadastrar para receber atualizações
diárias.
O bot responderá "Do you want to subscribe for daily updates?" (Deseja se
cadastrar para atualizações diárias?).
Em seguida, dirá:
---------------------------------------------------------------------------
The bot wants to [get_todays_horoscope]. Is this correct?
1. Yes.
2. No, the action is wrong.
0. Export current conversations as stories and quit
A ação não está correta, logo, pressionaremos 2 e treinaremos o bot para
escutar a ação do usuário.
---------------------------------------------------------------------------
what is the next action for the bot?
0 action_listen 0.21
1 action_restart 0.01
2 action_default_fallback 0.01
3 utter_greet 0.21
4 utter_ask_horoscope_sign 0.51
5 utter_ask_dob 0.01
6 utter_subscribe 0.02
7 get_todays_horoscope 0.78
8 subscribe_user 0.22
---------------------------------------------------------------------------
Pressionaremos 0 quando o bot estiver esperando para saber qual é a
próxima etapa. Agora ele esperará a entrada do usuário em nosso processo
de aprendizado interativo.
O usuário diz "Please subscribe me" (Cadastre-me, por favor) e nosso bot
reconhece com 80% de segurança que essa é uma intenção de assinatura e,
baseado nos dados de treinamento de [Link], também entende facilmente
que o usuário está pedindo para fazer a assinatura e não a cancelar. Em
outras palavras, ele configurou o slot subscribe com True, como você pode
ver aqui:
---------------------------------------------------------------------------
user said: Please subscribe me
whose intent is: {'confidence': 0.795172441763619, 'name': 'subscription'}
with subscribe: True
we currently have slots: DD: None, MM: None, horoscope_sign: capricorn,
subscribe: True
---------------------------------------------------------------------------
Agora que nosso bot entendeu a intenção e também fez o parsing de suas
entidades, é hora de responder ao usuário dizendo que ele foi cadastrado
com sucesso, e aí está – recebemos a mensagem do bot:
You're successfully subscribed
Pronto! Você pode construir com sucesso seu próprio chatbot. Como parte
do exercício, recomendo que adicione todos os casos de uso que
discutimos para HoroscopeBot e veja se ele funciona. Tente adicionar mais
casos de uso e recursos quando tudo que fizemos até agora estiver
funcionando bem.
Você pode adicionar mais uma mensagem aqui para que o bot diga
"Goodbye, have a good day" (Até a próxima, tenha um bom-dia) após a
conversa ser concluída. Tenho certeza de que consegue. Não deixe de fazê-
lo e nos diga como se saiu.
Como parte final, devemos retornar todo esse aprendizado para o usuário a
fim de não precisarmos ensinar as mesmas stories novamente, e o bot deve
tentar aprender com as stories existentes e outras que virão.
Exportando conversas como stories
A próxima etapa da parte do aprendizado interativo é pressionar 0,
exportar nossas conversas atuais como stories e sair da aplicação.
Pressionaremos 0 para fazer isso e o bot exibirá algo como:
File to export to (if file exists, this will append the stories) [[Link]]:
Insira o nome de arquivo [Link]; se tiver dado outro nome, certifique-se
de fornecer o nome de arquivo correto.
O Rasa fará a parte difícil para nós e gerará mais uma vez um arquivo
[Link] automaticamente como este:
## Generated Story 3797421409943253925
* greeting
- utter_greet
* I want to know my horoscope
- utter_ask_horoscope_sign
* get_horoscope
## Generated Story 7304374603374920907
* greeting
- utter_greet
* what is my todays horoscope?
- utter_ask_horoscope_sign
* Cancer
## Generated Story -6877464862083507836
* greeting
- utter_greet
* get_horoscope
- utter_ask_horoscope_sign
* get_horoscope{"horoscope_sign": "capricorn"}
- slot{"horoscope_sign": "capricorn"}
- get_todays_horoscope
- slot{"horoscope_sign": "capricorn"}
- utter_subscribe
* subscription{"subscribe": "True"}
- slot{"subscribe": "True"}
- subscribe_user
- slot{"subscribe": true}
Você pode alterar a origem do arquivo de stories ao treinar o modelo com
o arquivo citado ou pode copiar e colar as stories recém-geradas em nosso
arquivo [Link] original. Por enquanto, copiarei e colarei as stories no
arquivo [Link]. Certifique-se de executar seus modelos antes de fazer
testes ou realizar o aprendizado interativo novamente.
Testando o bot
Testar o bot faz parte do processo de aprendizado interativo. Verificamos
todos os cenários possíveis pensados inicialmente para o bot e o treinamos
de acordo. Testei o Horoscope Bot para alguns outros cenários e o treinei.
A seguir apresento um deles, que é um pouco diferente do que fizemos
anteriormente neste capítulo.
Caso de teste 1
Executaremos o primeiro teste:
Usuário: Hello there! (Olá!).
HoroscopeBot: Hello! What can I do for you? (Olá! Em que posso
ajudá-lo?).
Usuário: What's the horoscope for Capricorn today? (Qual é o
horóscopo de hoje para capricórnio?).
HoroscopeBot: Your today's horoscope: (Seu horóscopo para hoje:).
The journey from defeat to success is driven by optimism. You will be
very optimistic today – about your work, future, and everything that
can lead you to success, says Ganesha. You will also be very careful
while dealing with day-to-day work, and will capitalize on every
opportunity that can get you a step closer to your goals. Determination
and good luck is all you need to realize your dreams; you will have both
today.
(A jornada da derrota ao sucesso é conduzida pelo otimismo. Você estará
muito otimista hoje – sobre seu trabalho, futuro e tudo que pode levá-lo
ao sucesso, diz Ganesha. Também terá muito cuidado ao lidar com o
trabalho cotidiano e se beneficiará de todas as oportunidades que
puderem levá-lo para mais perto de seus objetivos. Você só precisa de
determinação e boa sorte para realizar seus sonhos; terá os dois hoje).
HoroscopeBot: Do you want to subscribe for daily updates? (Deseja se
cadastrar para atualizações diárias?).
Usuário: Please subscribe me (Cadastre-me, por favor).
HoroscopeBot: You're successfully subscribed (Você foi cadastrado com
sucesso).
Como você pode ver nessa conversa entre o usuário e o chatbot, testamos
se o bot manipula o cenário em que o próprio usuário fornece o signo ao
solicitar o horóscopo do dia. O bot se sai bem nesse caso, oferece
cadastramento e, de acordo com a resposta do usuário, executa a ação
apropriada.
Você deve fazer um teste de conformidade na conversa do bot para
determinar se o fluxo normal está ou não funcionando.
Também testei a story que mencionamos em nosso arquivo [Link] em
que o usuário solicita diretamente uma assinatura e ele também funcionou.
Caso de teste 2
Agora o segundo teste:
Usuário: Hi (Olá).
HoroscopeBot: Hello! What can I do for you? (Olá! Em que posso
ajudá-lo?).
Usuário: Subscribe me please for daily updates (Cadastre-me, por favor,
para atualizações diárias).
HoroscopeBot: You're successfully subscribed (Você foi cadastrado com
sucesso).
Adicionarei mais algumas stories para que o bot funcione sem falhas.
Mesmo assim, já temos um bot totalmente funcional. Na segunda versão
do código no github, você verá que o bot está corrigindo os erros de grafia
do signo, recuperando o signo de acordo com a DOB do usuário, exibindo
uma mensagem de adeus etc. Recomendo que você verifique o código para
ver como isso foi feito e dê feedback. Porém, antes pense em como o faria e
em onde inseriria alterações. Não comentamos o código dos outros casos
de uso neste capítulo propositalmente, para que as coisas não ficassem
muito confusas enquanto você se concentra em aprender os truques do
ofício.
Baixe o código Python e os Jupyter Notebooks mais recentes a partir de
nosso repositório no github e tente instalar os pacotes corretos para
executá-los. Você também encontrará mais casos de uso manipulados no
código como discutido neste capítulo.
Resumo
Neste capítulo, conhecemos o Rasa-NLU e vimos por que ele é melhor do
que outras ferramentas open source disponíveis no mercado. Também
aprendemos a configurar pipelines usando o TensorFlow, o sklearn e o
keras.
Aprendemos a criar a aplicação toda a partir do zero em nosso sistema
local sem depender de serviços que demandam o uso de suas APIs, como o
Dialogflow, [Link] etc.
Também examinamos como criar stories e treinar um modelo NLU e um
modelo de diálogo e usá-los com o Rasa Core para construir um bot por
treinamento utilizando um recurso muito interessante, o aprendizado
interativo. Tivemos uma boa noção de como criar dados de treinamento
facilmente com a ajuda de ferramentas open source como o rasa-nlu-
trainer. Espero que este capítulo tenha sido mais interativo para você do
que os outros. Se não estiver satisfeito, prepare-se para o próximo capítulo,
no qual colocaremos o bot no ar para nosso público e mostraremos a todos
o que os bots podem fazer. Aprenderemos a integrar o chatbot deste
capítulo a várias plataformas como o Facebook e o Slack usando nossos
próprios servidores.
Continue treinando seu bot até o colocarmos no ar no próximo capítulo.
Vejo-o lá.
CAPÍTULO 5
Implantando seu chatbot
Neste capítulo, aprenderemos a implantar nossos chatbots na web. Há
várias maneiras e canais pelos quais podemos implantar ou expor uma
aplicação web de chatbot no ambiente externo. Para ver um exemplo,
podemos expor o HoroscopeBot com o NLU e o modelo de diálogo no
Facebook e Slack porque eles já fornecem uma interface de usuário. Se
quiser, você pode ter um aplicativo web sendo executado em seu próprio
servidor. Também examinaremos no fim do capítulo como implantar um
chatbot em nossos próprios servidores usando nossa interface de usuário.
Primeiras etapas
A primeira etapa é criar uma cópia do chatbot que construímos no
Capítulo 4 e fazer outra cópia para termos um backup. Já que faremos
algumas alterações adicionando novo código, manteremos os dois projetos
separados.
Criei uma nova pasta chamada Chapter V e colei minha pasta horoscope_bot
nela. Todos os meus arquivos de modelo, conjuntos de dados e arquivos de
código foram copiados e eu posso usá-los diretamente na implantação.
Gerenciamento de credenciais do Rasa
O Rasa fornece uma maneira de gerenciarmos todas as credenciais no
mesmo local. Você poderia ter um único modelo, mas querer implantá-lo
em várias plataformas como o Facebook, Slack, Telegram etc. Todas essas
plataformas de terceiros precisam que credenciais sejam usadas na
conexão. As credenciais são armazenadas em um arquivo YAML chamado
[Link].
Criaremos um arquivo chamado [Link] na pasta horoscope_bot do
diretório do projeto e inseriremos nele nossas credenciais do Facebook. Se
não sabe como fazê-lo, apenas crie o arquivo por enquanto, e na próxima
seção verá as etapas para a obtenção de credenciais do Facebook.
O conteúdo de [Link] será o seguinte:
facebook:
verify: "horoscope-bot"
secret: "bfe5a34a8903e745e32asd18"
page-access-token: "HPaCAbJJ1JmQ7qDedQKdjEAAbO4iJKr7H9nx4rEBAAuFk4Q3gPQcNT0wtD"
Essas credenciais são fictícias; o tamanho do token ou senha e o tipo dos
caracteres podem ser diferentes em seu aplicativo do Facebook.
Se você estiver trabalhando em um projeto grande em que esteja
integrando seu chatbot a várias plataformas e quiser tornar a manutenção
mais fácil, é melhor usar [Link]. Recomendo que você tenha um
arquivo [Link] se estiver em uma empresa e quiser construir um bot
que funcione da mesma maneira em várias plataformas como o Facebook,
Slack, Twitter, Telegram ou em seu próprio site. Nesse caso, fica mais fácil
gerenciar chaves e senhas.
Uma boa maneira de gerenciar chaves secretas de nível de aplicação é
armazená-las como variáveis de ambiente e escrever um código que leia os
valores das chaves ou qualquer outra informação sigilosa a partir do
ambiente do próprio sistema operacional. Lembre-se, não é uma boa ideia
manter as chaves dentro de seu código.
Você também pode criar um arquivo ponto (.) env em seu servidor e ler as
chaves nele; esse arquivo não estará em nenhum local do repositório de seu
código.
Para simplificar, usaremos as chaves de acesso e as chaves secretas em
nossos scripts independentes para fazer a implantação. Vamos tornar o
exemplo fácil de entender: primeiro construiremos o bot, depois o
escalaremos e, o mais importante, consideraremos problemas de nível de
segurança.
Se você precisar implantar seu bot em várias plataformas e quiser usar o
arquivo [Link] para ter diferentes credenciais, pode utilizá-lo
passando um argumento adicional. Como exemplo com o uso do arquivo
de credenciais anterior chamado [Link], ao executar o rasa core
você pode empregar o comando a seguir.
python -m rasa_core.run -d models/dialogue -u models/nlu/current --port 5002 --
credentials [Link]
É bom sabermos disso para quando desenvolvermos chatbots maiores de
nível empresarial, mas, como discutido, usaremos as credenciais
diretamente em nosso script nos próximos exemplos.
Implantando o chatbot no Facebook
Nesta seção, primeiro implantaremos nosso chatbot usando o Heroku na
nuvem, uma plataforma como serviço (PaaS, platform-as-a-service) que
permite aos desenvolvedores construir, executar e operar aplicações
totalmente na nuvem. O benefício que ele traz é que podemos fazer
facilmente o aplicativo ser executado no https. Não precisamos comprar
certificados SSL enquanto estamos conhecendo e testando os chatbots. O
https é necessário porque algumas plataformas como o Facebook não
permitem aos desenvolvedores usar urls não https como URLs de callback.
Seguiremos um conjunto de etapas individualmente para implantar com
sucesso nosso chatbot como web service na nuvem. Após obter êxito, será
muito mais fácil integrá-lo a diferentes plataformas como o Slack,
Telegram etc. Mãos à obra.
Criando um aplicativo no Heroku
Hora de começar:
Cadastre-se no Heroku, crie um aplicativo e chame-o de something-actions, já
que esse será nosso aplicativo de servidor de ações. Examine o screenshot
da Figura 5.1, no qual demos um nome exclusivo para o servidor de ações,
que precisa estar disponível no Heroku. Se o nome estiver disponível,
clique no botão Create app para criar o aplicativo de servidor de ações.
Figura 5.1 – Criando o aplicativo de servidor de ações no Heroku com o
nome horoscopebot1212-actions.
Fique à vontade para dar o nome que quiser se o que escolheu não estiver
disponível, mas tente sempre dar nomes significativos.
Instalando o Heroku em seu sistema local
Instale a CLI do Heroku em seu sistema operacional local. Acesse este link:
[Link]
Se estiver no macOS, use o comando a seguir:
brew install heroku/brew/heroku
Criando e configurando um aplicativo no Facebook
Para implantar nosso chatbot no Facebook, primeiro precisamos ter
credenciais do aplicativo na plataforma. Para obter credenciais, temos de
configurar um aplicativo e uma página do Facebook, como fizemos em um
aplicativo do Capítulo 3.
1. Acesse [Link] e crie um aplicativo se ainda não
tiver um. Criamos um para nosso OnlineEatsBot; agora criaremos outro
para HoroscopeBot. Insira os detalhes e clique em Create App ID. Examine
a Figura 5.2 para ver como inserir o nome de exibição de seu bot e seu
email de contato.
Figura 5.2 – Criando o aplicativo no Facebook para desenvolvedores.
2. Após o aplicativo ser criado, acesse Basic sob Settings e clique no botão
Show em App Secret. Essa será sua variável fb_secret. Consulte a Figura 5.3
para ver exatamente onde você obterá sua chave fb_secret.
Figura 5.3 – Obtendo a senha para o aplicativo do Facebook.
3. Acesse o dashboard do aplicativo e role para baixo até "Add a
Product". Clique em Add a Product e adicione o Messenger (clique em
SetUp). Veja a Figura 5.4.
Figura 5.4 – Adicionando o Messenger como produto para o aplicativo do
Facebook.
4. Nas configurações do Messenger, quando você rolar para baixo até a
seção Token Generation, verá um link para criar uma nova página para seu
aplicativo. Se ainda não tiver uma página, crie-a ou selecione uma no
menu dropdown Select a page. Aqui, o token de acesso à página (Page Access
Token) será sua variável fb_access_token. Veja a Figura 5.5.
Você pode acessar o link a seguir para criar uma nova página para seu
projeto de bot: [Link]
Figura 5.5 – Gerando o token do aplicativo do Facebook Messenger.
5. Logo após a seção Token Generation, em Webhooks, clique em Setup
Webhooks. Veja a Figura 5.6.
Figura 5.6 – Definindo webhooks do Facebook.
6. Em seguida, selecione o token de verificação que usaremos
posteriormente. O token de verificação pode ser qualquer string
aleatória. Ele será sua variável fb_verify. Consulte a Figura 5.7 para
saber onde deve adicionar o token de verificação no aplicativo do
Facebook. Deixe a seção Callback URL em branco como se encontra. Não
feche o navegador; apenas o deixe de lado – voltaremos a ele.
Figura 5.7 – Adicionando o token de verificação à configuração de webhook
do Facebook.
7. Mantenha fb_verify, fb_secret e fb_access_token à mão para conectar seu
bot ao Facebook.
Criando e implantando o aplicativo de servidor de ações do Rasa no Heroku
Nessa etapa, usaremos nosso aplicativo de ações do Heroku como servidor
de ações do Rasa. Precisamos ter duas aplicações diferentes porque não
podemos executar duas aplicações web no mesmo aplicativo do Heroku.
Acesse sua linha de comando e execute o conjunto de comandos a seguir a
partir do diretório do projeto conforme instruções.
1. Crie uma nova pasta chamada actions_app e entre no diretório:
mkdir actions_app
cd actions_app
2. Copie [Link] do diretório principal do projeto para o diretório
actions_app.
3. Crie um arquivo [Link] com o conteúdo a seguir.
[Link] solicitará ao aplicativo Heroku que instale os pacotes
com suas versões.
rasa-core-sdk==0.11.0
requests==2.18.4
4. Crie um arquivo chamado Procfile com o conteúdo a seguir. Procfile é
o arquivo que mostra ao Heroku o que fazer para acionar as aplicações.
web: python -m rasa_core_sdk.endpoint --actions actions --port $PORT
a) Execute o conjunto de comandos a seguir:
$ heroku login
$ git init
$ heroku git:remote -a <nome-de-seu-aplicativo-do-heroku>
$ heroku buildpacks:set heroku/python
$ heroku config:set PORT=5055
$ git add .
$ git commit -am "deploy my bot"
$ git push heroku master
Após o último comando, o Heroku instalará todos os pacotes necessários
descritos no arquivo [Link]. Se seu aplicativo for implantado com
sucesso, você deve ver logs semelhantes aos seguintes:
remote:
remote: -----> Discovering process types
remote: Procfile declares types -> web
remote:
remote: -----> Compressing...
remote: Done: 48.3M
remote: -----> Launching...
remote: Released v4
remote: [Link] deployed to Heroku
remote:
remote: Verifying deploy... done.
To [Link]
* [new branch] master -> master
Por enquanto, vamos apenas verificar se nosso aplicativo está respondendo
a solicitações públicas. Para fazê-lo, acessaremos a url do aplicativo
acrescida de "webhook."
No meu caso, a url é [Link] logo,
verificarei se meu servidor de ações está respondendo.
Acessei a url [Link] e, como
esperado, a resposta foi Method Not Allowed, como na Figura 5.8, o que é bom
e significa que o aplicativo está respondendo corretamente conforme a
solicitação do usuário.
Figura 5.8 – Verificando o endpoint do servidor de ações.
Criando o aplicativo de API do chatbot Rasa
Nessa etapa, executaremos alguns procedimentos e comandos semelhantes
aos que acabamos de usar, mas esse é um novo aplicativo que criaremos
para ser o programa principal de gerenciamento de diálogo. Façamos isso.
Volte ao diretório principal do projeto (isto é, em horoscope_bot), crie um
nome de arquivo (Procfile) e adicione a ele o conteúdo a seguir:
web: python -m spacy download en && python [Link]
Criando um script independente para o chatbot do Facebook Messenger
Crie um nome de arquivo [Link] no mesmo diretório de projeto. O
conteúdo do arquivo Python deve ser o fornecido aqui:
from rasa_core.[Link] import FacebookInput
from rasa_core.agent import Agent
from rasa_core.interpreter import RasaNLUInterpreter
import os
from rasa_core.utils import EndpointConfig
# carrega o agente treinado
interpreter = RasaNLUInterpreter("models/nlu/default/horoscopebot/")
MODEL_PATH = "models/dialog"
action_endpoint = EndpointConfig(url="[Link]
[Link]/webhook")
agent = [Link](MODEL_PATH, interpreter=interpreter)
input_channel = FacebookInput(
fb_verify="YOUR_FB_VERIFY_TOKEN",
# você precisa fornecer esse token para o facebook para confirmar sua URL
fb_secret="YOUR_FB_SECRET", # senha do aplicativo
fb_access_token="YOUR_FB_ACCESS_TOKEN"
# token da página que você assinou
)
# configure serve_forever=True se quiser manter o servidor em execução
s = agent.handle_channels([input_channel], int([Link]('PORT', 5004)),
serve_forever=True)
Certifique-se de substituir os valores das variáveis fb_verify, fb_secret e
fb_access_token desse código pelos que usamos na Etapa 3.
Crie um novo arquivo [Link] e adicione todos os pacotes
requeridos pelo projeto e suas versões. Meu arquivo [Link] ficou
com a aparência a seguir; os requisitos podem ser outros para seu projeto,
mas esses devem ser adequados se você estiver seguindo o exemplo de bot
deste capítulo para instalar os pacotes no servidor.
rasa-core==0.11.1
rasa-core-sdk==0.11.0
rasa-nlu==0.13.2
gunicorn==19.9.0
requests==2.18.4
spacy==2.0.11
sklearn-crfsuite==0.3.6
Agora criaremos um novo aplicativo no Heroku como fizemos antes.
Acesse o dashboard do Heroku e crie um novo aplicativo como mostrado
na Figura 5.9.
Figura 5.9 – Criando o aplicativo de gerenciamento de diálogo no Heroku.
Após criar o aplicativo, acesse o diretório raiz de seu projeto e execute o
conjunto de comandos a seguir a partir da linha de comando na pasta do
projeto:
$ git init
$ heroku git:remote -a <nome-de-seu-aplicativo-heroku>
$ heroku buildpacks:set heroku/python
$ heroku config:set PORT=5004
$ git add .
$ git commit -am "deploy my bot"
$ git push heroku master
Se aparecer um erro de runtime após a implantação, a mensagem pode ser
esta:
ValueError: You may be trying to read with Python 3 a joblib pickle generated
with Python 2. This feature is not supported by joblib.
Isso ocorrerá principalmente se você estiver usando o Python versão 2.x.
Por padrão, o Heroku usa o Python versão 3.x. Se você quiser usar o
Python 2.x, terá de executar as etapas a seguir para corrigir o erro. Altere
Python 3.6 para Python-2.7.15.
Crie um arquivo [Link] no diretório raiz do aplicativo em seu projeto.
Abra o arquivo [Link], adicione a linha python-2.7.15 e salve-o. O
Heroku usará a versão de Python fornecida só para construir o seu projeto.
Após o término de uma implantação bem-sucedida, você verá uma url
fonecida pelo Heroku dizendo que o aplicativo foi implantado em <url>.
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Python app detected
remote: -----> Installing requirements with pip
remote:
remote: -----> Discovering process types
remote: Procfile declares types -> web
remote:
remote: -----> Compressing...
remote: Done: 254M
remote: -----> Launching...
remote: Released v17
remote: [Link] deployed to Heroku
remote:
remote: Verifying deploy... done.
To [Link]
cd3eb1b..c0e081d master -> master
A implantação demora um pouco, logo, seja paciente – o que você verá é
mágico. Se não aparecer nenhuma mensagem de erro, você implantou o
chatbot com sucesso na nuvem Heroku para fazê-lo funcionar com o
Facebook Messenger. Vejamos se funciona.
Verificando a implantação do aplicativo de gerenciamento de diálogo no Heroku
Para verificar se o aplicativo de gerenciamento de diálogo foi implantado
com sucesso no Heroku, executaremos as etapas a seguir.
1. Pegue a url fornecida pelo Heroku e acrescente a ela este endpoint:
/webhooks/facebook/webhook?
hub.verify_token=SEU_TOKEN_DE_VERIFICAÇAO&[Link]=successfully_verified.
Certifique-se de usar o token de verificação correto utilizado nas
definições de webhooks no Facebook. Minha url completa ficou assim:
[Link]
hub.verify_token=my-secret-verify-token&[Link]=success.
2. Vá até o navegador, cole a url inteira, e ele deve retornar o valor de
[Link] se hub.verify_token estiver correto. Sua url completa será:
[Link]
hub.verify_token=
SEU_TOKEN_DE_VERIFICAÇAO&[Link]=successsfully_verified.
Se você receber
a mensagem successsfully_verified in the browser, o aplicativo foi
implantado com sucesso e está funcionando.
Integrando o webhook ao Facebook
Voltaremos à configuração de nosso aplicativo do Facebook. Iremos até o
ponto em que paramos na Etapa 3 e adicionaremos a URL de callback.
Certifique-se de verificar as mensagens em Subscription Fields. Consulte a
Figura 5.10 como referência.
Figura 5.10 – Configuração de webhooks do Facebook Messenger.
Clique em Verify and Save. O Facebook confirmará o token de verificação
usando a url fornecida, que é a do servidor, ou informará que nosso
aplicativo só responderá a solicitações que tenham o token de verificação
correto. Se o token de verificação estiver correto, a assinatura do webhook
será ativada para o aplicativo.
Agora selecione a página para a qual cadastrará o webhook de eventos de
página na seção Webhooks. Clique em Subscribe (Figura 5.11).
Figura 5.11 – Cadastre o webhook para eventos da página do Facebook.
Terminamos! Hora de testar nosso Horoscope Bot no Facebook.
Verificação pós-implantação: chatbot do Facebook
Em cenários normais de desenvolvimento de software, as pessoas
constroem, testam e implantam o software e executam a verificação pós-
implantação (PDV, post-deployment verification). Também faremos algo
semelhante executando a PDV de nosso chatbot após a implantação bem-
sucedida no Facebook Messenger. Isso é importante porque, como você
aprendeu, o chatbot tem uma fase em que precisa se conectar ao servidor
de ações para responder a solicitações de intenção do usuário. A PDV é
como um teste de conformidade para vermos se, no geral, a integridade do
aplicativo é adequada. Se você estiver construindo um aplicativo que usa
de 10 a 15 APIS de diferentes fornecedores, é obrigatório verificar todos os
cenários em que o bot acessa o servidor de ações e utiliza as APIs para
retornar dados para o usuário.
Acesse seu aplicativo mensageiro ou o Facebook no navegador de seu
computador e procure o bot para começar a conversar.
As figuras 5.12.1 a 5.12.3 mostram o que meu Horoscope Bot faz e fala.
Figura 5.12.1 – Horoscope_Bot no Facebook.
Aí está! Nosso primeiro aplicativo de chatbot caseiro foi implantado na
web e pode ser acessado na plataforma do Facebook Messenger. Aproveite
e compartilhe-o com sua família, amigos, colegas e com o resto do mundo.
Figura 5.12.2 – Horoscope_Bot no Facebook.
Figura 5.12.3 – Horoscope_Bot no Facebook.
Implantando o chatbot no Slack
Nesta seção, implantaremos o chatbot no Slack, uma ferramenta de
colaboração muito popular entre desenvolvedores e corporações. Se você
não é uma pessoa adepta das mídias sociais, pode precisar da ajuda do
Slack para falar com seu chatbot usando uma interface. Passemos à
construção de nosso primeiro chatbot caseiro no Slack.
Para implantar nosso chatbot de horóscopo no Slack, escreveremos um
script independente como fizemos no caso do Facebook.
Criando um script independente para o chatbot do Slack
Crie um novo arquivo chamado [Link] no diretório de seu projeto. O
conteúdo do arquivo será o seguinte:
from rasa_core.[Link] import SlackInput
from rasa_core.agent import Agent
from rasa_core.interpreter import RasaNLUInterpreter
import os
from rasa_core.utils import EndpointConfig
# load your trained agent
interpreter = RasaNLUInterpreter("models/nlu/default/horoscopebot/")
MODEL_PATH = "models/dialogue"
action_endpoint = EndpointConfig(url="[Link]
[Link]/webhook")
agent = [Link](MODEL_PATH, interpreter=interpreter,
action_endpoint=action_endpoint)
input_channel = SlackInput(
slack_token="SEU_TOKEN_DO_SLACK",
# é o 'bot_user_o_auth_access_token'
slack_channel="SEU_CANAL_DO_SLACK"
# nome do canal no qual o bot conversará (opcional)
)
# configure serve_forever=True se quiser manter o servidor em execução
s = agent.handle_channels([input_channel], int([Link]('PORT', 5004)),
serve_forever=True)
A principal diferença entre [Link] e [Link] é o objeto input_channel que
criamos. O Rasa fornece vários canais internos como o do Facebook, Slack,
Mattermost, Telegram, Twilio, RocketChat e Microsoft Bot Framework,
que podemos usar diretamente para implantar com facilidade o mesmo bot
em vários canais.
Como você pode ver, precisamos adicionar um slack_token e um slack_channel
ao nosso script. Como tivemos de criar um aplicativo na plataforma de
desenvolvedor do Facebook, também teremos de criar um aplicativo no
Slack.
Faremos isso passo a passo:
1. Acesse a url [Link] e clique no botão Create App.
Veja a Figura 5.13.
Figura 5.13 – Criando um aplicativo no Slack.
2. A próxima etapa é criar um usuário do bot. Para criá-lo, clique em Bots
sob Add features and functionality. Na nova página, você verá a opção Add a Bot
User. Consulte a Figura 5.14 para ver como adicionar detalhes e um
usuário do bot.
Figura 5.14 – Dando um nome para seu bot no Slack.
3. Forneça os detalhes de acordo com o chatbot que está construindo.
Para o nome de exibição você pode usar o que quiser; o nome de
usuário padrão tem de ser exclusivo; deixe-o como está. A ativação da
última opção Always show my bot as online sempre exibirá o bot como
disponível para o usuário. É para isso que os chatbots existem – os
humanos não podem estar disponíveis 24 horas nos 7 dias da semana,
mas os chatbots podem, logo, ativaremos esse recurso. Certifique-se de
clicar para salvar as alterações.
4. Volte à aba Basic Information. Clique em Install your app to your workspace. O
aplicativo pedirá a confirmação da identidade. Autorize-a como faria
para qualquer aplicativo. Veja a Figura 5.15 que mostra como será a
autorização.
Figura 5.15 – Autorizando seu aplicativo do Slack.
Você verá a aba Bots and Permissions sob Add features and functionality com uma
marca de seleção verde, o que significa que o bot e o aplicativo estão
integrados. É um sinal de que até agora fizemos tudo certo.
5. Vá até a seção OAuth & Permissions e copie Bot User OAuth Access Token.
6. Cole o token que copiou no script Python [Link]. Forneça o nome de
canal que quiser. Se você quiser que seu bot converse em um canal,
forneça seu nome. Forneci @slackbot. Se você não configurar o
argumento de palavra-chave slack_channel, as mensagens serão
retornadas para o usuário que as enviou.
Editando seu procfile
Nessa etapa, não criaremos um procfile novo, já que estamos trabalhando
com a mesma base de código. Alteraremos o Procfile existente para o
descrito a seguir para fazê-lo funcionar para o bot do Slack. Mudaremos
apenas o nome do arquivo de script de [Link] para [Link] a fim de que
o Heroku use o arquivo fornecido para iniciar a aplicação.
web: python -m spacy download en && python [Link]
Implantação final do bot do Slack no Heroku
Para implantar nosso novo bot do Slack no Heroku, executaremos na linha
de comando um conjunto de comandos semelhantes aos que já usamos e
implantaremos a aplicação.
$ git init
$ heroku git:remote -a <nome-de-seu-aplicativo-do-heroku>
$ git add .
$ git commit -am "deploy my bot"
$ git push heroku master
Inscreva-se em eventos do Slack
Clique na aba Event Subscriptions e ative a funcionalidade de assinaturas de
eventos alterando o botão para o estado de ativação na tela. Insira a url de
webhook do aplicativo do Heroku para o Slack.
Se o aplicativo foi implantado no Heroku apropriadamente com o procfile
modificado, a url do webhook para o Slack será app_url +
/webhooks/slack/webhook e ficará assim:
[Link]
Você verá uma marca de seleção verified após o Slack enviar uma solicitação
HTTP POST para a URL citada com um parâmetro challenge, e nosso
endpoint deve responder com um valor para o desafio. Isso é semelhante
ao que discutimos ao construir o token secreto do chatbot do Facebook.
Consulte a Figura 5.16 para saber mais.
Figura 5.16 – Ative assinaturas de eventos para seu bot.
Inscreva-se em eventos do bot
Nessa etapa, apenas rolaremos para baixo na página de assinaturas de
eventos, iremos até a seção Subscribe to Bot Events e clicaremos em Add Bot User
Event. Use a Figura 5.17 como referência para saber para onde deve navegar.
Figura 5.17 – Inscreva-se em eventos do bot.
Assinar eventos do bot é apenas declarar os eventos aos quais o bot deve
responder. Demonstraremos somente dois cenários aqui: em primeiro
lugar, quando alguém menciona o nome do bot (isto é, app_mention), e, em
segundo lugar, quando alguém envia diretamente uma mensagem ao bot
([Link]).
Clique em salvar alterações e terá terminado. É hora de testarmos nosso
chatbot do Slack como fizemos na seção anterior para o Facebook.
Verificação pós-implantação: bot do Slack
Acesse o workspace que usamos para criar o aplicativo, e, sob Apps no lado
esquerdo, você encontrará seu bot. Tente conversar com ele e veja se
funciona bem. Meu bot se saiu muito bem para fornecer o horóscopo de
hoje, que foi fácil de ler. Se não conseguiu chegar até esse ponto, examine a
Figura 5.18 para ver como meu bot do Slack respondeu.
Figura 5.18 – Testando o chatbot do Slack.
Bem, terminamos nosso bot do Slack. Na próxima seção, implantaremos o
bot em nossa própria UI. Construir uma UI pode requerer algumas
habilidades de front-end, mas não se preocupe – temos planos para isso.
Implantando o chatbot por sua própria conta
O título é descolado, não? Até agora, implantamos nosso chatbot na web
usando o Facebook ou o Slack, ou poderíamos ter usado o Telegram etc.,
mas é hora de implantarmos tudo por nossa própria conta – nossos
próprios servidores, nossos próprios dados e nosso próprio modelo usando
nossa própria interface de usuário. Se você estiver em uma empresa ou for
um empreendedor iniciante, talvez possa implantar sua ideia no Facebook,
Twitter ou Slack, mas o ideal é que ela funcione em seu site para que o
valor da marca cresça à medida que a base de usuários aumenta.
Nesta seção, usaremos todo o trabalho pesado que fizemos até agora para
finalmente construir um chatbot totalmente funcional e independente de
qualquer chamada de API de terceiros ou ferramentas como o Dialogflow,
[Link], Watson etc. Você terá controle total para ajustar seu chatbot da
maneira que quiser e, o que é mais importante, escalá-lo facilmente para
milhões de pessoas.
Mãos à obra.
A primeira etapa é assegurar que os dois aplicativos que desenvolvemos nas
seções anteriores estejam ativos e funcionando. Você já sabe como fazer
uma verificação de conformidade básica. É preciso que o aplicativo
gerenciador de diálogo e o aplicativo de ações estejam sempre em execução
para que você use o modelo do chatbot em qualquer plataforma.
No mesmo diretório de projeto em que criamos [Link] e [Link],
geraremos um novo arquivo chamado myown_chatbot.py. Os scripts criados
anteriormente, como [Link] e [Link], são scripts independentes que
criamos para informar ao Heroku em um comando qual deles deve ser
executado para acionar a aplicação. Agora estamos criando nosso próprio
script que exporá a solicitação/resposta entre um usuário e o chatbot por
intermédio de APIs REST.
A implantação de seu próprio chatbot terá duas partes. Na primeira,
escreveremos um script para criar um canal personalizado e implantá-lo
como API REST. Na segunda, precisaremos de nossa própria UI porque,
até agora, usamos telas de chat do Facebook e do Slack para as conversas.
Escrevendo um script para o canal de seu próprio chatbot
Esse script é semelhante aos que estudamos e criamos até agora, mas temos
de sobrepor alguns dos métodos existentes de rasa_core para podermos
definir nossa própria regra para autenticação de API. Fiz a verificação de
string básica para comprovação do token no código a seguir. Isso não é
recomendável para sistemas de nível de produção, logo, certifique-se de
criar essa parte com cuidado se estiver construindo um chatbot para
sistemas maiores.
Crie um novo arquivo chamado myown_chatbot.py e adicione a ele o conteúdo
a seguir:
import os
from rasa_core.channels.rasa_chat import RasaChatInput
from rasa_core.agent import Agent
from rasa_core.interpreter import RasaNLUInterpreter
from rasa_core.utils import EndpointConfig
# carrega o agente treinado
interpreter = RasaNLUInterpreter("models/nlu/default/horoscopebot/")
MODEL_PATH = "models/dialogue"
action_endpoint = EndpointConfig(url="[Link]
[Link]/webhook")
agent = [Link](MODEL_PATH, interpreter=interpreter,
action_endpoint=action_endpoint)
class MyNewInput(RasaChatInput):
def _check_token(self, token):
if token == 'mysecret':
return {'username': 1234}
else:
print("Failed to check token: {}.".format(token))
return None
input_channel = MyNewInput(url='[Link]
# configure serve_forever=True se quiser manter o servidor em execução
s = agent.handle_channels([input_channel], int([Link]('PORT', 5004)),
serve_forever=True)
Alguns pontos devem ser observados aqui:
• O método _check_token de rasa_core é como o descrito a seguir, que faz
uma chamada de API para obter o objeto de usuário. Sua tarefa
principal é a autenticação de nível de usuário. No método sobreposto
anterior, simplificamos seu conteúdo para fazê-lo funcionar e entender
seu uso.
def _check_token(self, token):
url = "{}/users/me".format(self.base_url)
headers = {"Authorization": token}
[Link]("Requesting user information from auth server {}."
«».format(url))
result = [Link](url,
headers=headers,
timeout=DEFAULT_REQUEST_TIMEOUT)
if result.status_code == 200:
return [Link]()
else:
[Link]("Failed to check token: {}. "
"Content: {}".format(token, [Link]))
return None
• O uso do método _check_token do Rasa requer a criação de uma API ou
web service que aceite a solicitação e retorne a resposta da maneira
especificada.
• Certifique-se de alterar o endpoint do servidor de ações para sua
própria url.
• Lembre-se de que a string mysecret do código será usada para fazermos
chamadas de API posteriormente.
Criando o procfile e implantando-o na web
Você já deve estar familiarizado com a criação de procfiles para
implantação no Heroku. Usaremos novamente nosso procfile, com
modificações, para implantar o chatbot baseado em API na web. Crie um
novo procfile após criar backups dos existentes.
O conteúdo a seguir é do meu procfile:
web: python -m spacy download en && python myown_chatbot.py
Ao terminar, execute o conjunto de comandos a seguir que conhecemos ao
implantar o bot do Facebook Messenger e do Slack.
$ git init
$ heroku git:remote -a <nome-do-seu-aplicativo-do-heroku>
$ git add .
$ git commit -am "deploy my bot"
$ git push heroku master
Após o último comando, você verá alguns logs do Heroku relacionados à
versão da implantação, alterações feitas no aplicativo etc.
Verificando as APIs de seu chatbot
Após ver uma mensagem de implantação bem-sucedida, verificaremos se as
APIs do chatbot estão ou não funcionando. Para fazer o teste de
conformidade rapidamente, acesse a seguinte url:
<url-de-seu-aplicativo-básico>+/webhooks/rasa/
Exemplo:
[Link]
A abertura dessa url em seu navegador deve exibir uma resposta como a
mostrada a seguir. Se o status fornecido for "ok", você está pronto para
continuar – apenas sente-se, relaxe e depure.
{"status":"ok"}
Às vezes, só essa verificação não é suficiente, logo, faremos um teste real
tentando verificar se o chatbot está funcionando para identificar as
intenções e dando respostas com base nelas.
Usarei a ferramenta POSTMAN (o POSTMAN é uma ferramenta baseada
em GUI muito interessante para execução do teste de API). Você pode usar
qualquer ferramenta com a qual se sinta confortável. Vamos testar apenas
uma das intenções que nosso chabot deve entender e a qual deve
responder. Testei a intenção de saudação e ela funcionou perfeitamente. O
bot retornou a resposta esperada como mostrado na Figura 5.19.
Figura 5.19 – Testando a API do chatbot no POSTMAN.
Criando a UI do chatbot
Conforme discutimos, como parte da segunda etapa precisamos ter nossa
própria UI para fornecer um local amigável para a conversa entre o chatbot
e o usuário. Se você é desenvolvedor front-end ou tem um na equipe, pode
fornecer facilmente para o chatbot as APIs que construímos até agora, e a
equipe de front-end deve conseguir integrá-las à UI. Eles podem fazer uso
de chamadas HTTP comuns para utilizar essas APIs. Os websockets são
uma maneira melhor de construir chatbots, mas sua explicação não faz
parte do escopo deste livro.
Se você não está familiarizado com tecnologias front-end como
HTML/CSS/Javascript, recomendo a leitura de Pro HTML5 with CSS,
JavaScript, and Multimedia (Apress, 2017).
A fim de simplificar para nosso leitor – ou deveria dizer, aprendiz –,
criamos uma UI básica necessária para a conversa entre o chatbot e o
usuário. Você encontrará o código funcional inteiro no site do github ou da
Apress. Mostrarei apenas a configuração requerida para fazê-lo funcionar
para seu bot.
Após baixar o código deste capítulo, você encontrará uma pasta dentro da
pasta principal chamada my_own_chatbot. Abra-a e acesse assets -> js ->
[Link].
Altere a linha de código JavaScript a seguir inserindo a url de seu endpoint.
Se o nome de seu aplicativo for diferente, a url também será no seu caso.
Use sua própria url com o token no código JavaScript como mostrado na
url do exemplo.
var baseUrl = "[Link]
token=SUA-SENHA";
Salve o arquivo, abra [Link] no navegador e verá facilmente a UI do
chatbot pronta. No entanto, fazer chamadas de API a partir de HTML
simples sendo servido localmente traz um problema de compartilhamento
de recursos com origens diferentes (CORS, cross-origin resource sharing).
Para evitar essa situação, alteraremos um pouco myown_chatbot.py para servir
o HTML a partir do aplicativo no Heroku.
Altere myown_chatbot.py para o descrito a seguir e discutiremos as mudanças
feitas.
import os
from rasa_core.channels.rasa_chat import RasaChatInput
from rasa_core.[Link] import CollectingOutputChannel, UserMessage
from rasa_core.agent import Agent
from rasa_core.interpreter import RasaNLUInterpreter
from rasa_core.utils import EndpointConfig
from rasa_core import utils
from flask import render_template, Blueprint, jsonify, request
# carrega o agente treinado
interpreter = RasaNLUInterpreter("models/nlu/default/horoscopebot/")
MODEL_PATH = "models/dialogue"
action_endpoint = EndpointConfig(url="[Link]
[Link]/webhook")
agent = [Link](MODEL_PATH, interpreter=interpreter,
action_endpoint=action_endpoint)
class MyNewInput(RasaChatInput):
@classmethod
def name(cls):
return "rasa"
def _check_token(self, token):
if token == 'secret':
return {'username': 1234}
else:
print("Failed to check token: {}.".format(token))
return None
def blueprint(self, on_new_message):
templates_folder =
[Link]([Link]([Link](__file__)), 'myown_chatbot')
custom_webhook = Blueprint('custom_webhook', __name__, template_folder =
templates_folder)
@custom_webhook.route("/", methods=['GET'])
def health():
return jsonify({"status": "ok"})
@custom_webhook.route("/chat", methods=['GET'])
def chat():
return render_template('[Link]')
@custom_webhook.route("/webhook", methods=['POST'])
def receive():
sender_id = self._extract_sender(request)
text = self._extract_message(request)
should_use_stream = utils.bool_arg("stream", default=False)
if should_use_stream:
return Response(
self.stream_response(on_new_message, text, sender_id),
content_type='text/event-stream')
else:
collector = CollectingOutputChannel()
on_new_message(UserMessage(text, collector, sender_id))
return jsonify([Link])
return custom_webhook
input_channel = MyNewInput(url='[Link]
# configure serve_forever=True se quiser manter o servidor em execução
s = agent.handle_channels([input_channel], int([Link]('PORT', 5004)),
serve_forever=True)
Estas são alterações que fizemos:
• Sobrepusemos os métodos name e blueprint em nossa classe, o que nos
permite criar nosso próprio endpoint e também nos dá a liberdade de
definir como ele deve se comportar.
• Criamos um novo endpoint/chat e servimos o arquivo [Link], que é
apenas a UI do chatbot. Logo, esse será o link inicial de nosso chatbot.
• Tivemos de importar algumas classes e métodos necessários, como
utils, CollectingOutputChannel e UserMessage, requeridos para fazer tudo
funcionar.
Salve o arquivo e implante as alterações novamente no aplicativo do
Heroku usando os seguintes comandos:
$ git add .
$ git commit -am "deploy my bot"
$ git push heroku master
Após a implantação bem-sucedida – aí está! Nosso bot está pronto para ser
compartilhado com o resto do mundo funcionando com dois aplicativos
no Heroku: uma para o gerenciamento de diálogo e o outro para as ações.
Abra a url a seguir no navegador onde verá nossa UI de chatbot
personalizada:
[Link]
As figuras 5.20.1 e 5.20.2 mostram a aparência de meu chatbot durante a
conversa.
Figura 5.20.1 – Chatbot personalizado em meu próprio site.
Figura 5.20.2 – Chatbot personalizado em meu próprio site.
Usando os recursos de nome de domínio personalizados do Heroku,
qualquer um pode apontar facilmente o mesmo aplicativo para o nome de
seu site, como [Link]. Faça isso quando achar que seu chatbot está
suficientemente bom para ser aberto para o resto do mundo com fins
lucrativos ou não.
Isso é tudo! É assim que os chatbots são construídos com Python usando
Natural Language Processing e machine learning. Espero que este capítulo
e os anteriores tenham sido úteis e você tenha aprendido a abordagem
prática de conhecimento e construção dos chatbots.
Resumo
Neste capítulo, aprendemos a implantar nosso próprio aplicativo em
nossos próprios servidores usando o Heroku. Aprendemos a integrar o
chatbot ao Facebook usando a plataforma de desenvolvedores. Também
aprendemos a criar um chatbot personalizado para um aplicativo do Slack
e o testamos. Para concluir, como prometido no fim do Capítulo 3,
removendo todas as dependências de plataformas de mídia social, criamos
nossa própria UI, a implantamos no Heroku e a testamos. Vimos que ela
funciona perfeitamente – funcionou enquanto a treinávamos. Já que temos
um modelo básico funcionando, você pode manipular casos em que o
chatbot não esteja funcionando bem. Determine se é um problema
relacionado a dados ou a treinamento, ao servidor de ações ou à
manipulação de código personalizado. Ao descobrir o caso raiz, corrija-o,
implante novamente e verifique se o chatbot melhorou. Construímos
grandes programas começando pequeno.
Estou ansioso para ter notícias suas e curioso para saber que chatbot
construiu após ler o livro. Ficarei feliz em ajudá-lo a qualquer momento se
você tiver problemas com algum conceito, com a execução do código ou
com a implantação.
Obrigado.