Tutorial: Construye tu primer chatbot usando NLTK y Keras

En este artículo, aprenderemos sobre chatbots usando Python y cómo crear chatbots en Python usando NLTK y Keras.

- , ,
tutorial-nltk-keras

¿Qué es un chatbot?

Un chatbot es una aplicación de software que se utiliza para llevar a cabo una conversación de chat en línea a través de texto o de texto a voz, en lugar de proporcionar contacto directo con un agente humano en vivo. Un chatbot es un tipo de software que puede automatizar conversaciones e interactuar con personas a través de plataformas de mensajería.

Los chatbots ahora son responsables de casi el 30% de todas las actividades. Las empresas utilizan los chatbots para brindar servicios como atención al cliente, generación de conocimiento y más.

Desarrollo de ChatBots para empresas

Creamos chatbots en WhatsApp, Facebook Messenger, Telegram...

Contáctanos en nuestra web

Tipos de chatbots

Los chatbots se pueden clasificar en tres tipos:

Tipos de chatbots

Chatbots simples

  • Los chatbots simples tienen capacidades limitadas y, por lo general, se les llama bots basados en reglas.
  • Son tareas específicas. Esto significa que el bot plantea preguntas basadas en opciones predeterminadas y el cliente puede elegir entre las opciones hasta que obtenga respuestas a su consulta.
  • Estos chatbots son los más adecuados para diálogos sencillos.
  • Son muy simples de construir y entrenar.
  • Ejemplo: pedir pizza.

Chatbots inteligentes

  • Los chatbots inteligentes habilitados para IA están diseñados para simular interacciones casi humanas con los clientes.
  • Pueden tener conversaciones fluidas y comprender la intención, el lenguaje y el sentimiento.
  • Estos chatbots requieren programación para ayudarlos a comprender el contexto de las interacciones.
  • Son mucho más difíciles de implementar y ejecutar y necesitan muchos datos para aprender.
  • Ejemplo: asistentes virtuales.

Chatbots híbridos

  • Son una combinación de chatbots simples e inteligentes.
  • Los chatbots híbridos se encuentran con ese término medio.
  • Los chatbots híbridos tienen algunas tareas basadas en reglas y pueden comprender la intención y el contexto.
  • Esto los convierte en una herramienta equilibrada para que las empresas interactúen con los clientes.
  • Ejemplo: diagnóstico médico.

¿Cómo hacer un chatbot en Python?

Para crear un chatbot en Python, debes tener un buen conocimiento de PythonKeras y el procesamiento del lenguaje natural (NLTK).

A continuación se muestran los 6 pasos para crear un chatbot en Python:

1. Instala los módulos necesarios, puedes instalar los módulos necesarios con la ayuda del comando python-pip

pip install tensorflow, keras, pickle, nltk

2. Importa y carga el archivo de datos

  • Crea intents.json. Así es como se ve nuestro archivo intents.json.

intents.json

  • Primero, crea un nombre de archivo como train_chatbot.py. Importamos los paquetes necesarios para nuestro chatbot e inicializamos las variables que usaremos en nuestro proyecto Python.
  • El archivo de datos está en formato JSON, por lo que usamos el paquete JSON para analizar el archivo JSON en Python.
import nltk  from nltk.stem import WordNetLemmatizer  lemmatizer = WordNetLemmatizer()  import json  import pickleimport numpy as np  from keras.models import Sequential  from keras.layers import Dense, Activation, Dropout  from keras.optimizers import SGD  import randomwords=[]  classes = []  documents = []ignore_words = ['?', '!']data_file = open('intents.json').read()  intents = json.loads(data_file)

3. Preprocesar datos

  • Cuando trabajamos con datos de texto, necesitamos realizar varios preprocesos en los datos antes de hacer un machine learning o un modelo de Deep learning. Según los requisitos, necesitamos aplicar varias operaciones para preprocesar los datos.
  • La creación de tokens es lo más básico y lo primero que puedes hacer con los datos de texto. La creación de tokens es el proceso de dividir todo el texto en partes pequeñas, como palabras.
  • Aquí iteramos a través de los patrones y tokenizamos la oración usando la función nltk.word_tokenize () y agregamos cada palabra en la lista de palabras. También creamos una lista de clases para nuestras etiquetas.
for intent in intents['intents']:   for pattern in intent['patterns']:   #tokenize each word   w = nltk.word_tokenize(pattern)   words.extend(w)#add documents in the corpus   documents.append((w, intent['tag']))   # add to our classes list   if intent['tag'] not in classes:   classes.append(intent['tag'])
  • Ahora lematizaremos cada palabra y eliminaremos las palabras duplicadas de la lista. Lematizar es el proceso de convertir una palabra en su forma de lema y luego crear un archivo pickle para almacenar los objetos de Python que usaremos al predecir.
# lemmatize, lower each word and remove duplicates  words = [lemmatizer.lemmatize(w.lower())  for w in words if w not in ignore_words]   words = sorted(list(set(words)))# sort classes  classes = sorted(list(set(classes)))# documents = combination between patterns and intents  print(len(documents), "documents")# classes = intents  print(len(classes), "classes", classes)# words = all words, vocabulary  print(len(words), "unique lemmatized words", words)  pickle.dump(words,open('words.pkl','wb'))  pickle.dump(classes,open('classes.pkl','wb'))

4. Crea datos de entrenamiento y prueba

  • Ahora, crearemos los datos de entrenamiento en los que proporcionaremos la entrada y la salida.
  • Nuestra entrada será el patrón y la salida será la clase a la que pertenece nuestro patrón de entrada. Pero la computadora no entiende el texto, así que convertiremos el texto en números.
# create our training data  training = []# create an empty array for our output  output_empty = [0] * len(classes)# training set, bag of words for each sentencefor doc in documents:   # initialize our bag of words   bag = []   # list of tokenized words for the pattern   pattern_words = doc[0]   # lemmatize each word - create base word, in attempt to represent related words   pattern_words = [lemmatizer.lemmatize(word.lower()) for word in pattern_words]# create our bag of words array with 1, if word match found in current pattern   for w in words:   bag.append(1) if w in pattern_words else bag.append(0)   # output is a '0' for each tag and '1' for current tag (for each pattern)   output_row = list(output_empty)   output_row[classes.index(doc[1])] = 1   training.append([bag, output_row])# shuffle our features and turn into np.array  random.shuffle(training)  training = np.array(training)# create train and test lists. X - patterns, Y - intents  train_x = list(training[:,0])  train_y = list(training[:,1])  print("Training data created")

5. Construye el modelo

  • Tenemos nuestros datos de entrenamiento listos, ahora construiremos una red neuronal profunda que tiene 3 capas. Usamos la API secuencial de Keras para esto.
  • Después de entrenar el modelo durante 200 épocas, logramos una precisión del 100% en nuestro modelo. Guardemos el modelo como “chatbot_model.h5”.
# Create model - 3 layers. First layer 128 neurons, second layer 64 neurons and 3rd output layer contains number of neurons  # equal to number of intents to predict output intent with softmax  model = Sequential()  model.add(Dense(128, input_shape=(len(train_x[0]),), activation='relu'))  model.add(Dropout(0.5))  model.add(Dense(64, activation='relu'))  model.add(Dropout(0.5))  model.add(Dense(len(train_y[0]), activation='softmax'))# Compile model. Stochastic gradient descent with Nesterov accelerated gradient gives good results for this model  sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)  model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])#fitting and saving the model   hist = model.fit(np.array(train_x), np.array(train_y), epochs=200, batch_size=5, verbose=1)  model.save('chatbot_model.h5', hist)  print("model created")

5. Predecir la respuesta (interfaz gráfica de usuario)

  • Para predecir las oraciones y obtener una respuesta del usuario que nos permita crear un nuevo archivo “chatapp.py”.
  • Cargaremos el modelo entrenado y luego usaremos una interfaz gráfica de usuario que predecirá la respuesta del bot. El modelo solo nos dirá la clase a la que pertenece, por lo que implementaremos algunas funciones que identificarán la clase y luego recuperaremos una respuesta aleatoria de la lista de respuestas.
  • Nuevamente importamos los paquetes necesarios y cargamos los archivos pickle “words.pkl” y “classes.pkl” que hemos creado cuando entrenamos nuestro modelo:
import nltk  from nltk.stem import WordNetLemmatizer  lemmatizer = WordNetLemmatizer()import pickle  import numpy as np  from keras.models import load_model  model = load_model('chatbot_model.h5')import json  import random  intents = json.loads(open('intents.json').read())  words = pickle.load(open('words.pkl','rb'))  classes = pickle.load(open('classes.pkl','rb'))
  • Para predecir la clase, necesitaremos proporcionar información de la misma manera que lo hicimos durante el entrenamiento. Entonces crearemos algunas funciones que realizarán el preprocesamiento de texto y luego predecirán la clase.
def clean_up_sentence(sentence):   # tokenize the pattern - split words into array   sentence_words = nltk.word_tokenize(sentence)   # stem each word - create short form for word   sentence_words = [lemmatizer.lemmatize(word.lower()) for word in sentence_words]   return sentence_words  # return bag of words array: 0 or 1 for each word in the bag that exists in the sentencedef bow(sentence, words, show_details=True):   # tokenize the pattern   sentence_words = clean_up_sentence(sentence)   # bag of words - matrix of N words, vocabulary matrix   bag = [0]*len(words)for s in sentence_words:   for i,w in enumerate(words):   if w == s:    # assign 1 if current word is in the vocabulary position   bag[i] = 1   if show_details:   print ("found in bag: %s" % w)   return(np.array(bag))def predict_class(sentence, model):   # filter out predictions below a threshold   p = bow(sentence, words,show_details=False)   res = model.predict(np.array([p]))[0]   ERROR_THRESHOLD = 0.25   results = [[i,r] for i,r in enumerate(res) if r>ERROR_THRESHOLD]   # sort by strength of probability   results.sort(key=lambda x: x[1], reverse=True)   return_list = []    for r in results:   return_list.append({"intent": classes[r[0]], "probability": str(r[1])})   return return_list
  • Después de predecir la clase, obtendremos una respuesta aleatoria de la lista de intenciones.
def getResponse(ints, intents_json):   tag = ints[0]['intent']   list_of_intents = intents_json['intents']   for i in list_of_intents:   if(i['tag']== tag):   result = random.choice(i['responses'])   break   return resultdef chatbot_response(text):   ints = predict_class(text, model)   res = getResponse(ints, intents)   return res
  • Ahora desarrollaremos una interfaz gráfica de usuario. Usemos la biblioteca Tkinter que se envía con toneladas de bibliotecas útiles para GUI.
  • Tomaremos el mensaje de entrada del usuario y luego usaremos las funciones auxiliares que hemos creado para obtener la respuesta del bot y mostrarla en la GUI. Aquí está el código fuente completo de la GUI.
#Creating GUI with tkinter  import tkinter  from tkinter import *def send():   msg = EntryBox.get("1.0",'end-1c').strip()   EntryBox.delete("0.0",END)   if msg != '':   ChatLog.config(state=NORMAL)   ChatLog.insert(END, "You: " + msg + '\n\n')   ChatLog.config(foreground="#442265", font=("Verdana", 12 ))   res = chatbot_response(msg)   ChatLog.insert(END, "Bot: " + res + '\n\n')   ChatLog.config(state=DISABLED)   ChatLog.yview(END)base = Tk()  base.title("Hello")  base.geometry("400x500")  base.resizable(width=FALSE, height=FALSE)  #Create Chat window  ChatLog = Text(base, bd=0, bg="white", height="8", width="50", font="Arial",)  ChatLog.config(state=DISABLED)  #Bind scrollbar to Chat window  scrollbar = Scrollbar(base, command=ChatLog.yview, cursor="heart")  ChatLog['yscrollcommand'] = scrollbar.set  #Create Button to send message  SendButton = Button(base, font=("Verdana",12,'bold'), text="Send", width="12", height=5, bd=0, bg="#32de97", activebackground="#3c9d9b",fg='#ffffff', command= send )#Create the box to enter message  EntryBox = Text(base, bd=0, bg="white",width="29", height="5", font="Arial")#EntryBox.bind("<Return>", send)  #Place all components on the screen  scrollbar.place(x=376,y=6, height=386)  ChatLog.place(x=6,y=6, height=386, width=370)  EntryBox.place(x=128, y=401, height=90, width=265)  SendButton.place(x=6, y=401, height=90)  base.mainloop()

6. Ejecuta el chatbot

  • Para ejecutar el chatbot, tenemos dos archivos principales; train_chatbot.py y chatapp.py.
  • Primero, entrenamos el modelo usando el comando en la terminal:
python train_chatbot.py
  • Si no vemos ningún error durante el entrenamiento, hemos creado el modelo correctamente. Luego, para ejecutar la aplicación, ejecutamos el segundo archivo.
python chatgui.py
  • El programa abrirá una ventana GUI en unos segundos. Con la GUI puedes chatear fácilmente con el bot.

Capturas:

Resultado del chatbot

Si quieres leer la versión en inglés de este artículo, puedes hacer click aquí.

Mira el código en mi GitHub.

Gracias por leer. Si el artículo te resultó útil, compártelo con tus amigos. 🙂

Entradas del mismo autor

Deja un comentario