Pues dado que ahora mismo estamos todos locos con ChatGPT y las posibilidades que ofrecen, me ha parecido muy oportuno, comenzar una serie de pequeños artículos donde explicar algunas de las técnicas más utilizadas para su programación. Y es que si bien los algoritmos generativos son la última tendencia, también es cierto que existen otras posibilidades que pueden sernos útiles en contextos más limitados o bien donde queramos tener un control de grano fino de como funciona nuestro agente conversacional.
¿Como definimos a un chatbot aunque me gusta más el término de agente conversacional? Un chatbot es un programa de software diseñado para simular una conversación con seres humanos a través de una interfaz de chat. Los chatbots pueden entender y responder a preguntas y declaraciones en lenguaje natural, lo que les permite interactuar con usuarios en tiempo real. Se utilizan comúnmente en aplicaciones de mensajería, sitios web y plataformas de atención al cliente para responder preguntas, proporcionar información, resolver problemas y ofrecer recomendaciones a los usuarios. Como veis nada nuevo bajo el sol y que no supierais ya.
Los chatbots pueden clasificarse en dos categorías principales:
- Basados en reglas: Son quizás los primeros que se crearon y funcionan siguiendo un conjunto predefinido de reglas y patrones. Utilizan coincidencias de palabras clave y expresiones regulares para identificar preguntas y respuestas relevantes en función de la entrada del usuario. Si bien son más simples y fáciles de implementar, estos chatbots tienen limitaciones en su capacidad para entender y responder a preguntas más complejas y variaciones en el lenguaje, sin embargo, como os decía anteriormente pueden ser muy útiles en algunos escenarios simples o cuando tengamos ciertas limitaciones de recursos.
- Basados en técnicas de inteligencia artificial (IA): En este caso se utilizan algoritmos de aprendizaje automático y procesamiento del lenguaje natural (NLP) para comprender y responder a las preguntas de los usuarios. Pueden adaptarse y aprender de las interacciones con los usuarios, lo que les permite mejorar su desempeño con el tiempo y manejar preguntas y declaraciones más complejas y variadas. Los chatbots basados en IA, como los desarrollados con GPT-3 de OpenAI o Rasa, pueden ofrecer una experiencia de conversación más fluida y natural en comparación con los chatbots basados en reglas.
Tanto unos como otros pueden usarse en una variedad de aplicaciones, como atención al cliente, ventas, marketing, asistentes virtuales, entretenimiento y educación. Pueden ayudar a las empresas a mejorar la eficiencia, reducir costos y proporcionar una experiencia más satisfactoria y personalizada a los usuarios.
Librerías Disponibles
Llegados a este punto podemos preguntarnos también, bueno si esto se lleva haciendo desde hace tiempo, lo normal es que existan librerías y herramientas que nos permitan programarlos sin tener que comenzar desde cero. Efectivamente así es y podemos encontrar las siguientes que podéis usar en vuestros proyectos.
Chatbots basados en reglas:
- ChatterBot: ChatterBot es una biblioteca de Python que facilita la creación de chatbots basados en reglas. Utiliza una base de datos de conocimientos y algoritmos de aprendizaje para generar respuestas a preguntas similares a las que se encuentran en su base de datos de conocimientos. Puedes encontrar más información en su repositorio de GitHub: https://github.com/gunthercox/ChatterBot
- AIML (Artificial Intelligence Markup Language): AIML es un lenguaje de marcado basado en XML utilizado para crear chatbots basados en reglas. AIML permite definir patrones de entrada y respuestas asociadas en archivos XML. Programas como Program-Y y PyAIML facilitan la creación de chatbots utilizando AIML en Python. Puedes encontrar más información sobre Program-Y aquí: https://github.com/keiffster/program-y y sobre PyAIML aquí: https://github.com/creatorrr/pyAIML
Chatbots basados en inteligencia artificial (IA):
- Rasa: Rasa es una plataforma de código abierto para desarrollar chatbots y asistentes virtuales basados en IA. Utiliza aprendizaje profundo y procesamiento del lenguaje natural para comprender y responder a las preguntas de los usuarios. Rasa es altamente personalizable y se puede utilizar para crear chatbots para una amplia variedad de aplicaciones y dominios. Puedes encontrar más información en su sitio web oficial: https://rasa.com/
- Dialogflow: Dialogflow es una plataforma de desarrollo de chatbots basada en IA creada por Google. Permite crear chatbots y asistentes virtuales que entienden el lenguaje natural y pueden integrarse con aplicaciones, sitios web y plataformas de mensajería populares. Dialogflow utiliza el aprendizaje automático de Google y es especialmente adecuado para desarrollar chatbots para Google Assistant. Puedes encontrar más información en su sitio web oficial: https://dialogflow.cloud.google.com/
- Wit.ai: Wit.ai es una plataforma de desarrollo de chatbots basada en IA creada por Facebook. Permite crear chatbots y asistentes virtuales que entienden el lenguaje natural y pueden integrarse con aplicaciones, sitios web y plataformas de mensajería populares. Wit.ai utiliza el aprendizaje automático de Facebook y es especialmente adecuado para desarrollar chatbots para Facebook Messenger. Puedes encontrar más información en su sitio web oficial: https://wit.ai/
Mucha teoria pero poca práctica, pero ¿qué es la Similitud del Coseno?
Vale, vale, pero es que hay que poner unos cimientos sólidos si realmente queremos entender como va la cosa. Veamos ahora como podemos implementar un primer ejemplo de Chatbot muy sencillo usando el lenguaje Python y alguna de las librerías comentadas. Por simplicidad, lo único que podrá entender será una batería de saludos, sin embargo, no hay ningún problema para añadir más preguntas y respuestas para hacerlo más versátil y potente, sin embargo como decía en el epígrafe de esta sección, primero necesitamos explicar para que sirve y que es la similitud del coseno, como ya sabemos el coseno es una función trigonométrica que tiene multitud de aplicaciones, y en este caso podemos calcular un vector en base a una serie de palabras y comparar estos cosenos en vez de tener que estar comparando palabras propiamente dichas.
La similitud del coseno es una medida de similitud entre dos vectores no nulos en un espacio vectorial, que se utiliza a menudo en la recuperación de información y en el análisis de texto. La similitud del coseno mide el ángulo entre dos vectores en lugar de la distancia euclidiana entre ellos, lo que la hace especialmente útil para comparar vectores en un espacio de alta dimensionalidad.
La similitud del coseno se calcula como el coseno del ángulo entre dos vectores. Si los dos vectores son A y B, la similitud del coseno se define como:
similitud_coseno(A, B) = (A · B) / (||A|| ||B||)
donde «A · B» es el producto escalar (o producto punto) de los vectores A y B, y «||A||» y «||B||» representan las normas (longitudes o valores absolutos) de los vectores A y B, respectivamente.
En el contexto del procesamiento del lenguaje natural y la recuperación de información, la similitud del coseno se utiliza a menudo para comparar documentos o fragmentos de texto. Para hacer esto, primero se representan los documentos como vectores en un espacio vectorial de términos. Cada dimensión en este espacio representa un término (palabra) único en el vocabulario, y el valor en esa dimensión indica la importancia del término en el documento. Una técnica común para representar la importancia de un término es la ponderación TF-IDF (Term Frequency-Inverse Document Frequency).
Una vez que los documentos están representados como vectores, se puede calcular la similitud del coseno entre ellos para determinar qué tan similares son en términos de su contenido. La similitud del coseno varía entre -1 y 1, donde -1 indica que los vectores son completamente opuestos, 1 indica que son idénticos y 0 indica que no tienen relación (ortogonalidad).
En resumen, la similitud del coseno es una medida de similitud entre dos vectores que compara el ángulo entre ellos en lugar de la distancia euclidiana. En el análisis de texto, se utiliza para comparar documentos o fragmentos de texto representados como vectores en un espacio vectorial de términos.
Y aquí una pregunta interesante, teniendo en cuenta lo ya explicado, ¿como se hace la transformación de un conjunto de documentos en un vector en un espacio vectorial de términos? En algoritmo no es demasiado complejo, y en realidad se puede simplificar en cinco pasos básicos, tal y como vamos a ver un poquito más adelante.
La transformación de un conjunto de documentos en vectores en un espacio vectorial de términos implica representar cada documento como un vector en un espacio de características, donde cada dimensión del espacio corresponde a un término único en el vocabulario del conjunto de documentos. Una técnica común para realizar esta transformación es utilizar la ponderación TF-IDF (Term Frequency-Inverse Document Frequency).
Aquí hay una descripción general de los pasos involucrados en la transformación de un conjunto de documentos en vectores en un espacio vectorial de términos utilizando TF-IDF:
- Tokenización: Separa cada documento en palabras individuales (tokens). Es posible que desees eliminar palabras vacías (stop words), signos de puntuación y aplicar la lematización o el stemming para reducir las palabras a su forma base.
- Crear el vocabulario: Haz una lista de todos los términos únicos en el conjunto de documentos. Estos términos únicos formarán las dimensiones del espacio vectorial.
- Calcular la frecuencia de términos (TF): La frecuencia de términos es el número de veces que un término aparece en un documento. Para cada documento, crea un vector donde cada dimensión corresponde a la frecuencia de un término en ese documento. Puedes normalizar la frecuencia de términos dividiendo el recuento de términos por la longitud total del documento (la suma de las frecuencias de todos los términos en el documento).
- Calcular la frecuencia inversa de documentos (IDF): La frecuencia inversa de documentos mide qué tan común o raro es un término en todo el conjunto de documentos. Se calcula como:
IDF(t) = log(N / df(t))
donde t
es un término, N
es el número total de documentos y df(t)
es el número de documentos en los que aparece el término t
. El logaritmo se utiliza para atenuar el efecto de la división.
- Calcular TF-IDF: Multiplica la frecuencia de términos (TF) por la frecuencia inversa de documentos (IDF) para cada término en cada documento. Esto dará como resultado un vector para cada documento en el espacio vectorial de términos, donde cada dimensión representa la ponderación TF-IDF para un término específico en ese documento.
La biblioteca scikit-learn en Python proporciona una herramienta llamada TfidfVectorizer
que realiza estos pasos de manera eficiente. Aquí tienes un ejemplo de cómo usar TfidfVectorizer
para transformar un conjunto de documentos en un espacio vectorial de términos:
from sklearn.feature_extraction.text import TfidfVectorizer
# Un conjunto de ejemplo de documentos
documents = [
"Este es el primer documento.",
"Este documento es el segundo documento.",
"Y este es el tercer documento.",
"¿Este es el primer documento?"
]
# Crear una instancia de TfidfVectorizer
vectorizer = TfidfVectorizer()
# Ajustar y transformar los documentos en vectores TF-IDF
tfidf_matrix = vectorizer.fit_transform(documents)
# tfidf_matrix es una matriz dispersa que contiene los vectores TF-IDF
print(tfidf_matrix)
Esto te dará una matriz dispersa de los vectores TF-IDF, donde cada fila representa un documento en el espacio vectorial de términos. Puedes usar esta matriz para calcular la similitud del coseno entre los documentos o realizar otras tareas de análisis de texto, como agrupamiento o clasificación de documentos.
Y nada más por hoy, que ya es demasiado largo, en el próximo artículo de esta serie explicaremos un poco más sobre las técnicas para creación de chatbots, que seguro os ayudaran en vuestro día a día.
Para ver en acción esta técnica puedes descargarte el siguiente cuaderno Jupiter:
https://github.com/me-santiagomarquezsolis/NLP
Feliz coding 😉
Más artículos sobre esta serie: