Olá Pessoas Ingriveis Desse Site, Hoje o artgo vai tratar de um assunto que está muito em alta: чат -боты!
Para amecar, vamos pensar na forma que que quegimos com wutros seres humos o que seria do mundo se não searsise a comunicação, desde o o avanço da tecnologia vem afetando a forma como essa comunicação é feita, por exemplo, é tão fácil confuringarmos компонент О. Амигос АТРЕВЕСА ДЕПАС ДЕР МЕНСАГЕНС, НАО? Esse avanço não só afeta a forma que nos comunicamos com вереса, como também a forma que comunicamos com as máquinas, à medida que avançamos, o modo comunicamos com osquis vai se aproximando do Quarty ore que que que que que que que que que que que quesquis Computacional Chamado PLN (NLP, Do Do INGLês Eartual Language обработка), Out Processamento de linguagem Natural. Esse Campo de Pesquisa estuda Como Fazer A Maquina insed a nossa língua escrita, de uma forma que o comportador consiga invend ascrita sem conteúdo defineido por programadores e vamos fazer essa replainaço! CorporaCões, nós do Luizalabs USAMOS ESSES SOFTWARES POR NOS PORTORCIONAREM UMA COMUNICAçAO MAIS Humanizada E Fluída Com O Cliente, Mas Para O Pequeno usuário, Que Talvez Queira Criar Ум, бот, симул GitHub Анкет
Vamos instalar?
Para amecar, é reveliefio Que você tenha uma versão nevale do python e pip instalados no seu computador, логотип Mais, Vamos instalar в качестве Seguintes bibliotecas:
pip install nltk pip install numpy pip install keras pip install tensorflow
- Nltk – é Uma das Ferramentas mais utilizadas para paraamento de linguagem natural, foi desenvolvida em python e teme uma gama muito grande de recursos, como: classificação, tokenização, Stemming, Tagging, Parsing E Raciocínio semânticoCoico. Todas Essas Funcões são utilizadas para análise de texto;
- Numpy – é uma biblioteca para a linguagem python com funcões para se Trabalhar Com Computação Numérica, E Que Pode Realizar Operações de Algebra Linear de Maneira Muito eficiente;
- Керас – Por último, E De Extrema Importância, Usamos O Керас Пара Эстртура де Апрендизадо Профундо, Эсса Либ Подеросиссима и Ума Дас Принцип Апис де Родирует Neurais de Alto Nível.
Seria Interessante vocês darem uma lida em como essas bibliotecas funcionam para para melhor o nosso código, apesar que vou emdo o decorrer da infulação.
Вамос Ла Энтао, Криаремос Носсо Диционарио де намерения , Quando falamos em intenções em Chatbot, falamos sobre o Intuito do usuário ao escrever tal texto. Nosso json irá conter a тег que define o que é aquela intenção, os шаблоны que serão os exemplos de mensagens enviadas, os ответы Que Säo OS обратной связи Enviados pelo bot e o контекст , SE Quisermos USAR Manipulação de Contexto de Mensagens:
{ "intents": [ { "tag": "welcome", "patterns": ["Oi", "bom dia", "boa tarde", "boa noite", "good morning", "Hi", "hello", "Olá"], "responses": ["Olá, eu sou sua assistente virtual, em que posso te ajudar?"], "context": [""] }, { "tag": "who_are_you", "patterns": ["qual seu nome?", "quem é você?", "como você chama?", "nome?"], "responses": ["Eu sou uma assistente virtual, ainda não tenho nome."], "context": [""] }, { "tag": "love", "patterns": ["te amo", "linda", "querida", "casa comigo?", "maravilhosa"], "responses": ["Awwwn, muito obrigada <3"], "context": [""] }, { "tag": "censored", "patterns": ["feia", "boba", "chata", "vai pro inferno", "puta", "quer casar comigo?", "sua gostosa"], "responses": ["Não toleramos nenhum tipo de assédio."], "context": [""] }, { "tag": "thanks", "patterns": ["obrigada", "tks", "thank you", "valeu", "obrigada pela ajuda", "muito obrigada"], "responses": ["De nada ;)", "Agradeço seu contato, volte sempre!"], "context": [""] }, { "tag": "anything_else", "patterns": [], "responses": ["Desculpa, não entendi o que você falou, tente novamente!"], "context": [""] } ] }
Treinando e Criando nosso modelo
Agora, Vamos Criar O Arquivo train.py , Onde vamos ter o código para ler os dados de linguagem natural e usar rede нервного сексуального последовательного модель . Нессе Кодиго Вамос Дивидир Явность Альгумас Партс, Пара Фасилитара O Intendimento. Realizamos a Importação E Configuração Inicial Das Libs Que Iremos utilizar:
import json import pickle import nltk import random import numpy as np from nltk.stem import WordNetLemmatizer from keras.models import Sequential from keras.layers import Dense, Activation, Dropout from keras.optimizers import SGD nltk.download('punkt') nltk.download('wordnet') lemmatizer = WordNetLemmatizer()
Inicializamos nossa dista de palavras, классы, документы E Definimos Quais palavras Serão INSORADAS, Percorremos a Nossa Lista de intenções, Que foram lidas pelo código e com jjuda do nltk fazemos a Tokenização DOS Patterns E Adicionamos na lista de palavras, adicionamos também aos documentos Para Termos Adinificação da Tag para cada palavra e adicionamos как теги nossa lista de classe:
# inicializaremos nossa lista de palavras, classes, documentos e # definimos quais palavras serão ignoradas words = [] documents = [] intents = json.loads(open('intents.json').read()) # adicionamos as tags em nossa lista de classes classes = [i['tag'] for i in intents['intents']] ignore_words = ["!", "@", "#", "$", "%", "*", "?"] # é feita a leitura do arquivo intents.json e transformado em json intents = json.loads(open('intents.json').read()) # percorremos nosso array de objetos for intent in intents['intents']: for pattern in intent['patterns']: # com ajuda no nltk fazemos aqui a tokenizaçao dos patterns # e adicionamos na lista de palavras word = nltk.word_tokenize(pattern) words.extend(word) # adiciona aos documentos para identificarmos a tag para a mesma documents.append((word, intent['tag']))
Em Seguida, Vamos Lematizar, Ou Seja, Transformar As Palavras EM SEUS TARGINADOS Básicos, Com O objetivo de Restringir Tudo ao nível mais simples osplyvel. Um exemplo de lematização ocorre com verbos, tipo, escrevendo, escreveu e escreve tem o mesmo lema que é escrever. Логотип, Classificamos nossas listas e estamos prontos para construir o modelo de aprendizado profundo.
# lematizamos as palavras ignorando os palavras da lista ignore_words words = [lemmatizer.lemmatize(w.lower()) for w in words if w not in ignore_words] # classificamos nossas listas words = sorted(list(set(words))) classes = sorted(list(set(classes))) # salvamos as palavras e classes nos arquivos pkl pickle.dump(words, open('words.pkl', 'wb')) pickle.dump(classes, open('classes.pkl', 'wb'))
Vamos gomes nosso treinamento criando um array vazio de treinamento e criando uma de saídas vazias de acordo com o tamanho das nossas классы. Percorremos nossos Docuctos, Inicializamos Um Array de сумка Vazio, inserimos no nosso pattern_word NOSSA PALAVRA CORPROPENTERE AQUELE PADROAO, LEMATIZAMOS CADA UMA DELAS NA TENTATIVA DE PALAVRAS RELACIONADAS, INSERIMOS 1 Нет сумки SE CORPECTENCIA DE PALAVRAS для Encontrada No Pattern Atual Etilizamos O output_row Como Uma Chave Para A Lista, Onde A Saída Será 0 Para Cada Tag e 1 Para tag. Após Esso Embaralhamos Nosso Concunto de Treinamentos, Transformamos em Numpy Array e Definimos uma lista de treinos, Sendo x os e y e y intenções:
# inicializamos o treinamento training = [] output_empty = [0] * len(classes) for document in documents: # inicializamos o saco de palavras bag = [] # listamos as palavras do pattern pattern_words = document[0] # lematizamos cada palavra # na tentativa de representar palavras relacionadas pattern_words = [lemmatizer.lemmatize( word.lower()) for word in pattern_words] # criamos nosso conjunto de palavras com 1, # se a correspondência de palavras for encontrada no padrão atual for word in words: bag.append(1) if word in pattern_words else bag.append(0) # output_row atuará como uma chave para a lista, # onde a saida será 0 para cada tag e 1 para a tag atual output_row = list(output_empty) output_row[classes.index(document[1])] = 1 training.append([bag, output_row]) # embaralhamos nosso conjunto de treinamentos e transformamos em numpy array random.shuffle(training) training = np.array(training) # criamos lista de treino sendo x os patterns e y as intenções x = list(training[:, 0]) y = list(training[:, 1])
Com Nossos Dados de Treinamento Prontos, Usaremos O Modelo de Aprendizado Propundo Keras Chamado Sequencial , Esse modelo sequencial é Uma das пересматривает Neurais mais simples, um pesptron multicamadas, que em comm 3 camadas, com a primeira tendo 128 Neurenios, Segunda 64 E terceira tendo o número de intensees o número de nuerônios, objetivo des é tentar Prever Qual Base Escolher de Acordo Com Alguns Дадос. Esse Modelo Será Treinado Com Descida Gradiente Estocástica Que é Um Tópico Beeeem Complexo, Mas Que Tem Muito Conteúdo no senhor Google e no Link isponibilizado. Depois que nosso modelo é treinado será salvo no Model.h5 Como Numpy Array E é Com Esse Modelo Que Vamos Criar Nossa Gui Do Chatbot.
# Criamos nosso modelo com 3 camadas. # Primeira camada de 128 neurônios, # segunda camada de 64 neurônios e terceira camada de saída # contém número de neurônios igual ao número de intenções para prever a intenção de saída com softmax model = Sequential() model.add(Dense(128, input_shape=(len(x[0]),), activation='relu')) model.add(Dropout(0.5)) model.add(Dense(64, activation='relu')) model.add(Dropout(0.5)) model.add(Dense(len(y[0]), activation='softmax')) # O modelo é compilado com descida de gradiente estocástica # com gradiente acelerado de Nesterov. # A ideia da otimização do Momentum de Nesterov, ou Nesterov Accelerated Gradient (NAG), # é medir o gradiente da função de custo não na posição local, # mas ligeiramente à frente na direção do momentum. # A única diferença entre a otimização de Momentum é que o gradiente é medido em θ + βm em vez de em θ. sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True) model.compile(loss='categorical_crossentropy',optimizer=sgd, metrics=['accuracy']) # ajustamos e salvamos o modelo m = model.fit(np.array(x), np.array(y), epochs=200, batch_size=5, verbose=1) model.save('model.h5', m) print("fim")
Reseaindo os dados e criando nossa interface (gui)
Vamos Criar UM Arquivo Extract.py Para Extrair Os Dados E LiDAR Com As Previsões E, вероятно, Das Mensagens Em Concunto Com O Modelo Treinado E Um Arquivo Chamado Bot.py que será a nossa interface gráfica. Nosso arquivo экстракт Tem 4 Funcões, Sendo Essas:
- четкое письмо que é a responseavel por limpar as sentenças inseridas, ou seja, fazer a higienizção da mensagem enviada pelo usuário
- BAG_OF_WORDS é A Funcáo oucteravel por criar um pacote de palavras que será usado para как previsões.
- class_prediction faz a previsão do pacote de palavras, usamos como limite de erro 0,25 para evitarmos, переосмысливая e classificamos esces restudados por força da prosebilidade;
- get_response é A Funcáo Que vamos usar depois que fizermos todo o processo acima, com nosso retorno de intenção, verificamos Qual as Mensagens de retorno do json, usamos o Случайный Paramos apenas uma resposta da lista.
import random import numpy as np import pickle import nltk from nltk.stem import WordNetLemmatizer lemmatizer = WordNetLemmatizer() words = pickle.load(open('words.pkl', 'rb')) classes = pickle.load(open('classes.pkl', 'rb')) def clear_writing(writing): """ Limpa todas as sentenças inseridas. """ #tokeniza todas as setenças das frases inseridas, lematiza cada uma delas e retorna sentence_words = nltk.word_tokenize(writing) return [lemmatizer.lemmatize(word.lower()) for word in sentence_words] # return bag of words array: 0 or 1 for each word in the bag that exists in the sentence def bag_of_words(writing, words): """ Pega as sentenças que são limpas e cria um pacote de palavras que são usadas para classes de previsão que são baseadas nos resultados que obtivemos treinando o modelo. """ # tokenize the pattern sentence_words = clear_writing(writing) # cria uma matriz de N palavras bag = [0]*len(words) for setence in sentence_words: for i, word in enumerate(words): if word == setence: # atribui 1 no pacote de palavra se a palavra atual estiver na posição da setença bag[i] = 1 return(np.array(bag)) def class_prediction(writing, model): """ Faz a previsao do pacote de palavras, usamos como limite de erro 0.25 para evitarmos overfitting e classificamos esses resultados por força da probabilidade. """ # filtra as previsões abaixo de um limite 0.25 prevision = bag_of_words(writing, words) response_prediction = model.predict(np.array([prevision]))[0] results = [[index, response] for index, response in enumerate(response_prediction) if response > 0.25] # verifica nas previsões se não há 1 na lista, se não há envia a resposta padrão (anything_else) # ou se não corresponde a margem de erro if "1" not in str(prevision) or len(results) == 0 : results = [[0, response_prediction[0]]] # classifica por força de probabilidade results.sort(key=lambda x: x[1], reverse=True) return [{"intent": classes[r[0]], "probability": str(r[1])} for r in results] def get_response(intents, intents_json): """ pega a lista gerada e verifica o arquivo json e produz a maior parte das respostas com a maior probabilidade. """ tag = intents[0]['intent'] list_of_intents = intents_json['intents'] for idx in list_of_intents: if idx['tag'] == tag: # caso as respostas sejam um array contendo mais de uma, # usamos a função de random para pegar uma resposta randomica da nossa lista result = random.choice(idx['responses']) break return result
Por Fim, Vamos Criar Nossa Interface Gráfica utilizando o módulo tkinter Сделай питон, Que é UM Toolkit Padrão Para CrioCão de gui. Para não extender muito e visto que esse módulo tem uma documentaço muito boa, vou deixar o código com os comentários do que fiz para criar. Интерфейс:
import json import tkinter from tkinter import * from extract import class_prediction, get_response from keras.models import load_model # extraimos o modelo usando o keras model = load_model('model.h5') # carregamos nossas intenções intents = json.loads(open('intents.json').read()) base = Tk() base.title("Chatbot") base.geometry("400x500") base.resizable(width=FALSE, height=FALSE) def chatbot_response(msg): """ Resposta do bot """ ints = class_prediction(msg, model) res = get_response(ints, intents) return res def send(): """ Envia a mensagem """ msg = EntryBox.get("1.0", 'end-1c').strip() EntryBox.delete("0.0", END) if msg != '': Chat.config(state=NORMAL) Chat.insert(END, f"Você: {msg}\n\n") Chat.config(foreground="#000000", font=("Arial", 12)) response = chatbot_response(msg) Chat.insert(END, f"Bot: {response}\n\n") Chat.config(state=DISABLED) Chat.yview(END) # Cria a janela do chat Chat = Text(base, bd=0, bg="white", height="8", width="50", font="Arial",) Chat.config(state=DISABLED) # Vincula a barra de rolagem à janela de bate-papo scrollbar = Scrollbar(base, command=Chat.yview) Chat['yscrollcommand'] = scrollbar.set # Cria o botão de envio de mensagem, onde o comando envia para a função de send SendButton = Button(base, font=("Verdana", 10, 'bold'), text="Enviar", width="12", height=2, bd=0, bg="#666", activebackground="#333", fg='#ffffff', command=send) # Cria o box de texto EntryBox = Text(base, bd=0, bg="white", width="29", height="2", font="Arial") # Coloca todos os componentes na tela scrollbar.place(x=376, y=6, height=386) Chat.place(x=6, y=6, height=386, width=370) EntryBox.place(x=128, y=401, height=50, width=260) SendButton.place(x=6, y=401, height=50) base.mainloop()
Executando Nosso Código
Antes de Exemare Nosso Código, Vamos Criar 3 Arquivos na Raiz do Projeto Model.h5 , words.pkl E Classe.pkl Анкет SE Você USA Windows, Terá Que Instalar um servidor wamado xming.
Vamos keyçar treinando nosso modelo e depois de treinado recemos nosso bot.py
python train.py
python bot.py
Бом, заключение Aqui Nosso Primeiro Chatbot, Estou Feliz de Poder Compartilhar Com Vocês. Esse Projeto por mais simples que seja nos da habilidades úteis para a ciência de dados, claro que tem muito chão para intendermos aprendizado profundo, mas estamos no caminho.
Госто? Entãa ae ao post e compartilhe com seus amigos para que eu eu продолжить trazendo conteúdo interessantes para ocês!
Оригинал: “https://dev.to/thaisribeiro/como-criar-um-bot-usando-deep-learning-e-python-2d55”