{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "provenance": []
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "source": [
        "**Nota:** Este cuaderno está diseñado para **Google Colab**.\n",
        "\n",
        "Si ves el logotipo de Colab <span style='vertical-align:bottom;'><img src='https://colab.research.google.com/img/colab_favicon_256px.png' width='40' alt='Logotipo de Colab'></span> en la esquina superior izquierda, ¡ya está todo listo! Por favor, **continúa**.\n",
        "\n",
        "Si no ves el logotipo (por ejemplo, estás en GitHub), haz clic en el botón de abajo para abrirlo en el entorno correcto:\n",
        "\n",
        "[![Abrir en Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/mparrott-at-wiris/aimodelshare/blob/master/notebooks/justice_and_equity_advance_notebook_es.ipynb)"
      ],
      "metadata": {
        "id": "pjnUTfUOGMX3"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# **Reto Avanzado de Justicia y Equidad: Construir y Enviar Modelos Personalizados**\n",
        "\n",
        "Bienvenido a la **Vía Avanzada** del Reto de Justicia de Ética en Juego (Ethics at Play).\n",
        "\n",
        "**¿Para quién es esto?**\n",
        "Este cuaderno está diseñado para participantes con experiencia en Python (por ejemplo, Scikit-Learn, TensorFlow, PyTorch). En lugar de usar las aplicaciones gamificadas, construirás, entrenarás y enviarás tus propios modelos de aprendizaje automático directamente a la tabla de clasificación de la competencia.\n",
        "\n",
        "**El Objetivo:**\n",
        "Entrenar un modelo para predecir el riesgo de reincidencia (la probabilidad de volver a delinquir) utilizando el conjunto de datos COMPAS, equilibrando la precisión y la equidad."
      ],
      "metadata": {
        "id": "intro_advanced"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "## 🚀 **Guía de Inicio Rápido**\n",
        "\n",
        "Para participar en el reto, completa estos 5 pasos:\n",
        "\n",
        "1.  **Instalar Bibliotecas:** Ejecuta la celda de configuración para instalar `aimodelshare`.\n",
        "2.  **Obtener los Datos:** Ejecuta la celda de carga de datos para recuperar los datos de entrenamiento y prueba pre-divididos.\n",
        "3.  **Entrenar tu Modelo:** Usa el ejemplo de Pipeline de Scikit-Learn proporcionado o escribe tu propio código de entrenamiento personalizado.\n",
        "4.  **Conectar:** Vincula este cuaderno a la Tabla de Clasificación del Reto de Justicia.\n",
        "5.  **Enviar:** Envía tus predicciones a la tabla de clasificación para ver tu puntuación.\n",
        "\n",
        "**¿Listo? Haz clic en el botón de reproducción ▶ en la primera celda de abajo para comenzar.**"
      ],
      "metadata": {
        "id": "quick_start_guide"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "---\n",
        "# **Paso 1: Instalación**\n",
        "\n",
        "Necesitamos instalar la biblioteca `aimodelshare` para conectarnos al backend de la competencia."
      ],
      "metadata": {
        "id": "step1_md"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# Instalar la biblioteca aimodelshare\n",
        "print(\"Instalando las bibliotecas necesarias...\")\n",
        "!pip install aimodelshare --upgrade -q --no-warn-script-location > /dev/null 2>&1\n",
        "print(\"✅ ¡Instalación completada!\")"
      ],
      "metadata": {
        "id": "step1_code"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "---\n",
        "# **Paso 2: Cargar Datos**\n",
        "\n",
        "Cargaremos los datos de entrenamiento y prueba directamente desde las URL oficiales de la competencia.\n",
        "\n",
        "* **X_train:** Características para el entrenamiento.\n",
        "* **y_train:** Etiquetas objetivo (¿ocurrió reincidencia?) para el entrenamiento.\n",
        "* **X_test:** Características para la prueba (generarás predicciones sobre esto)."
      ],
      "metadata": {
        "id": "step2_md"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "import pandas as pd\n",
        "\n",
        "# 1. Cargar Datos desde las URL\n",
        "X_train = pd.read_csv(\"https://raw.githubusercontent.com/AIModelShare/aimodelshare_tutorials/refs/heads/main/datasets/ethicsatplay/X_train.csv\")\n",
        "X_test = pd.read_csv(\"https://raw.githubusercontent.com/AIModelShare/aimodelshare_tutorials/refs/heads/main/datasets/ethicsatplay/X_test.csv\")\n",
        "y_train_labels = pd.read_csv(\"https://raw.githubusercontent.com/AIModelShare/aimodelshare_tutorials/refs/heads/main/datasets/ethicsatplay/y_train.csv\")\n",
        "\n",
        "# Asegurar que y_train es una Serie 1D (requerido para sklearn)\n",
        "y_train = y_train_labels.squeeze()\n",
        "\n",
        "# 2. Definir Listas de Características para el Pipeline\n",
        "# Estas listas coinciden con las columnas presentes en X_train y X_test\n",
        "ALL_NUMERIC_COLS = [\"juv_fel_count\", \"juv_misd_count\", \"juv_other_count\", \"days_b_screening_arrest\", \"age\", \"length_of_stay\", \"priors_count\"]\n",
        "ALL_CATEGORICAL_COLS = [\"race\", \"sex\", \"c_charge_degree\", \"c_charge_desc\"]\n",
        "\n",
        "print(\"✅ ¡Datos cargados exitosamente!\")\n",
        "print(f\"Forma de los datos de entrenamiento: {X_train.shape}\")\n",
        "print(f\"Forma de los datos de prueba: {X_test.shape}\")\n",
        "print(\"\\nPrimeras 5 filas de los datos de entrenamiento:\")\n",
        "X_train.head()"
      ],
      "metadata": {
        "id": "step2_code"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "---\n",
        "# **Paso 3: Entrenar el Modelo con la Biblioteca Preferida (Sklearn, Tensorflow, Pytorch, Etc.)**\n",
        "\n",
        "Usaremos un **Pipeline de Scikit-Learn** para agilizar el preprocesamiento y el modelado.\n",
        "\n",
        "Este pipeline:\n",
        "1.  **Imputará Valores Faltantes** (Rellena NaNs con la mediana para números, el más frecuente para categorías).\n",
        "2.  **Codificará One-Hot** las columnas categóricas (Raza, Sexo, Grado del Cargo, Descripción del Cargo).\n",
        "3.  **Escalará** las columnas numéricas (Edad, Antecedentes, Duración de la Estancia, etc.).\n",
        "4.  **Entrenará** un clasificador de Regresión Logística."
      ],
      "metadata": {
        "id": "step3_md"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "from sklearn.pipeline import Pipeline\n",
        "from sklearn.compose import ColumnTransformer\n",
        "from sklearn.preprocessing import OneHotEncoder, StandardScaler\n",
        "from sklearn.impute import SimpleImputer\n",
        "from sklearn.linear_model import LogisticRegression\n",
        "\n",
        "# 1. Definir grupos de características usando constantes del Paso 2\n",
        "# Las características numéricas serán imputadas y escaladas\n",
        "numeric_features = ALL_NUMERIC_COLS\n",
        "\n",
        "# Las características categóricas serán imputadas y codificadas con One-Hot\n",
        "categorical_features = ALL_CATEGORICAL_COLS\n",
        "\n",
        "# 2. Definir Transformadores con Imputación\n",
        "# Numérico: Imputar valores faltantes con la mediana, luego escalar\n",
        "numeric_transformer = Pipeline(steps=[\n",
        "    ('imputer', SimpleImputer(strategy='median')),\n",
        "    ('scaler', StandardScaler())\n",
        "])\n",
        "\n",
        "# Categórico: Imputar valores faltantes con el valor más frecuente, luego codificar con one-hot\n",
        "categorical_transformer = Pipeline(steps=[\n",
        "    ('imputer', SimpleImputer(strategy='most_frequent')),\n",
        "    ('encoder', OneHotEncoder(handle_unknown='ignore'))\n",
        "])\n",
        "\n",
        "# 3. Crear Preprocesador usando los transformadores\n",
        "preprocessor = ColumnTransformer(\n",
        "    transformers=[\n",
        "        ('num', numeric_transformer, numeric_features),\n",
        "        ('cat', categorical_transformer, categorical_features)\n",
        "    ])\n",
        "\n",
        "# 4. Crear Pipeline (Preprocesador + Modelo)\n",
        "# Puedes reemplazar LogisticRegression con cualquier otro modelo de sklearn (ej. RandomForestClassifier)\n",
        "pipeline = Pipeline(steps=[\n",
        "    ('preprocessor', preprocessor),\n",
        "    ('classifier', LogisticRegression(max_iter=1000))\n",
        "])\n",
        "\n",
        "# 5. Entrenar el pipeline\n",
        "pipeline.fit(X_train, y_train)\n",
        "\n",
        "# 6. Generar predicciones en el conjunto de prueba\n",
        "predictions = pipeline.predict(X_test)\n",
        "\n",
        "print(f\"✅ ¡Modelo Entrenado! Predicciones generadas para {len(predictions)} muestras.\")\n",
        "print(\"Procede al siguiente paso para enviar tus predicciones a la tabla de clasificación.\")"
      ],
      "metadata": {
        "id": "step3_code"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "---\n",
        "# **Paso 4: Conectar a la Tabla de Clasificación**\n",
        "\n",
        "Este paso conecta tu cuaderno al backend específico para el Reto de Justicia y Equidad.\n",
        "\n",
        "*Nota: Se te pedirá que ingreses un nombre de usuario y contraseña. Si no tienes uno, deberás crear uno en [modelshare.ai](https://www.modelshare.ai)"
      ],
      "metadata": {
        "id": "step4_md"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "from aimodelshare.aws import set_credentials\n",
        "from aimodelshare.playground import Competition\n",
        "import os\n",
        "\n",
        "import warnings\n",
        "warnings.simplefilter(action='ignore', category=FutureWarning)\n",
        "\n",
        "\n",
        "# La URL específica del Model Playground para el Reto de Justicia\n",
        "my_playground_url = \"https://cf3wdpkg0d.execute-api.us-east-1.amazonaws.com/prod/m\"\n",
        "\n",
        "# Configura tus credenciales (aparecerá una ventana emergente)\n",
        "set_credentials(apiurl=my_playground_url)\n",
        "\n",
        "# Generar tu token de acceso a la sesión\n",
        "token=os.getenv(\"AWS_TOKEN\")\n",
        "\n",
        "# Conectar a la competencia\n",
        "playground = Competition(my_playground_url)"
      ],
      "metadata": {
        "id": "step4_code"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "---\n",
        "# **Paso 5: Enviar y Verificar Resultados**\n",
        "\n",
        "Envía tus predicciones a la tabla de clasificación."
      ],
      "metadata": {
        "id": "step5_md"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# 1. Enviar tus predicciones\n",
        "# Nota: Pasamos None para el modelo y preprocesador porque solo estamos enviando predicciones para evaluación\n",
        "playground.submit_model(\n",
        "    model=None,\n",
        "    preprocessor=None,\n",
        "    prediction_submission=predictions, token=token,\n",
        "    input_dict={\n",
        "        \"Team\": \"Los Buscadores de Equidad\", # Cambia el nombre del equipo manualmente si es necesario.\n",
        "        \"description\": \"Regresión Logística con Pipeline de Sklearn\",\n",
        "        \"tags\": \"sklearn, logistic_regression, advanced_pathway, pipeline\"\n",
        "    }\n",
        ")\n",
        "\n",
        "print(\"✅ ¡Predicciones enviadas exitosamente!\")\n",
        "\n",
        "# 2. Verificar la tabla de clasificación\n",
        "print(\"Cargando tabla de clasificación...\")\n",
        "leaderboard = playground.get_leaderboard()\n",
        "playground.stylize_leaderboard(leaderboard)"
      ],
      "metadata": {
        "id": "step5_code"
      },
      "execution_count": null,
      "outputs": []
    }
  ]
}
