Construyendo un Chatbot simple desde cero en Python (usando NLTK)

Fuente: eWeek
Gartner estima que para 2020, los chatbots manejarán el 85 por ciento de las interacciones de servicio al cliente; ya están manejando alrededor del 30 por ciento de las transacciones ahora.

Estoy seguro de que has oído hablar de Duolingo: una aplicación popular de aprendizaje de idiomas, que gamifica la práctica de un nuevo idioma. Es bastante popular debido a sus estilos innovadores de enseñanza de un idioma extranjero. El concepto es simple: cinco a diez minutos de capacitación interactiva al día son suficientes para aprender un idioma.

Sin embargo, a pesar de que Duolingo está permitiendo que las personas aprendan un nuevo idioma, los profesionales tenían una preocupación. Las personas sentían que se estaban perdiendo el aprendizaje de valiosas habilidades de conversación ya que estaban aprendiendo por su cuenta. Las personas también estaban preocupadas por ser emparejadas con otros estudiantes de idiomas debido al miedo a la vergüenza. Esto resultó ser un gran cuello de botella en los planes de Duolingo.

Entonces, su equipo resolvió este problema construyendo un chatbot nativo dentro de su aplicación, para ayudar a los usuarios a aprender habilidades de conversación y practicar lo que aprendieron.

http://bots.duolingo.com/

Dado que los bots están diseñados para conversar y ser amigables, los estudiantes de Duolingo pueden practicar la conversación en cualquier momento del día, utilizando su elección de caracteres, hasta que se sientan lo suficientemente valientes como para practicar su nuevo idioma con otros hablantes. Esto resolvió un importante problema para el consumidor e hizo que aprender a través de la aplicación fuera mucho más divertido.

Entonces, ¿qué es un chatbot?

Un chatbot es una pieza de software con inteligencia artificial en un dispositivo (Siri, Alexa, Google Assistant, etc.), una aplicación, un sitio web u otras redes que intentan evaluar las necesidades de los consumidores y luego ayudarlos a realizar una tarea particular como una transacción comercial, reserva de hotel, envío de formularios, etc. Hoy en día, casi todas las empresas tienen un chatbot implementado para interactuar con los usuarios. Algunas de las formas en que las empresas usan chatbots son:

  • Para entregar información de vuelo
  • para conectar a los clientes y sus finanzas
  • Como atención al cliente

Las posibilidades son (casi) ilimitadas.

La historia de los chatbots se remonta a 1966 cuando Weizenbaum inventó un programa de computadora llamado ELIZA. Imitaba el lenguaje de un psicoterapeuta de solo 200 líneas de código. Todavía puedes conversar con él aquí: Eliza.
Fuente: Cognizant

¿Cómo funcionan los chatbots?

En términos generales, hay dos variantes de chatbots: basado en reglas y autoaprendizaje.

  1. En un enfoque basado en reglas, un bot responde preguntas basadas en algunas reglas sobre las cuales está entrenado. Las reglas definidas pueden ser muy simples o muy complejas. Los bots pueden manejar consultas simples pero no pueden administrar las complejas.
  2. Los bots de autoaprendizaje son los que usan algunos enfoques basados ​​en el aprendizaje automático y definitivamente son más eficientes que los bots basados ​​en reglas. Estos bots pueden ser de otros dos tipos: basados ​​en recuperación o generativos

i) En los modelos basados ​​en la recuperación, un chatbot usa alguna heurística para seleccionar una respuesta de una biblioteca de respuestas predefinidas. El chatbot usa el mensaje y el contexto de la conversación para seleccionar la mejor respuesta de una lista predefinida de mensajes de bot. El contexto puede incluir una posición actual en el árbol de diálogo, todos los mensajes anteriores en la conversación, variables previamente guardadas (por ejemplo, nombre de usuario). La heurística para seleccionar una respuesta se puede diseñar de muchas maneras diferentes, desde la lógica condicional if-else basada en reglas hasta los clasificadores de aprendizaje automático.

ii) Los bots generativos pueden generar las respuestas y no siempre responden con una de las respuestas de un conjunto de respuestas. Esto los hace más inteligentes, ya que toman palabra por palabra de la consulta y generan las respuestas.

En este artículo crearemos un chatbot basado en recuperación simple basado en la biblioteca NLTK en python.

Construyendo el bot

Prerrequisitos

Se asume el conocimiento práctico de la biblioteca scikit y NLTK. Sin embargo, si es nuevo en PNL, aún puede leer el artículo y luego consultar los recursos.

PNL

El campo de estudio que se centra en las interacciones entre el lenguaje humano y las computadoras se llama procesamiento del lenguaje natural, o PNL para abreviar. Se encuentra en la intersección de la informática, la inteligencia artificial y la lingüística computacional [Wikipedia] .NLP es una forma para que las computadoras analicen, comprendan y obtengan significado del lenguaje humano de una manera inteligente y útil. Al utilizar NLP, los desarrolladores pueden organizar y estructurar el conocimiento para realizar tareas tales como resumen automático, traducción, reconocimiento de entidades con nombre, extracción de relaciones, análisis de sentimientos, reconocimiento de voz y segmentación de temas.

NLTK: una breve introducción

NLTK (Natural Language Toolkit) es una plataforma líder para crear programas de Python para trabajar con datos de lenguaje humano. Proporciona interfaces fáciles de usar a más de 50 recursos corporales y léxicos como WordNet, junto con un conjunto de bibliotecas de procesamiento de texto para clasificación, tokenización, derivación, etiquetado, análisis y razonamiento semántico, envoltorios para bibliotecas NLP de potencia industrial.

NLTK ha sido llamado "una herramienta maravillosa para enseñar y trabajar en lingüística computacional usando Python", y "una biblioteca increíble para jugar con lenguaje natural".

El procesamiento del lenguaje natural con Python proporciona una introducción práctica a la programación para el procesamiento del lenguaje. Recomiendo este libro a las personas que comienzan en PNL con Python.

Descargar e instalar NLTK

  1. Instalar NLTK: ejecutar pip install nltk
  2. Instalación de prueba: ejecute python y luego escriba import nltk

Para obtener instrucciones específicas de la plataforma, lea aquí.

Instalación de paquetes NLTK

importe NLTK y ejecute nltk.download (). Esto abrirá el descargador NLTK desde donde puede elegir los corpus y los modelos para descargar. También puede descargar todos los paquetes a la vez.

Preprocesamiento de texto con NLTK

El principal problema con los datos de texto es que todo está en formato de texto (cadenas). Sin embargo, los algoritmos de aprendizaje automático necesitan algún tipo de vector de características numéricas para realizar la tarea. Entonces, antes de comenzar con cualquier proyecto de PNL, debemos preprocesarlo para que sea ideal para el trabajo. El procesamiento previo de texto básico incluye:

  • Convertir todo el texto en mayúsculas o minúsculas, para que el algoritmo no trate las mismas palabras en diferentes casos como diferentes
  • Tokenización: Tokenización es solo el término utilizado para describir el proceso de convertir las cadenas de texto normales en una lista de tokens, es decir, palabras que realmente queremos. El tokenizador de oraciones se puede usar para encontrar la lista de oraciones y el tokenizador de palabras se puede usar para encontrar la lista de palabras en cadenas.

El paquete de datos NLTK incluye un tokenizador Punkt pre-entrenado para inglés.

  • Eliminar ruido, es decir, todo lo que no está en un número o letra estándar.
  • Eliminando palabras Stop. A veces, algunas palabras extremadamente comunes que parecen ser de poco valor para ayudar a seleccionar documentos que coinciden con las necesidades de un usuario se excluyen por completo del vocabulario. Estas palabras se llaman palabras de detención
  • Derivación: La derivación es el proceso de reducir las palabras flexionadas (o algunas veces derivadas) a su forma de raíz, base o raíz, generalmente una forma de palabra escrita. Ejemplo si tuviéramos que contener las siguientes palabras: "Stems", "Stemming", "Stemmed", "and Stemtization", el resultado sería una sola palabra "stem".
  • Lematización: una ligera variante de la derivación es la lematización. La principal diferencia entre estos es que, la derivación a menudo puede crear palabras inexistentes, mientras que los lemmas son palabras reales. Por lo tanto, su raíz raíz, es decir, la palabra con la que termina, no es algo que simplemente puede buscar en un diccionario, sino que puede buscar un lema. Algunos ejemplos de lematización son que "ejecutar" es una forma básica de palabras como "correr" o "ejecutar" o que las palabras "mejor" y "bueno" están en el mismo lema, por lo que se consideran iguales.

Bolsa de palabras

Después de la fase inicial de preprocesamiento, necesitamos transformar el texto en un vector significativo (o matriz) de números. La bolsa de palabras es una representación de texto que describe la aparición de palabras dentro de un documento. Implica dos cosas:

• Un vocabulario de palabras conocidas.

• Una medida de la presencia de palabras conocidas.

¿Por qué se llama una "bolsa" de palabras? Esto se debe a que cualquier información sobre el orden o la estructura de las palabras en el documento se descarta y el modelo solo se preocupa de si las palabras conocidas aparecen en el documento, no de dónde aparecen en el documento.

La intuición detrás de la Bolsa de palabras es que los documentos son similares si tienen un contenido similar. Además, podemos aprender algo sobre el significado del documento solo a partir de su contenido.

Por ejemplo, si nuestro diccionario contiene las palabras {Learning, is, the, not, great}, y queremos vectorizar el texto "Learning is great", tendríamos el siguiente vector: (1, 1, 0, 0, 1)

Enfoque TF-IDF

Un problema con el enfoque de la Bolsa de palabras es que las palabras muy frecuentes comienzan a dominar en el documento (por ejemplo, una puntuación más alta), pero pueden no contener tanto "contenido informativo". Además, dará más peso a documentos más largos que a documentos más cortos.

Un enfoque es reescalar la frecuencia de las palabras según la frecuencia con la que aparecen en todos los documentos para que se penalicen las puntuaciones de palabras frecuentes como "the" que también son frecuentes en todos los documentos. Este enfoque de puntuación se llama Frecuencia de documento de frecuencia inversa de término, o TF-IDF para abreviar, donde:

Término Frecuencia: es una puntuación de la frecuencia de la palabra en el documento actual.

TF = (Número de veces que el término t aparece en un documento) / (Número de términos en el documento)

Frecuencia de documento inversa: es una puntuación de cuán rara es la palabra en los documentos.

IDF = 1 + log (N / n), donde, N es el número de documentos yn es el número de documentos en los que ha aparecido un término t.

El peso de Tf-IDF es un peso usado a menudo en la recuperación de información y minería de texto. Este peso es una medida estadística utilizada para evaluar la importancia de una palabra para un documento en una colección o corpus

Ejemplo:

Considere un documento que contiene 100 palabras en el que la palabra "teléfono" aparece 5 veces.
El término frecuencia (es decir, tf) para el teléfono es entonces (5/100) = 0.05. Ahora, supongamos que tenemos 10 millones de documentos y la palabra teléfono aparece en mil de estos. Luego, la frecuencia inversa del documento (es decir, IDF) se calcula como log (10,000,000 / 1,000) = 4. Por lo tanto, el peso Tf-IDF es el producto de estas cantidades: 0.05 * 4 = 0.20.
Tf-IDF se puede implementar en scikit learn como:
from sklearn.feature_extraction.text import TfidfVectorizer

Similitud de coseno

TF-IDF es una transformación aplicada a textos para obtener dos vectores con valores reales en el espacio vectorial. Entonces podemos obtener la similitud de coseno de cualquier par de vectores tomando su producto escalar y dividiéndolo por el producto de sus normas. Eso produce el coseno del ángulo entre los vectores. La similitud de coseno es una medida de similitud entre dos vectores distintos de cero. Usando esta fórmula podemos encontrar la similitud entre dos documentos cualquiera d1 y d2.

Coseno Similitud (d1, d2) = Producto de puntos (d1, d2) / || d1 || * || d2 ||

donde d1, d2 son dos vectores distintos de cero.

Para una explicación detallada y un ejemplo práctico de TF-IDF y Cosine Similarity, consulte el documento a continuación.

Ahora tenemos una idea justa del proceso de PNL. Es hora de que lleguemos a nuestra tarea real, es decir, la creación de Chatbot. Llamaremos al chatbot aquí como "ROBO".

Puede encontrar el código completo con el corpus en el repositorio Github asociado aquí o puede verlo en mi carpeta haciendo clic en la imagen a continuación.

Importando las bibliotecas necesarias

importar nltk
importar numpy como np
importar al azar
importar cadena # para procesar cadenas estándar de Python

Cuerpo

Para nuestro ejemplo, utilizaremos la página de Wikipedia para chatbots como nuestro corpus. Copie el contenido de la página y colóquelo en un archivo de texto llamado "chatbot.txt". Sin embargo, puede usar cualquier corpus de su elección.

Leer en los datos

Leeremos en el archivo corpus.txt y convertiremos todo el corpus en una lista de oraciones y una lista de palabras para un procesamiento previo adicional.

f = abierto ('chatbot.txt', 'r', errores = 'ignorar')
raw = f.read ()
raw = raw.lower () # se convierte en minúsculas
nltk.download ('punkt') # solo uso por primera vez
nltk.download ('wordnet') # solo uso por primera vez
sent_tokens = nltk.sent_tokenize (raw) # convierte a la lista de oraciones
word_tokens = nltk.word_tokenize (raw) # se convierte en una lista de palabras

Veamos un ejemplo de los tokens enviados y los tokens de palabras

tokens_enviados [: 2]
['un chatbot (también conocido como talkbot, chatterbot, bot, im bot, agente interactivo o entidad de conversación artificial) es un programa de computadora o una inteligencia artificial que conduce una conversación a través de métodos auditivos o textuales',
 "tales programas a menudo están diseñados para simular de manera convincente cómo se comportaría un humano como compañero de conversación, pasando así la prueba de turing".
word_tokens [: 2]
['a', 'chatbot', '(', 'también', 'conocido']

Preprocesar el texto sin procesar

Ahora definiremos una función llamada LemTokens que tomará como entrada los tokens y devolverá tokens normalizados.

lemmer = nltk.stem.WordNetLemmatizer ()
#WordNet es un diccionario de inglés semánticamente incluido en NLTK.
def LemTokens (tokens):
    return [lemmer.lemmatize (token) para el token en tokens]
remove_punct_dict = dict ((ord (punct), None) para punct en string.punctuation)
def LemNormalize (texto):
    return LemTokens (nltk.word_tokenize (text.lower (). translate (remove_punct_dict)))

Concordancia de palabras clave

A continuación, definiremos una función para un saludo del bot, es decir, si la entrada de un usuario es un saludo, el bot devolverá una respuesta de saludo. ELIZA usa una palabra clave simple para saludos. Utilizaremos el mismo concepto aquí.

GREETING_INPUTS = ("hola", "hola", "saludos", "sup", "qué pasa", "hola",)
GREETING_RESPONSES = ["hola", "hola", "* asiente con la cabeza *", "hola", "hola", "¡Me alegro! Me estás hablando"]
def saludo (oración):
 
    para palabra en oración.split ():
        if word.lower () en GREETING_INPUTS:
            return random.choice (GREETING_RESPONSES)

Generando respuesta

Para generar una respuesta de nuestro bot para preguntas de entrada, se utilizará el concepto de similitud de documentos. Entonces comenzamos importando los módulos necesarios.

  • Desde la biblioteca de aprendizaje scikit, importe el vectorizador TFidf para convertir una colección de documentos en bruto en una matriz de características TF-IDF.
from sklearn.feature_extraction.text import TfidfVectorizer
  • Además, importe el módulo de similitud de coseno de la biblioteca de aprendizaje scikit
desde sklearn.metrics.pairwise import cosine_similarity

Esto se usará para encontrar la similitud entre las palabras ingresadas por el usuario y las palabras en el corpus. Esta es la implementación más simple posible de un chatbot.

Definimos una respuesta de función que busca en el enunciado del usuario una o más palabras clave conocidas y devuelve una de varias respuestas posibles. Si no encuentra la entrada que coincide con ninguna de las palabras clave, devuelve una respuesta: "¡Lo siento! No te entiendo "

respuesta def (respuesta_usuario):
    robo_response = ''
    sent_tokens.append (respuesta_usuario)
    TfidfVec = TfidfVectorizer (tokenizer = LemNormalize, stop_words = 'english')
    tfidf = TfidfVec.fit_transform (sent_tokens)
    vals = cosine_similarity (tfidf [-1], tfidf)
    idx = vals.argsort () [0] [- 2]
    flat = vals.flatten ()
    flat.sort ()
    req_tfidf = plano [-2]
    if (req_tfidf == 0):
        robo_response = robo_response + "¡Lo siento! No te entiendo"
        volver robo_response
    más:
        robo_response = robo_response + sent_tokens [idx]
        volver robo_response

Finalmente, alimentaremos las líneas que queremos que diga nuestro bot al iniciar y finalizar una conversación, dependiendo de la entrada del usuario.

bandera = verdadero
print ("ROBO: Mi nombre es Robo. Contestaré tus consultas sobre Chatbots. Si quieres salir, escribe Bye!")
while (flag == True):
    user_response = input ()
    user_response = user_response.lower ()
    if (user_response! = 'bye'):
        if (user_response == 'gracias' o user_response == 'gracias'):
            bandera = falso
            print ("ROBO: De nada ..")
        más:
            if (saludo (respuesta_usuario)! = Ninguno):
                print ("ROBO:" + saludo (respuesta_usuario))
            más:
                print ("ROBO:", end = "")
                print (respuesta (respuesta_usuario))
                sent_tokens.remove (respuesta_usuario)
    más:
        bandera = falso
        print ("ROBO: Bye! cuídate ..")

Entonces eso es todo. Hemos codificado nuestro primer chatbot en NLTK. Ahora, veamos cómo interactúa con los humanos:

Esto no estuvo tan mal. Aunque el chatbot no pudo dar una respuesta satisfactoria a algunas preguntas, le fue bastante bien a otras.

Conclusión

Aunque es un bot muy simple con apenas habilidades cognitivas, es una buena manera de ingresar a la PNL y conocer los chatbots. Aunque "ROBO" responde a las aportaciones de los usuarios. No engañará a sus amigos, y para un sistema de producción querrá considerar una de las plataformas o marcos de bot existentes, pero este ejemplo debería ayudarlo a pensar en el diseño y el desafío de crear un chatbot. Internet está inundado de recursos y, después de leer este artículo, estoy seguro de que querrás crear un chatbot propio. Muy feliz jugando!