Python para PNL: creaci贸n de un chatbot basado en reglas

    Este es el art铆culo n煤mero 12 de mi serie de art铆culos sobre Python para PNL. En el art铆culo anterior, expliqu茅 brevemente las diferentes funcionalidades de Python Biblioteca Gensim. Hasta ahora, en esta serie, hemos cubierto casi todas las bibliotecas de PNL m谩s utilizadas, como NLTK, SpaCy, Gensim, StanfordCoreNLP, Pattern, TextBlob, etc.

    En este art铆culo, no vamos a explorar ninguna biblioteca de PNL. M谩s bien, desarrollaremos un chatbot basado en reglas muy simple capaz de responder las consultas de los usuarios sobre el deporte del tenis. Pero antes de comenzar la codificaci贸n real, primero analicemos brevemente qu茅 son los chatbots y c贸mo se usan.

    驴Qu茅 es un chatbot?

    Un chatbot es un agente conversacional capaz de responder las consultas de los usuarios en forma de texto, voz o mediante una interfaz gr谩fica de usuario. En palabras simples, un chatbot es una aplicaci贸n de software que puede conversar con un usuario sobre cualquier tema. Los chatbots se pueden clasificar ampliamente en dos tipos: chatbots orientados a tareas y chatbots de uso general.

    Los chatbots orientados a tareas est谩n dise帽ados para realizar tareas espec铆ficas. Por ejemplo, un chatbot orientado a tareas puede responder consultas relacionadas con la reserva de trenes, la entrega de pizzas; tambi茅n puede trabajar como terapeuta m茅dico personal o asistente personal.

    Por otro lado, los chatbots de prop贸sito general pueden tener discusiones abiertas con los usuarios.

    Tambi茅n hay un tercer tipo de chatbots llamados chatbots h铆bridos que pueden participar en discusiones abiertas y orientadas a tareas con los usuarios.

    Enfoques para el desarrollo de chatbot

    Los enfoques de desarrollo de chatbots se dividen en dos categor铆as: chatbots basados 鈥嬧媏n reglas y chatbots basados 鈥嬧媏n aprendizaje.

    Chatbots basados 鈥嬧媏n el aprendizaje

    Los chatbots basados 鈥嬧媏n el aprendizaje son el tipo de chatbots que utilizan t茅cnicas de Machine Learning y un conjunto de datos para aprender a generar una respuesta a las consultas de los usuarios. Los chatbots basados 鈥嬧媏n el aprendizaje se pueden dividir en dos categor铆as: chatbots basados 鈥嬧媏n la recuperaci贸n y chatbots generativos.

    Los chatbots basados 鈥嬧媏n la recuperaci贸n aprenden a seleccionar una determinada respuesta a las consultas de los usuarios. Por otro lado, los chatbots generativos aprenden a generar una respuesta sobre la marcha.

    Una de las principales ventajas de los chatbots basados 鈥嬧媏n el aprendizaje es su flexibilidad para responder a una variedad de consultas de los usuarios. Aunque la respuesta no siempre sea correcta, los chatbots basados 鈥嬧媏n el aprendizaje son capaces de responder a cualquier tipo de consulta de los usuarios. Uno de los principales inconvenientes de estos chatbots es que pueden necesitar una gran cantidad de tiempo y datos para entrenarse.

    Chatbots basados 鈥嬧媏n reglas

    Los chatbots basados 鈥嬧媏n reglas son bastante sencillos en comparaci贸n con los chatbots basados 鈥嬧媏n el aprendizaje. Hay un conjunto espec铆fico de reglas. Si la consulta del usuario coincide con alguna regla, se genera la respuesta a la consulta; de lo contrario, se notifica al usuario que la respuesta a la consulta del usuario no existe.

    Una de las ventajas de los chatbots basados 鈥嬧媏n reglas es que siempre dan resultados precisos. Sin embargo, en el lado negativo, no escalan bien. Para agregar m谩s respuestas, debe definir nuevas reglas.

    En la siguiente secci贸n, explicar茅 c贸mo crear un chatbot basado en reglas que responder谩 a las consultas simples de los usuarios sobre el deporte del tenis.

    Desarrollo de chatbot basado en reglas con Python

    El chatbot que vamos a desarrollar ser谩 muy sencillo. Primero necesitamos un corpus que contenga mucha informaci贸n sobre el deporte del tenis. Desarrollaremos tal corpus raspando el art铆culo de Wikipedia sobre tenis. A continuaci贸n, realizaremos algunos preprocesos en el corpus y luego dividiremos el corpus en oraciones.

    Cuando un usuario ingresa una consulta, la consulta se convertir谩 en forma vectorizada. Todas las oraciones del corpus tambi茅n se convertir谩n a sus correspondientes formas vectorizadas. A continuaci贸n, la oraci贸n con la mayor similitud de coseno con el vector de entrada del usuario se seleccionar谩 como respuesta a la entrada del usuario.

    Siga estos pasos para desarrollar el chatbot:

    Importaci贸n de bibliotecas necesarias

    import nltk
    import numpy as np
    import random
    import string
    
    import bs4 as bs
    import urllib.request
    import re
    

    Estaremos usando el Beautifulsoup4 biblioteca para analizar los datos de Wikipedia. Adem谩s, la biblioteca de expresiones regulares de Python, re, se utilizar谩 para algunas tareas de preprocesamiento en el texto.

    Creando el Corpus

    Como dijimos anteriormente, usaremos el art铆culo de Wikipedia sobre Tenis para crear nuestro corpus. El siguiente script recupera el art铆culo de Wikipedia y extrae todos los p谩rrafos del texto del art铆culo. Finalmente, el texto se convierte a min煤sculas para facilitar su procesamiento.

    raw_html = urllib.request.urlopen('https://en.wikipedia.org/wiki/Tennis')
    raw_html = raw_html.read()
    
    article_html = bs.BeautifulSoup(raw_html, 'lxml')
    
    article_paragraphs = article_html.find_all('p')
    
    article_text=""
    
    for para in article_paragraphs:
        article_text += para.text
    
    article_text = article_text.lower()
    

    Funci贸n de ayuda y preprocesamiento de texto

    A continuaci贸n, necesitamos preprocesar nuestro texto para eliminar todos los caracteres especiales y espacios vac铆os de nuestro texto. La siguiente expresi贸n regular hace eso:

    article_text = re.sub(r'[[0-9]*]', ' ', article_text)
    article_text = re.sub(r's+', ' ', article_text)
    

    Necesitamos dividir nuestro texto en oraciones y palabras, ya que la similitud del coseno de la entrada del usuario se comparar谩 con cada oraci贸n. Ejecute el siguiente script:

    article_sentences = nltk.sent_tokenize(article_text)
    article_words = nltk.word_tokenize(article_text)
    

    Finalmente, necesitamos crear funciones de ayuda que eliminar谩n la puntuaci贸n del texto de entrada del usuario y tambi茅n lematizar谩n el texto. La lematizaci贸n se refiere a reducir una palabra a su forma ra铆z. Por ejemplo, la lematizaci贸n de la palabra “comi贸” devuelve comer, la palabra “arrojar” se convertir谩 en tirar y la palabra “peor” se reducir谩 a “malo”.

    Ejecute el siguiente c贸digo:

    wnlemmatizer = nltk.stem.WordNetLemmatizer()
    
    def perform_lemmatization(tokens):
        return [wnlemmatizer.lemmatize(token) for token in tokens]
    
    punctuation_removal = dict((ord(punctuation), None) for punctuation in string.punctuation)
    
    def get_processed_text(document):
        return perform_lemmatization(nltk.word_tokenize(document.lower().translate(punctuation_removal)))
    

    En el script anterior, primero instanciamos el WordNetLemmatizer desde el NTLK biblioteca. A continuaci贸n, definimos una funci贸n perform_lemmatization, que toma una lista de palabras como entrada y lematiza la correspondiente lista lematizada de palabras. los punctuation_removal list elimina la puntuaci贸n del texto pasado. Finalmente, el get_processed_text El m茅todo toma una oraci贸n como entrada, la tokeniza, la lematiza y luego elimina la puntuaci贸n de la oraci贸n.

    Responder a los saludos

    Dado que estamos desarrollando un chatbot basado en reglas, necesitamos manejar diferentes tipos de entradas de usuario de una manera diferente. Por ejemplo, para los saludos definiremos una funci贸n dedicada. Para manejar los saludos, crearemos dos listas: greeting_inputs y greeting_outputs. Cuando un usuario ingrese un saludo, intentaremos buscarlo en el greetings_inputs lista, si se encuentra el saludo, elegiremos aleatoriamente una respuesta del greeting_outputs lista.

    Mira el siguiente gui贸n:

    greeting_inputs = ("hey", "good morning", "good evening", "morning", "evening", "hi", "whatsup")
    greeting_responses = ["hey", "hey hows you?", "*nods*", "hello, how you doing", "hello", "Welcome, I am good and you"]
    
    def generate_greeting_response(greeting):
        for token in greeting.split():
            if token.lower() in greeting_inputs:
                return random.choice(greeting_responses)
    

    Aqu铆 el generate_greeting_response() El m茅todo b谩sicamente se encarga de validar el mensaje de saludo y generar la respuesta correspondiente.

    Responder a las consultas de los usuarios

    Como dijimos anteriormente, la respuesta se generar谩 en funci贸n de la similitud de coseno de la forma vectorizada de la oraci贸n de entrada y las oraciones en los cuerpos. El siguiente script importa el TfidfVectorizer y el cosine_similarity funciones:

    from sklearn.feature_extraction.text import TfidfVectorizer
    from sklearn.metrics.pairwise import cosine_similarity
    

    Ahora tenemos todo configurado que necesitamos para generar una respuesta a las consultas de los usuarios relacionadas con el tenis. Crearemos un m茅todo que toma la entrada del usuario, encuentra la similitud del coseno de la entrada del usuario y la compara con las oraciones en el corpus.

    Mira el siguiente gui贸n:

    def generate_response(user_input):
        tennisrobo_response=""
        article_sentences.append(user_input)
    
        word_vectorizer = TfidfVectorizer(tokenizer=get_processed_text, stop_words="english")
        all_word_vectors = word_vectorizer.fit_transform(article_sentences)
        similar_vector_values = cosine_similarity(all_word_vectors[-1], all_word_vectors)
        similar_sentence_number = similar_vector_values.argsort()[0][-2]
    
        matched_vector = similar_vector_values.flatten()
        matched_vector.sort()
        vector_matched = matched_vector[-2]
    
        if vector_matched == 0:
            tennisrobo_response = tennisrobo_response + "I am sorry, I could not understand you"
            return tennisrobo_response
        else:
            tennisrobo_response = tennisrobo_response + article_sentences[similar_sentence_number]
            return tennisrobo_response
    

    Puedes ver que el generate_response() El m茅todo acepta un par谩metro que es la entrada del usuario. A continuaci贸n, definimos una cadena vac铆a tennisrobo_response. Luego agregamos la entrada del usuario a la lista de oraciones ya existentes. Despu茅s de eso en las siguientes l铆neas:

    word_vectorizer = TfidfVectorizer(tokenizer=get_processed_text, stop_words="english")
    all_word_vectors = word_vectorizer.fit_transform(article_sentences)
    

    Inicializamos el tfidfvectorizer y luego convierta todas las oraciones en el corpus junto con la oraci贸n de entrada en su forma vectorizada correspondiente.

    En la siguiente l铆nea:

    similar_vector_values = cosine_similarity(all_word_vectors[-1], all_word_vectors)
    

    Usamos el cosine_similarity funci贸n para encontrar la similitud de coseno entre el 煤ltimo elemento de la all_word_vectors list (que en realidad es el vector de palabra para la entrada del usuario, ya que se agreg贸 al final) y los vectores de palabra para todas las oraciones en el corpus.

    A continuaci贸n, en la siguiente l铆nea:

    similar_sentence_number = similar_vector_values.argsort()[0][-2]
    

    Ordenamos la lista que contiene las similitudes de coseno de los vectores, el pen煤ltimo elemento de la lista tendr谩 el coseno m谩s alto (despu茅s de la clasificaci贸n) con la entrada del usuario. El 煤ltimo elemento es la entrada del usuario en s铆, por lo tanto, no lo seleccionamos.

    Finalmente, aplanamos la similitud de coseno recuperada y verificamos si la similitud es igual a cero o no. Si la similitud del coseno del vector emparejado es 0, eso significa que nuestra consulta no tuvo respuesta. En ese caso, simplemente imprimiremos que no entendemos la consulta del usuario.

    De lo contrario, si la similitud del coseno no es igual a cero, eso significa que encontramos una oraci贸n similar a la entrada en nuestro corpus. En ese caso, simplemente pasaremos el 铆ndice de la oraci贸n coincidente a nuestra lista “article_sentences” que contiene la colecci贸n de todas las oraciones.

    Charlando con el Chatbot

    Como paso final, necesitamos crear una funci贸n que nos permita chatear con el chatbot que acabamos de dise帽ar. Para hacerlo, escribiremos otra funci贸n auxiliar que seguir谩 ejecut谩ndose hasta que el usuario escriba “Bye”.

    Mire el siguiente script, el c贸digo se ha explicado despu茅s de eso:

    continue_dialogue = True
    print("Hello, I am your friend TennisRobo. You can ask me any question regarding tennis:")
    while(continue_dialogue == True):
        human_text = input()
        human_text = human_text.lower()
        if human_text != 'bye':
            if human_text == 'thanks' or human_text == 'thank you very much' or human_text == 'thank you':
                continue_dialogue = False
                print("TennisRobo: Most welcome")
            else:
                if generate_greeting_response(human_text) != None:
                    print("TennisRobo: " + generate_greeting_response(human_text))
                else:
                    print("TennisRobo: ", end="")
                    print(generate_response(human_text))
                    article_sentences.remove(human_text)
        else:
            continue_dialogue = False
            print("TennisRobo: Good bye and take care of yourself...")
    

    En el script anterior, primero configuramos la bandera continue_dialogue a la verdad. Despu茅s de eso, imprimimos un mensaje de bienvenida al usuario que solicita cualquier entrada. A continuaci贸n, inicializamos un ciclo while que se sigue ejecutando hasta que continue_dialogue bandera es verdadera. Dentro del bucle, se recibe la entrada del usuario, que luego se convierte a min煤sculas. La entrada del usuario se almacena en el human_text variable. Si el usuario ingresa la palabra “adi贸s”, el continue_dialogue se establece en falso y se imprime un mensaje de despedida al usuario.

    Por otro lado, si el texto de entrada no es igual a “adi贸s”, se comprueba si la entrada contiene palabras como “gracias”, “gracias”, etc. o no. Si se encuentran estas palabras, se genera una respuesta “Muy bienvenido”. De lo contrario, si la entrada del usuario no es igual a None, la generate_response Se llama al m茅todo que obtiene la respuesta del usuario en funci贸n de la similitud del coseno como se explica en la 煤ltima secci贸n.

    Una vez que se genera la respuesta, la entrada del usuario se elimina de la colecci贸n de oraciones, ya que no queremos que la entrada del usuario sea parte del corpus. El proceso contin煤a hasta que el usuario escribe “bye”. Puede ver por qu茅 este tipo de chatbot se llama chatbot basado en reglas. Hay muchas reglas a seguir y si queremos agregar m谩s funcionalidades al chatbot, tendremos que agregar m谩s reglas.

    La salida del script del chatbot se ve as铆:

    Puedes ver en la imagen de arriba que ingres茅 la entrada “roger federer” y la respuesta generada es:

    however it must be noted that both rod laver and ken rosewall also won major pro slam tournaments on all three surfaces (grass, clay, wood) rosewall in 1963 and laver in 1967. more recently, roger federer is considered by many observers to have the most "complete" game in modern tennis."
    

    Es posible que la respuesta no sea precisa, sin embargo, todav铆a tiene sentido.

    Es importante mencionar que la idea de este art铆culo no es desarrollar un chatbot perfecto, sino explicar el principio de funcionamiento de los chatbots basados 鈥嬧媏n reglas.

    Conclusi贸n

    Los chatbots son agentes conversacionales que participan en diferentes tipos de conversaciones con humanos. Los chatbots est谩n encontrando su lugar en diferentes estratos de la vida que van desde el asistente personal hasta los sistemas de reserva de boletos y los terapeutas fisiol贸gicos. Tener un chatbot en lugar de humanos puede ser muy rentable. Sin embargo, desarrollar un chatbot con la misma eficiencia que los humanos puede resultar muy complicado.

    En este art铆culo, mostramos c贸mo desarrollar un chatbot simple basado en reglas usando similitud de coseno. En el siguiente art铆culo, exploramos otro campo de procesamiento del lenguaje natural.

     

    Etiquetas:

    Deja una respuesta

    Tu direcci贸n de correo electr贸nico no ser谩 publicada. Los campos obligatorios est谩n marcados con *