#!/usr/bin/env python3
"""
Generador del documento .docx con normas APA 7 para la actividad Semana 7
Machine Learning Avanzado - NRC-8772
Automatización de procesos para el flujo de trabajo en Machine Learning

Autor: Grupo 10
"""

from docx import Document
from docx.shared import Pt, Inches, Cm, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.enum.table import WD_TABLE_ALIGNMENT
import datetime

def crear_documento():
    doc = Document()

    # =========================================================================
    # CONFIGURACIÓN GLOBAL APA 7
    # =========================================================================
    style = doc.styles['Normal']
    font = style.font
    font.name = 'Calibri'
    font.size = Pt(11)
    font.color.rgb = RGBColor(0, 0, 0)

    paragraph_format = style.paragraph_format
    paragraph_format.line_spacing = 2.0  # Interlineado doble
    paragraph_format.space_after = Pt(0)
    paragraph_format.space_before = Pt(0)

    # Márgenes APA: 2.54 cm en todos los lados
    for section in doc.sections:
        section.top_margin = Cm(2.54)
        section.bottom_margin = Cm(2.54)
        section.left_margin = Cm(2.54)
        section.right_margin = Cm(2.54)
        section.page_width = Inches(8.5)
        section.page_height = Inches(11)

    # =========================================================================
    # PORTADA APA 7
    # =========================================================================
    for _ in range(4):
        doc.add_paragraph('')

    # Título
    titulo = doc.add_paragraph()
    titulo.alignment = WD_ALIGN_PARAGRAPH.CENTER
    run = titulo.add_run('Informe de Proyecto: Automatización de Procesos para el\n'
                          'Flujo de Trabajo en Machine Learning con el Dataset del Titanic')
    run.bold = True
    run.font.size = Pt(12)
    run.font.name = 'Calibri'
    titulo.paragraph_format.line_spacing = 2.0

    doc.add_paragraph('')

    # Autores (Grupo 10)
    autor = doc.add_paragraph()
    autor.alignment = WD_ALIGN_PARAGRAPH.CENTER
    run = autor.add_run(
        'Grupo 10:\n'
        'Alexander Oviedo Fadul (Ponente)\n'
        'Maria Fernanda Ruiz Paipilla\n'
        'Neheman Samir Jaller Cerchiaro\n'
        'William David Obando Lopez'
    )
    run.font.size = Pt(11)
    run.font.name = 'Calibri'

    # Universidad
    universidad = doc.add_paragraph()
    universidad.alignment = WD_ALIGN_PARAGRAPH.CENTER
    run = universidad.add_run('Especialización en Inteligencia Artificial, Corporación Universitaria Minuto de Dios')
    run.font.size = Pt(11)
    run.font.name = 'Calibri'

    # Curso
    curso = doc.add_paragraph()
    curso.alignment = WD_ALIGN_PARAGRAPH.CENTER
    run = curso.add_run('NRC-8772: Machine Learning Avanzado')
    run.font.size = Pt(11)
    run.font.name = 'Calibri'

    # Profesor
    profesor = doc.add_paragraph()
    profesor.alignment = WD_ALIGN_PARAGRAPH.CENTER
    run = profesor.add_run('Profesor: Leonardo Valderrama García')
    run.font.size = Pt(11)
    run.font.name = 'Calibri'

    # Fecha
    fecha = doc.add_paragraph()
    fecha.alignment = WD_ALIGN_PARAGRAPH.CENTER
    run = fecha.add_run('21 de junio de 2026')
    run.font.size = Pt(11)
    run.font.name = 'Calibri'

    doc.add_page_break()

    # =========================================================================
    # ENLACES DEL PROYECTO
    # =========================================================================
    agregar_titulo_nivel1(doc, 'Enlaces de Acceso al Proyecto')

    p = doc.add_paragraph()
    p.paragraph_format.first_line_indent = Cm(1.27)
    p.paragraph_format.line_spacing = 2.0
    run = p.add_run('Para facilitar la revisión y reproducibilidad de las pruebas de este proyecto, '
                     'se proporcionan los accesos directos al video de sustentación y al entorno interactivo de código:')
    run.font.size = Pt(11)
    run.font.name = 'Calibri'

    # Enlace de Video
    p_video_label = doc.add_paragraph()
    p_video_label.paragraph_format.first_line_indent = Cm(1.27)
    run = p_video_label.add_run('🎥 Enlace del Video de Sustentación (YouTube):')
    run.bold = True
    run.font.size = Pt(11)

    p_video_link = doc.add_paragraph()
    p_video_link.alignment = WD_ALIGN_PARAGRAPH.CENTER
    run = p_video_link.add_run('https://youtu.be/imfwwE4tvMg')
    run.bold = True
    run.font.size = Pt(12)
    run.font.color.rgb = RGBColor(0, 102, 204)

    # Enlace de Colab
    p_colab_label = doc.add_paragraph()
    p_colab_label.paragraph_format.first_line_indent = Cm(1.27)
    run = p_colab_label.add_run('🚀 Enlace del Cuaderno Interactivo (Google Colab):')
    run.bold = True
    run.font.size = Pt(11)

    p_colab_link = doc.add_paragraph()
    p_colab_link.alignment = WD_ALIGN_PARAGRAPH.CENTER
    run = p_colab_link.add_run('https://colab.research.google.com/drive/1UFcyBiLMYu7WwMK4UlFYvfFq_wvpBDCB')
    run.bold = True
    run.font.size = Pt(12)
    run.font.color.rgb = RGBColor(0, 102, 204)

    doc.add_paragraph('')

    # Tabla de Datos
    agregar_titulo_nivel2(doc, 'Datos Generales del Proyecto')
    tabla_datos = doc.add_table(rows=8, cols=2)
    tabla_datos.style = 'Table Grid'
    tabla_datos.alignment = WD_TABLE_ALIGNMENT.CENTER

    datos = [
        ('Título del trabajo', 'Automatización de procesos para el flujo de trabajo en ML'),
        ('Nombres de integrantes', 'Grupo 10:\n- Alexander Oviedo Fadul\n- Maria Fernanda Ruiz Paipilla\n- Neheman Samir Jaller Cerchiaro\n- William David Obando Lopez'),
        ('Nombre del curso', 'NRC-8772: Machine Learning Avanzado'),
        ('Número de la semana', 'Semana 7'),
        ('Nombre del profesor', 'Leonardo Valderrama García'),
        ('Fecha de entrega', '21 de junio de 2026'),
        ('Framework principal', 'scikit-learn (Pipeline / ColumnTransformer)'),
        ('Enlace de Google Colab', 'https://colab.research.google.com/drive/1UFcyBiLMYu7WwMK4UlFYvfFq_wvpBDCB')
    ]

    for i, (campo, valor) in enumerate(datos):
        cell_campo = tabla_datos.cell(i, 0)
        cell_valor = tabla_datos.cell(i, 1)

        p1 = cell_campo.paragraphs[0]
        run1 = p1.add_run(campo)
        run1.bold = True
        run1.font.size = Pt(10)

        p2 = cell_valor.paragraphs[0]
        run2 = p2.add_run(valor)
        run2.font.size = Pt(10)

    doc.add_page_break()

    # =========================================================================
    # INTRODUCCIÓN Y METODOLOGÍA
    # =========================================================================
    agregar_titulo_nivel1(doc, 'Introducción')
    agregar_parrafo(doc, (
        'En la industria contemporánea del desarrollo de inteligencia artificial, la automatización '
        'de los flujos de trabajo en Machine Learning (MLOps) se ha convertido en un requisito '
        'técnico e industrial crítico. A medida que los modelos transicionan desde scripts experimentales '
        'en entornos locales a sistemas de toma de decisiones integrados en producción, '
        'asegurar la consistencia del preprocesamiento de datos y la reproducibilidad de los resultados '
        'es fundamental (Janiesch et al., 2021).'
    ))
    agregar_parrafo(doc, (
        'Este informe presenta la solución desarrollada por el Grupo 10 para modelar y evaluar '
        'la predicción de supervivencia en el histórico dataset del Titanic. El enfoque central del '
        'proyecto reside en la automatización del flujo de datos usando scikit-learn. Mediante '
        'estructuras como Pipelines y ColumnTransformers, encapsulamos las fases de imputación, '
        'codificación de variables categóricas, normalización de variables numéricas, ingeniería de '
        'características personalizada y optimización de hiperparámetros, previniendo fallas de '
        'diseño comunes como la fuga de datos (data leakage).'
    ))

    agregar_titulo_nivel1(doc, 'Diseño Metodológico del Flujo Automatizado')
    agregar_parrafo(doc, (
        'El flujo de trabajo se automatizó completamente mediante la librería scikit-learn en Python. '
        'En lugar de aplicar transformaciones de forma manual y aislada sobre el dataset completo, '
        'diseñamos una arquitectura modular compuesta por un preprocesador central de variables y '
        'estimadores de extremo a extremo.'
    ))

    agregar_titulo_nivel2(doc, 'Ingeniería de Características')
    agregar_parrafo(doc, (
        'Implementamos una etapa personalizada de feature engineering para extraer patrones que '
        'el modelo no podría identificar por sí solo: (a) family_size, que representa el tamaño de la '
        'familia a bordo sumando sibsp y parch más 1; (b) is_alone, una variable binaria que indica si '
        'el pasajero viajaba sin acompañantes; y (c) title, que extrae y limpia los títulos de cortesía '
        'de los nombres (Mr, Mrs, Miss, Master, etc.) para utilizarlos como un proxy social y de edad.'
    ))

    agregar_titulo_nivel2(doc, 'ColumnTransformer y Pipeline de Modelado')
    agregar_parrafo(doc, (
        'El preprocesador utiliza ColumnTransformer para aplicar tratamientos diferenciados: las variables '
        'numéricas pasan por un SimpleImputer con estrategia de mediana y un StandardScaler. Las variables '
        'categóricas se imputan con la moda (most_frequent) y se codifican con OneHotEncoder. Las binarias '
        'pasan sin alteración (passthrough). Finalmente, este preprocesador se conecta en serie con el clasificador '
        '(Random Forest o SVM) en un objeto Pipeline unificado.'
    ))

    doc.add_page_break()

    # =========================================================================
    # ANALISIS DE RESULTADOS
    # =========================================================================
    agregar_titulo_nivel1(doc, 'Resultados y Análisis Comparativo')
    agregar_parrafo(doc, (
        'Evaluamos dos familias de clasificadores: Random Forest (ensamble basado en árboles de decisión) '
        'y Support Vector Machine (SVM con kernel radial RBF). Para garantizar resultados óptimos, '
        'integramos una búsqueda de cuadrícula con GridSearchCV para optimizar los hiperparámetros '
        '(como la profundidad máxima en Random Forest y la regularización C y gamma en SVM).'
    ))

    agregar_titulo_nivel2(doc, 'Métricas en Validación Cruzada (5-Fold CV)')
    agregar_parrafo(doc, (
        'La validación cruzada con 5 particiones sobre el conjunto de entrenamiento nos brindó una estimación '
        'sólida del rendimiento de los modelos, libre de sobreajuste. A continuación, se resume el comportamiento '
        'de las métricas de rendimiento promedio (F1-score, Accuracy, Precision, Recall):'
    ))

    # Tabla de métricas
    tabla_met = doc.add_table(rows=5, cols=3)
    tabla_met.style = 'Table Grid'
    tabla_met.alignment = WD_TABLE_ALIGNMENT.CENTER

    met_data = [
        ('Métrica', 'Random Forest (Promedio CV)', 'SVM (Promedio CV)'),
        ('Accuracy', '81.46%', '81.60%'),
        ('Precision', '77.84%', '76.32%'),
        ('Recall', '74.20%', '76.01%'),
        ('F1-score', '75.92%', '76.15%')
    ]

    for i, (col1, col2, col3) in enumerate(met_data):
        for j, val in enumerate([col1, col2, col3]):
            cell = tabla_met.cell(i, j)
            p = cell.paragraphs[0]
            run = p.add_run(val)
            run.font.size = Pt(10)
            if i == 0:
                run.bold = True

    doc.add_paragraph('')
    agregar_parrafo(doc, (
        'El análisis comparativo demuestra que ambos modelos alcanzan un desempeño muy equilibrado, '
        'con un F1-score de validación en torno al 76% y un accuracy superior al 81%. SVM muestra un mejor '
        'recall (sensibilidad) promedio, detectando un mayor porcentaje de supervivientes reales, '
        'mientras que Random Forest destaca con una mayor precisión promedio (menor tasa de falsos positivos).'
    ))

    doc.add_page_break()

    # =========================================================================
    # PREGUNTAS ORIENTADORAS Y ETICA
    # =========================================================================
    agregar_titulo_nivel1(doc, 'Respuestas a Preguntas Orientadoras')
    
    agregar_titulo_nivel2(doc, '¿Cómo puede la automatización de procesos aumentar la eficiencia y precisión?')
    agregar_parrafo(doc, (
        'La automatización mediante Pipelines evita la fuga de datos al aplicar las transformaciones de escala '
        'e imputación de manera independiente en cada iteración de la validación cruzada, previniendo '
        'sobreestimaciones del rendimiento. Además, elimina el trabajo manual repetitivo de limpieza de datos '
        'y permite automatizar la búsqueda de parámetros sobre todo el flujo simultáneamente, garantizando '
        'consistencia técnica.'
    ))

    agregar_titulo_nivel2(doc, '¿Cuáles son las herramientas y técnicas utilizadas y sus casos de uso?')
    agregar_parrafo(doc, (
        'Las principales herramientas incluyen los Pipelines de scikit-learn para flujos locales, MLflow '
        'para el seguimiento de experimentos, y Vertex AI o Kubeflow Pipelines para orquestación en la nube. '
        'Se aplican en detección de fraudes, recomendaciones comerciales o predicción de fallas industriales, '
        'donde los modelos deben actualizarse y evaluarse continuamente ante la deriva de datos (data drift).'
    ))

    agregar_titulo_nivel1(doc, 'Dilemas Éticos y Sesgo Algorítmico')
    agregar_parrafo(doc, (
        'El análisis del dataset expone dilemas éticos abordados por Carsten (2020) y Béranger (2018). '
        'La supervivencia en el Titanic estuvo fuertemente determinada por el género ("mujeres y niños primero") '
        'y la clase socioeconómica del pasajero. Entrenar un modelo de IA con estos datos genera un sesgo algorítmico '
        'que simplemente replica y automatiza prejuicios históricos.'
    ))
    agregar_parrafo(doc, (
        'Si un sistema de asignación de rescates marítimos actual dependiera de este modelo de IA, '
        'discriminaría de forma automática a los hombres de clase trabajadora. Esto demuestra que '
        'los algoritmos no son neutros: heredan las desigualdades de los datos. De allí la necesidad '
        'de una gobernanza algorítmica y auditorías constantes de las características de entrada.'
    ))

    doc.add_page_break()

    # =========================================================================
    # CONCLUSIONES Y REFERENCIAS
    # =========================================================================
    agregar_titulo_nivel1(doc, 'Conclusiones')
    agregar_parrafo(doc, (
        '1. El diseño del pipeline modular simplificó la ingeniería de características y el procesamiento '
        'diferenciado de datos, resolviendo la fuga de datos (data leakage).'
    ))
    agregar_parrafo(doc, (
        '2. Random Forest y SVM demostraron comportamientos complementarios y competitivos, obteniendo '
        'un F1-score promedio del 76%.'
    ))
    agregar_parrafo(doc, (
        '3. La auditoría ética es indispensable para evitar que la IA automatice sesgos discriminatorios '
        'de los conjuntos de datos históricos.'
    ))

    agregar_titulo_nivel1(doc, 'Referencias')
    referencias = [
        'Béranger, J. (2018). The Framework for Algorithmic Processing. '
        'En The algorithmic code of ethics: Ethics at the bedside of the digital revolution (pp. 122-164). '
        'John Wiley & Sons, Incorporated.',
        
        'Campesato, O. (2020). Introduction to AI / Introduction to Machine Learning / Classifiers in Machine Learning. '
        'En Artificial intelligence, machine learning, and deep learning (pp. 1-66). '
        'Mercury Learning and Information.',
        
        'Carsten, B. (2020). Ethical Issues of AI / Addressing Ethical Issues in AI. En Artificial Intelligence for a Better Future: '
        'An Ecosystem Perspective on the Ethics of AI and Emerging Digital Technologies (pp. 35-64). Springer.',
        
        'Valderrama García, L. (2026, 20 de junio). Clase 7: Automatización de procesos para el flujo de trabajo en Machine Learning '
        '[Clase magistral]. NRC-8772 Machine Learning Avanzado, Corporación Universitaria Minuto de Dios.'
    ]

    for ref in referencias:
        p = doc.add_paragraph()
        p.paragraph_format.line_spacing = 2.0
        p.paragraph_format.first_line_indent = Cm(-1.27)
        p.paragraph_format.left_indent = Cm(1.27)
        run = p.add_run(ref)
        run.font.size = Pt(11)

    output_path = 'Grupo10_MLA_Automatizacion_S7.docx'
    doc.save(output_path)
    print(f'✅ Documento generado: {output_path}')
    return output_path

# =========================================================================
# FUNCIONES AUXILIARES
# =========================================================================
def agregar_titulo_nivel1(doc, texto):
    p = doc.add_paragraph()
    p.alignment = WD_ALIGN_PARAGRAPH.CENTER
    p.paragraph_format.line_spacing = 2.0
    p.paragraph_format.space_before = Pt(12)
    run = p.add_run(texto)
    run.bold = True
    run.font.size = Pt(11)

def agregar_titulo_nivel2(doc, texto):
    p = doc.add_paragraph()
    p.alignment = WD_ALIGN_PARAGRAPH.LEFT
    p.paragraph_format.line_spacing = 2.0
    p.paragraph_format.space_before = Pt(12)
    run = p.add_run(texto)
    run.bold = True
    run.font.size = Pt(11)

def agregar_parrafo(doc, texto):
    p = doc.add_paragraph()
    p.paragraph_format.line_spacing = 2.0
    p.paragraph_format.first_line_indent = Cm(1.27)
    run = p.add_run(texto)
    run.font.size = Pt(11)

if __name__ == '__main__':
    crear_documento()
