Skip to content
Project: Analyzing Car Reviews with LLMs
Car-ing is sharing, an auto dealership company for car sales and rental, is taking their services to the next level thanks to Large Language Models (LLMs).
As their newly recruited AI and NLP developer, you've been asked to prototype a chatbot app with multiple functionalities that not only assist customers but also provide support to human agents in the company.
The solution should receive textual prompts and use a variety of pre-trained Hugging Face LLMs to respond to a series of tasks, e.g. classifying the sentiment in a car’s text review, answering a customer question, summarizing or translating text, etc.
# Import necessary packages
import pandas as pd
import torch
from transformers import logging
logging.set_verbosity(logging.WARNING)# Start your code here!# Importar todas las librerías necesarias
import pandas as pd
import torch
from transformers import pipeline, AutoTokenizer, AutoModelForQuestionAnswering
import evaluate# Cargar el dataset de reseñas de automóviles
file_path = "data/car_reviews.csv"
df = pd.read_csv(file_path, delimiter=";")
# Extraer las reseñas y sus etiquetas de sentimiento en listas
reviews = df['Review'].tolist()
real_labels = df['Class'].tolist()
print(f"Número de reseñas cargadas: {len(reviews)}")
print(f"\nPrimera reseña:")
print(reviews[0])# TAREA 1: CLASIFICACIÓN DE SENTIMIENTO
print("TAREA 1: CLASIFICACIÓN DE SENTIMIENTO")
print("-" * 50)
# Cargar un LLM de análisis de sentimiento en un pipeline
classifier = pipeline('sentiment-analysis', model='distilbert-base-uncased-finetuned-sst-2-english')
# Realizar inferencia en las reseñas de automóviles y mostrar resultados de predicción
predicted_labels = classifier(reviews)
print("\nResultados de predicción:")
for review, prediction, label in zip(reviews, predicted_labels, real_labels):
print(f"Review: {review}")
print(f"Sentimiento real: {label}")
print(f"Sentimiento predicho: {prediction['label']} (Confianza: {prediction['score']:.4f})\n")
# Cargar métricas de accuracy y F1 score
accuracy = evaluate.load("accuracy")
f1 = evaluate.load("f1")
# Mapear etiquetas categóricas de sentimiento a etiquetas enteras
references = [1 if label == "POSITIVE" else 0 for label in real_labels]
predictions = [1 if label['label'] == "POSITIVE" else 0 for label in predicted_labels]
# Calcular accuracy y F1 score
accuracy_result_dict = accuracy.compute(references=references, predictions=predictions)
accuracy_result = accuracy_result_dict['accuracy']
f1_result_dict = f1.compute(references=references, predictions=predictions)
f1_result = f1_result_dict['f1']
print("\nRESULTADOS DE EVALUACIÓN:")
print(f"Accuracy: {accuracy_result:.4f}")
print(f"F1 Score: {f1_result:.4f}")# TAREA 2: TRADUCCIÓN
print("TAREA 2: TRADUCCIÓN AL ESPAÑOL")
print("-" * 50)
# Obtener la primera reseña
first_review = reviews[0]
print(f"\nReseña original:")
print(first_review)
# Cargar el LLM de traducción en un pipeline y traducir la reseña
translator = pipeline("translation", model="Helsinki-NLP/opus-mt-en-es")
translated_review = translator(first_review, max_length=27)[0]['translation_text']
print(f"\nTraducción del modelo:")
print(translated_review)
# Cargar traducciones de referencia desde el archivo
with open("data/reference_translations.txt", 'r') as file:
lines = file.readlines()
references = [line.strip() for line in lines]
print(f"\nTraducciones de referencia en español:")
for i, ref in enumerate(references, 1):
print(f"{i}. {ref}")
# Cargar y calcular la métrica BLEU score
bleu = evaluate.load("bleu")
bleu_score = bleu.compute(predictions=[translated_review], references=[references])
print(f"\nRESULTADOS DE TRADUCCIÓN:")
print(f"BLEU Score: {bleu_score['bleu']}")# TAREA 3: PREGUNTAS Y RESPUESTAS EXTRACTIVAS
print("TAREA 3: PREGUNTAS Y RESPUESTAS EXTRACTIVAS")
print("-" * 50)
# Importar clases automáticas de transformers
# Nota: también se puede resolver usando pipelines
# Instanciar modelo y tokenizador
model_ckp = "deepset/minilm-uncased-squad2"
tokenizer = AutoTokenizer.from_pretrained(model_ckp)
model = AutoModelForQuestionAnswering.from_pretrained(model_ckp)
# Definir contexto y pregunta
context = reviews[1]
question = "What did he like about the brand?"
print(f"\nContexto:")
print(context)
print(f"\nPregunta: {question}")
# Tokenizar contexto y pregunta
inputs = tokenizer(question, context, return_tensors="pt")
# Realizar inferencia y extraer respuesta de las salidas crudas
with torch.no_grad():
outputs = model(**inputs)
# Identificar posiciones de inicio y fin de la respuesta
start_idx = torch.argmax(outputs.start_logits)
end_idx = torch.argmax(outputs.end_logits) + 1
# Extraer el span de la respuesta
answer_span = inputs["input_ids"][0][start_idx:end_idx]
# Decodificar y mostrar respuesta
answer = tokenizer.decode(answer_span)
print(f"\nRespuesta: {answer}")# TAREA 4: RESUMEN DE TEXTO
print("TAREA 4: RESUMEN DE TEXTO")
print("-" * 50)
# Obtener el texto original para resumir de la última reseña
text_to_summarize = reviews[-1]
print(f"\nTexto original:")
print(text_to_summarize)
print(f"Longitud: {len(text_to_summarize.split())} palabras")
# Cargar pipeline de resumen y realizar inferencia
model_name = "cnicu/t5-small-booksum"
summarizer = pipeline("summarization", model=model_name)
outputs = summarizer(text_to_summarize, max_length=53)
summarized_text = outputs[0]['summary_text']
print(f"\nTexto resumido:")
print(summarized_text)
print(f"Longitud: {len(summarized_text.split())} palabras")