Skip to content

💬 Unidad 8. Aplicaciones Avanzadas de NLP

Esta unidad cubre aplicaciones avanzadas y casos de uso prácticos del NLP en el mundo real, incluyendo chatbots, sistemas de preguntas y respuestas, resumen automático y traducción automática.


8.1. Sistemas de Preguntas y Respuestas (QA)

Los sistemas de Question Answering (QA) responden preguntas en lenguaje natural basándose en un contexto o base de conocimiento.

Tipos de QA

Tipo Descripción Ejemplo
Extractivo Extrae la respuesta directamente del texto "¿Quién fundó Apple?" → "Steve Jobs" (del contexto)
Generativo Genera una respuesta en lenguaje natural Respuesta elaborada basada en múltiples fuentes
Open-domain Responde sobre cualquier tema Wikipedia QA
Closed-domain Responde sobre un dominio específico QA médico, legal

QA Extractivo con Transformers

from transformers import pipeline

# Pipeline de QA
qa_pipeline = pipeline("question-answering")

# Contexto
contexto = """
Apple Inc. es una empresa tecnológica estadounidense fundada en 1976 por Steve Jobs, 
Steve Wozniak y Ronald Wayne. La compañía tiene su sede en Cupertino, California.
Apple es conocida por productos como el iPhone, iPad, Mac y Apple Watch.
En 2023, Apple alcanzó una valoración de mercado de 3 billones de dólares.
"""

# Preguntas
preguntas = [
    "¿Quién fundó Apple?",
    "¿Dónde está la sede de Apple?",
    "¿Cuál es la valoración de Apple?",
    "¿Cuándo se fundó Apple?"
]

print("Sistema de Preguntas y Respuestas")
print("=" * 50)

for pregunta in preguntas:
    resultado = qa_pipeline(question=pregunta, context=contexto)
    print(f"\nP: {pregunta}")
    print(f"R: {resultado['answer']} (confianza: {resultado['score']:.3f})")

QA con Retrieval (RAG - Retrieval Augmented Generation)

from sentence_transformers import SentenceTransformer
from transformers import pipeline
import numpy as np

# Base de conocimiento
documentos = [
    "Python es un lenguaje de programación de alto nivel creado por Guido van Rossum en 1991.",
    "JavaScript fue creado por Brendan Eich en 1995 para Netscape.",
    "Java fue desarrollado por James Gosling en Sun Microsystems en 1995.",
    "C++ fue creado por Bjarne Stroustrup comenzando en 1979.",
    "Rust es un lenguaje de programación de sistemas desarrollado por Mozilla desde 2010."
]

# Modelo de embeddings para retrieval
embedder = SentenceTransformer('paraphrase-multilingual-MiniLM-L12-v2')
doc_embeddings = embedder.encode(documentos)

# Pipeline de QA
qa_pipeline = pipeline("question-answering")

def responder_pregunta_rag(pregunta, documentos, doc_embeddings, embedder, qa_pipeline, top_k=2):
    """
    Sistema RAG: Retrieve + Generate
    """
    # 1. Retrieve: Encontrar documentos relevantes
    query_embedding = embedder.encode(pregunta)
    similarities = np.dot(doc_embeddings, query_embedding)
    top_indices = similarities.argsort()[-top_k:][::-1]

    # Contexto relevante
    contexto = " ".join([documentos[i] for i in top_indices])

    # 2. Generate: Responder usando el contexto
    resultado = qa_pipeline(question=pregunta, context=contexto)

    return {
        'pregunta': pregunta,
        'respuesta': resultado['answer'],
        'confianza': resultado['score'],
        'documentos_usados': [documentos[i] for i in top_indices]
    }

# Probar
pregunta = "¿Quién creó Python?"
resultado = responder_pregunta_rag(pregunta, documentos, doc_embeddings, embedder, qa_pipeline)

print(f"Pregunta: {resultado['pregunta']}")
print(f"Respuesta: {resultado['respuesta']}")
print(f"Confianza: {resultado['confianza']:.3f}")
print(f"Documentos consultados: {resultado['documentos_usados']}")

8.2. Chatbots y Asistentes Conversacionales

Arquitectura de un Chatbot

┌─────────────────────────────────────────────────────┐
│                    Usuario                           │
└─────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────┐
│              NLU (Natural Language Understanding)    │
│  - Intent Classification                             │
│  - Entity Extraction                                 │
└─────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────┐
│              Dialog Manager                          │
│  - State Tracking                                    │
│  - Policy Selection                                  │
└─────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────┐
│              NLG (Natural Language Generation)       │
│  - Response Generation                               │
│  - Template Filling                                  │
└─────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────┐
│                    Respuesta                         │
└─────────────────────────────────────────────────────┘

Chatbot Simple con Reglas

import re
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import LogisticRegression

class ChatbotSimple:
    def __init__(self):
        self.intents = {
            'saludo': {
                'patterns': ['hola', 'buenos días', 'buenas tardes', 'qué tal'],
                'responses': ['¡Hola! ¿En qué puedo ayudarte?', '¡Buenos días! ¿Cómo puedo asistirte?']
            },
            'despedida': {
                'patterns': ['adiós', 'hasta luego', 'chao', 'nos vemos'],
                'responses': ['¡Hasta luego!', '¡Que tengas un buen día!']
            },
            'precio': {
                'patterns': ['cuánto cuesta', 'precio', 'valor', 'cuánto vale'],
                'responses': ['Nuestros precios varían. ¿Qué producto te interesa?']
            },
            'ayuda': {
                'patterns': ['ayuda', 'necesito ayuda', 'cómo funciona', 'help'],
                'responses': ['Puedo ayudarte con información de productos, precios y pedidos.']
            },
            'default': {
                'patterns': [],
                'responses': ['No entiendo tu pregunta. ¿Podrías reformularla?']
            }
        }

        self._entrenar_clasificador()

    def _entrenar_clasificador(self):
        textos = []
        labels = []

        for intent, data in self.intents.items():
            if intent != 'default':
                for pattern in data['patterns']:
                    textos.append(pattern)
                    labels.append(intent)

        self.vectorizer = TfidfVectorizer()
        X = self.vectorizer.fit_transform(textos)

        self.clf = LogisticRegression()
        self.clf.fit(X, labels)

    def responder(self, mensaje):
        import random

        # Preprocesar
        mensaje_limpio = mensaje.lower().strip()

        # Clasificar intent
        X = self.vectorizer.transform([mensaje_limpio])
        intent = self.clf.predict(X)[0]
        confianza = self.clf.predict_proba(X).max()

        # Si confianza baja, usar default
        if confianza < 0.3:
            intent = 'default'

        # Seleccionar respuesta
        respuestas = self.intents[intent]['responses']
        respuesta = random.choice(respuestas)

        return {
            'intent': intent,
            'confianza': confianza,
            'respuesta': respuesta
        }

# Usar chatbot
bot = ChatbotSimple()

mensajes = [
    "Hola, buenos días",
    "¿Cuánto cuesta el producto?",
    "Necesito ayuda por favor",
    "Adiós, gracias",
    "¿Cuál es el clima hoy?"  # Fuera de dominio
]

print("Chatbot Demo")
print("=" * 50)
for msg in mensajes:
    resultado = bot.responder(msg)
    print(f"\nUsuario: {msg}")
    print(f"Bot: {resultado['respuesta']}")
    print(f"  (intent: {resultado['intent']}, conf: {resultado['confianza']:.2f})")

Chatbot con LLM

from openai import OpenAI

class ChatbotLLM:
    def __init__(self, api_key, system_prompt=None):
        self.client = OpenAI(api_key=api_key)
        self.system_prompt = system_prompt or """
        Eres un asistente virtual amable y útil. 
        Respondes de forma concisa y clara.
        Si no sabes algo, lo admites honestamente.
        """
        self.historial = []

    def responder(self, mensaje_usuario):
        # Añadir mensaje al historial
        self.historial.append({
            "role": "user",
            "content": mensaje_usuario
        })

        # Llamar a la API
        response = self.client.chat.completions.create(
            model="gpt-3.5-turbo",
            messages=[
                {"role": "system", "content": self.system_prompt}
            ] + self.historial,
            temperature=0.7,
            max_tokens=500
        )

        respuesta = response.choices[0].message.content

        # Añadir respuesta al historial
        self.historial.append({
            "role": "assistant",
            "content": respuesta
        })

        return respuesta

    def reiniciar_conversacion(self):
        self.historial = []

# Uso
# bot_llm = ChatbotLLM(api_key="tu-api-key")
# print(bot_llm.responder("¿Qué es el machine learning?"))

8.3. Resumen Automático de Texto

Tipos de Resumen

Tipo Descripción Método
Extractivo Selecciona oraciones importantes del texto original TextRank, BERT extractivo
Abstractivo Genera un nuevo texto que resume el contenido T5, BART, GPT

Resumen Extractivo (TextRank)

from sumy.parsers.plaintext import PlaintextParser
from sumy.nlp.tokenizers import Tokenizer
from sumy.summarizers.text_rank import TextRankSummarizer

def resumir_extractivo(texto, num_oraciones=3):
    """
    Resumen extractivo usando TextRank.
    """
    parser = PlaintextParser.from_string(texto, Tokenizer("spanish"))
    summarizer = TextRankSummarizer()

    resumen = summarizer(parser.document, num_oraciones)

    return " ".join([str(oracion) for oracion in resumen])

# Texto largo de ejemplo
texto_largo = """
La inteligencia artificial ha experimentado un crecimiento exponencial en los últimos años.
Los avances en deep learning han permitido crear sistemas capaces de reconocer imágenes,
traducir idiomas y mantener conversaciones naturales con humanos.

Empresas como Google, Microsoft y OpenAI lideran la investigación en este campo.
Los modelos de lenguaje como GPT-4 pueden generar texto indistinguible del escrito por humanos.
Esto ha generado debates sobre el futuro del trabajo y la ética en la IA.

A pesar de los avances, los expertos advierten que la IA actual no posee verdadera comprensión
o consciencia. Los sistemas actuales son herramientas sofisticadas de reconocimiento de patrones.
El camino hacia la inteligencia artificial general (AGI) aún es largo e incierto.
"""

resumen = resumir_extractivo(texto_largo, num_oraciones=2)
print("Resumen Extractivo:")
print(resumen)

Resumen Abstractivo con Transformers

from transformers import pipeline

# Pipeline de resumen
summarizer = pipeline("summarization", model="facebook/bart-large-cnn")

# Texto en inglés (modelos en inglés funcionan mejor)
texto_en = """
Artificial intelligence has experienced exponential growth in recent years.
Advances in deep learning have enabled systems capable of recognizing images,
translating languages, and having natural conversations with humans.
Companies like Google, Microsoft, and OpenAI lead research in this field.
Language models like GPT-4 can generate text indistinguishable from human writing.
This has sparked debates about the future of work and AI ethics.
"""

resumen = summarizer(texto_en, max_length=50, min_length=20, do_sample=False)
print("Resumen Abstractivo:")
print(resumen[0]['summary_text'])

Resumen en Español con mT5

from transformers import MT5ForConditionalGeneration, MT5Tokenizer

# Cargar modelo multilingüe
model_name = "google/mt5-small"
tokenizer = MT5Tokenizer.from_pretrained(model_name)
model = MT5ForConditionalGeneration.from_pretrained(model_name)

def resumir_mt5(texto, max_length=100):
    """
    Resumen con mT5 (multilingüe).
    """
    # Prefijo para tarea de resumen
    input_text = f"summarize: {texto}"

    inputs = tokenizer(input_text, return_tensors="pt", max_length=512, truncation=True)

    outputs = model.generate(
        inputs["input_ids"],
        max_length=max_length,
        min_length=20,
        length_penalty=2.0,
        num_beams=4,
        early_stopping=True
    )

    resumen = tokenizer.decode(outputs[0], skip_special_tokens=True)
    return resumen

# Ejemplo
# resumen_es = resumir_mt5(texto_largo)
# print(resumen_es)

8.4. Traducción Automática

Traducción con MarianMT

from transformers import MarianMTModel, MarianTokenizer

def traducir(texto, src_lang="es", tgt_lang="en"):
    """
    Traduce texto entre idiomas usando MarianMT.
    """
    # Cargar modelo para el par de idiomas
    model_name = f"Helsinki-NLP/opus-mt-{src_lang}-{tgt_lang}"
    tokenizer = MarianTokenizer.from_pretrained(model_name)
    model = MarianMTModel.from_pretrained(model_name)

    # Tokenizar
    inputs = tokenizer(texto, return_tensors="pt", padding=True, truncation=True)

    # Traducir
    translated = model.generate(**inputs)

    # Decodificar
    resultado = tokenizer.decode(translated[0], skip_special_tokens=True)
    return resultado

# Ejemplos
texto_es = "El procesamiento de lenguaje natural permite a las máquinas entender el lenguaje humano."
texto_en = traducir(texto_es, "es", "en")
print(f"Original (ES): {texto_es}")
print(f"Traducido (EN): {texto_en}")

# Traducción inversa
texto_back = traducir(texto_en, "en", "es")
print(f"Back-translation: {texto_back}")

Traducción con Pipeline

from transformers import pipeline

# Pipeline de traducción
translator = pipeline("translation", model="Helsinki-NLP/opus-mt-es-en")

textos_es = [
    "Buenos días, ¿cómo estás?",
    "Me gusta programar en Python.",
    "El aprendizaje automático es fascinante."
]

print("Traducciones ES → EN:")
for texto in textos_es:
    resultado = translator(texto)[0]['translation_text']
    print(f"  {texto}")
    print(f"  → {resultado}")
    print()

8.5. Generación de Texto

Completado de Texto

from transformers import pipeline

# Pipeline de generación
generator = pipeline("text-generation", model="gpt2")

# Prompt
prompt = "The future of artificial intelligence will"

# Generar
resultado = generator(
    prompt,
    max_length=100,
    num_return_sequences=3,
    temperature=0.8,
    top_p=0.9
)

print("Generaciones:")
for i, gen in enumerate(resultado):
    print(f"\n{i+1}. {gen['generated_text']}")

Generación Controlada

from transformers import pipeline

# Generador con control de estilo
generator = pipeline("text-generation", model="gpt2-medium")

prompts_con_estilo = [
    "Write a formal email: Dear Mr. Smith,",
    "Write a casual text message: Hey!",
    "Write a news headline: BREAKING:"
]

for prompt in prompts_con_estilo:
    resultado = generator(prompt, max_length=50, num_return_sequences=1)
    print(f"Prompt: {prompt}")
    print(f"Output: {resultado[0]['generated_text']}")
    print("-" * 50)

8.6. Detección de Texto Generado por IA

Con el auge de los LLMs, detectar texto generado por IA es cada vez más importante.

from transformers import pipeline

# Detector de texto IA (ejemplo conceptual)
# Nota: Los detectores actuales no son 100% precisos

def analizar_texto_ia(texto):
    """
    Heurísticas simples para detectar texto generado por IA.
    """
    señales = {
        'longitud_oraciones': [],
        'palabras_repetidas': {},
        'conectores_comunes': 0
    }

    # Analizar longitud de oraciones
    oraciones = texto.split('.')
    señales['longitud_oraciones'] = [len(o.split()) for o in oraciones if o.strip()]

    # Variabilidad de longitud (IA tiende a ser más uniforme)
    if señales['longitud_oraciones']:
        variabilidad = np.std(señales['longitud_oraciones'])
    else:
        variabilidad = 0

    # Conectores comunes en texto de IA
    conectores_ia = ['además', 'sin embargo', 'por lo tanto', 'en conclusión', 
                     'furthermore', 'however', 'therefore', 'in conclusion']

    texto_lower = texto.lower()
    for conector in conectores_ia:
        if conector in texto_lower:
            señales['conectores_comunes'] += 1

    # Score simple
    score_ia = 0.5  # Base

    if variabilidad < 5:  # Poca variabilidad
        score_ia += 0.2

    if señales['conectores_comunes'] >= 3:
        score_ia += 0.2

    return {
        'score_ia': min(score_ia, 1.0),
        'señales': señales,
        'prediccion': 'Probablemente IA' if score_ia > 0.6 else 'Probablemente humano'
    }

# Ejemplo
import numpy as np

texto_sospechoso = """
La inteligencia artificial ha revolucionado muchos campos. Sin embargo, también 
presenta desafíos. Por lo tanto, es importante considerarlos. Además, debemos 
ser conscientes de las implicaciones éticas. En conclusión, la IA es una 
herramienta poderosa que debe usarse responsablemente.
"""

resultado = analizar_texto_ia(texto_sospechoso)
print(f"Score IA: {resultado['score_ia']:.2f}")
print(f"Predicción: {resultado['prediccion']}")

8.7. Aplicaciones Empresariales

Extracción de Información de Documentos

import spacy
from collections import defaultdict

nlp = spacy.load('es_core_news_lg')

def extraer_informacion_contrato(texto):
    """
    Extrae información clave de un contrato.
    """
    doc = nlp(texto)

    info = {
        'partes': [],
        'fechas': [],
        'montos': [],
        'ubicaciones': []
    }

    for ent in doc.ents:
        if ent.label_ in ['PER', 'ORG']:
            info['partes'].append(ent.text)
        elif ent.label_ == 'DATE':
            info['fechas'].append(ent.text)
        elif ent.label_ == 'MONEY':
            info['montos'].append(ent.text)
        elif ent.label_ in ['LOC', 'GPE']:
            info['ubicaciones'].append(ent.text)

    # Eliminar duplicados
    for key in info:
        info[key] = list(set(info[key]))

    return info

# Ejemplo
contrato = """
El presente contrato se celebra entre Empresa ABC S.A. y Juan Pérez García,
con fecha 15 de enero de 2024 en Madrid, España.
El monto total del contrato es de 50.000 euros, pagaderos en 12 meses.
"""

info_contrato = extraer_informacion_contrato(contrato)
print("Información extraída del contrato:")
for key, values in info_contrato.items():
    if values:
        print(f"  {key}: {', '.join(values)}")

Análisis de Feedback de Clientes

from collections import Counter
import pandas as pd

def analizar_feedback(comentarios, sentiment_pipeline):
    """
    Analiza feedback de clientes para obtener insights.
    """
    resultados = []

    for comentario in comentarios:
        # Análisis de sentimiento
        sent = sentiment_pipeline(comentario)[0]

        resultados.append({
            'comentario': comentario[:50] + '...' if len(comentario) > 50 else comentario,
            'sentimiento': sent['label'],
            'score': sent['score']
        })

    df = pd.DataFrame(resultados)

    # Resumen
    resumen = {
        'total_comentarios': len(comentarios),
        'distribucion_sentimiento': df['sentimiento'].value_counts().to_dict(),
        'score_promedio': df['score'].mean(),
        'ejemplos_negativos': df[df['sentimiento'] == 'NEGATIVE'].head(3)['comentario'].tolist()
    }

    return resumen

# Ejemplo conceptual
# comentarios = ["Excelente producto!", "Muy mal servicio", "Normal, nada especial"]
# resumen = analizar_feedback(comentarios, sentiment_pipeline)

8.8. Consideraciones Éticas y Mejores Prácticas

Sesgos en NLP

  • Los modelos heredan sesgos de los datos de entrenamiento.
  • Evaluar y mitigar sesgos de género, raza, etc.
  • Usar datasets diversos y representativos.

Privacidad

  • Los modelos pueden memorizar información sensible.
  • Implementar técnicas de anonimización.
  • Cumplir con regulaciones (GDPR, etc.).

Transparencia

  • Documentar limitaciones de los modelos.
  • Proporcionar explicaciones cuando sea posible.
  • Informar a usuarios cuando interactúan con IA.

Uso Responsable

  • No generar desinformación o contenido dañino.
  • Implementar filtros y salvaguardas.
  • Considerar el impacto social de las aplicaciones.

📅 Fecha de creación: Enero 2026
✍️ Autor: Fran García