Update python-chatGPT course

Signed-off-by: Manuel Vergara <manuel@vergaracarmona.es>
This commit is contained in:
Manuel Vergara 2023-06-10 22:49:39 +02:00
parent 91154fa094
commit 1b5a79be68
4 changed files with 104 additions and 9 deletions

View File

@ -663,10 +663,66 @@ Y para probarlo, vamos a añadir en las palabras_prohibidas la palabra "paella"
![](img/python-chatgpt12.png)
El fichero del código completo es [filtrar_palabras.py](src/08_filtrar_respuestas.py)
### 5.2. - Verificar respuestas Relevancia
Vamos a realizar tres pasos:
- Calcular similitudes
- Vectorizar los valores
- Interceptar la respuesta
### 5.3. - Limitaciones y consideraciones éticas
#### 5.2.1. - Calcular similitudes
Vamos a seguir con el chatbot para añadirle esta funcionalidad. Lo primero es instalar numpy que lo necesitaremos para realizar ciertos calculos. Importamos la biblioteca y le damos un alias:
```python
import numpy as np
```
Y vamos a crear una función con algunos principios matemáticos para aplicar a nuestro texto. Vamos a hacer que calcule lo que se llama la similitud coseno de dos vectores.
```python
def similitud_coseno(vec1, vec2):
superposicion = np.dot(vec1, vec2)
magnitud1 = np.linalg.norm(vec1) # Longitud del vector
magnitud2 = np.linalg.norm(vec2) # Longitud del vector
sim_cos = superposicion / (magnitud1 * magnitud2)
return sim_cos
```
El resultado de esta operación va a ser un valor entre -1 y uno. Este valor va a indicar la similitud, o sea, entre los dos vectores.
Si se obtiene un valor uno indica que los vectores son idénticos, que tienen el mismo ángulo si hablamos de números. Mientras que un valor de -1 indicaría que son completamente opuestos, que su ángulo es de 180 grados.
En el caso de los análisis de texto, que es lo que nos interesa a nosotros, los vectores se generan a partir de los textos utilizando un modelo de lenguaje como spacy que tiene la capacidad de convertir cada texto en un vector numérico que representa su contenido semántico, así como lo escuchas 🤯
Con lo cuál, la función similitud_coseno puede utilizarse para comparar estos vectores que son textos que han sido convertidos a valores numéricos según su valor semántico y así determinar cómo de similares son, en términos de contenido semántico.
#### 5.2.2. - Vectorizar los valores
Ahora, vamos a crear otra función que recogerá la respuesta y la entrada para calcular la similitud_coseno:
def es_relevante(respuesta, entrada, umbral=0.5):
```python
entrada_vectorizada = modelo_spacy(entrada).vector
respuesta_vectorizada = modelo_spacy(respuesta).vector
similitud = similitud_coseno(entrada_vectorizada, respuesta_vectorizada)
return similitud >= umbral
```
#### 5.2.3. - Interceptar la respuesta
Ahora ya volvemos al loop que da la dinámica y lógica al chatbot, justo antes de imprimir la respuesta debemos añadir en una variable la llamada a la función anterior y el print y la recogida de respuestas meterlas en un condicional si la respuesta el relevante, según nuestra función. Si es false
```python
relevante = es_relevante(respuesta_gpt, ingreso_usuario)
if relevante:
print(f"{respuesta_gpt}")
preguntas_anteriores.append(ingreso_usuario)
respuestas_anteriores.append(respuesta_gpt)
else:
print(Fore.RED + "La respuesta no es relevante ¿podrías reformularla?" + Fore.RESET)
```
Le he dado colorcito rojo a la respuesta errónea. Vamos a probarlo. Le pido un poema y le pregunto sobre mi opinión:
![](img/python-chatgpt13.png)
Y hasta aquí el curso. ¡Sigue cortando leña! 🪓
![](img/python-chatgpt14.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View File

@ -5,6 +5,7 @@ Chatbot con OpenAI GPT-3
import openai
import os
import spacy
import numpy as np
from dotenv import load_dotenv
from colorama import init, Fore
@ -24,10 +25,43 @@ init()
def clearConsole():
# Función limpiar consola
"""
Limpia la consola
"""
os.system('clear')
def similitud_coseno(vec1, vec2):
"""
Calcula la similitud coseno entre dos vectores
"""
superposicion = np.dot(vec1, vec2)
magnitud1 = np.linalg.norm(vec1) # Longitud del vector
magnitud2 = np.linalg.norm(vec2) # Longitud del vector
sim_cos = superposicion / (magnitud1 * magnitud2)
return sim_cos
def es_relevante(respuesta, entrada, umbral=0.2):
"""
Determina si una respuesta es relevante para una entrada
"""
entrada_vectorizada = modelo_spacy(entrada).vector
respuesta_vectorizada = modelo_spacy(respuesta).vector
# Ahora que tenemos las anteriores variables transformadas en vectores,
# podemos calcular la similitud coseno
similitud = similitud_coseno(entrada_vectorizada, respuesta_vectorizada)
# Si la similitud es mayor o igual al umbral, la respuesta es relevante
return similitud >= umbral
def filtrar_lista_negra(texto, lista_negra):
"""
Filtra palabras de una lista negra
@ -73,8 +107,8 @@ def preguntar_chat_gpt(prompt, modelo="text-davinci-002"):
# Bienvenida
clearConsole()
print(Fore.RED + "Bienvenido al chatbot de OpenAI GPT-3." + Fore.RESET)
print(Fore.RED + "Escribe \"salir\" cuando quieras terminar la conversación." + Fore.RESET)
print(Fore.BLUE + "Bienvenido al chatbot de OpenAI GPT-3." + Fore.RESET)
print(Fore.BLUE + "Escribe \"salir\" cuando quieras terminar la conversación." + Fore.RESET)
# Loop para controlar el flujo de la conversación
while True:
@ -94,7 +128,12 @@ while True:
conversacion_historica += prompt
respuesta_gpt = preguntar_chat_gpt(conversacion_historica)
print(f"{respuesta_gpt}")
relevante = es_relevante(respuesta_gpt, ingreso_usuario)
preguntas_anteriores.append(ingreso_usuario)
respuestas_anteriores.append(respuesta_gpt)
if relevante:
print(f"{respuesta_gpt}")
preguntas_anteriores.append(ingreso_usuario)
respuestas_anteriores.append(respuesta_gpt)
else:
print(Fore.RED + "La respuesta no es relevante ¿podrías reformularla?" + Fore.RESET)