{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Tu primer scorecard con bayesrisk\n",
    "\n",
    "Este cuaderno construye un **scorecard de riesgo de crédito** de punta a punta y deja el\n",
    "informe, el registro de auditoría y los libros de Excel listos para revisar. Las salidas\n",
    "que ves abajo son **reales**: se generaron ejecutando este mismo cuaderno.\n",
    "\n",
    "Lo que necesitas antes de empezar:\n",
    "\n",
    "```bash\n",
    "pip install \"bayesrisk[scoring,report,excel,ui]\"\n",
    "```\n",
    "\n",
    "Y nada más. No hay que configurar el motor: los valores de fábrica funcionan, y lo que sí\n",
    "decide la institución —qué es un incumplimiento, qué muestra queda fuera de tiempo— se\n",
    "pide de forma explícita.\n",
    "\n",
    "Las rutas de las salidas se muestran relativas a la carpeta de este cuaderno."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. Los datos\n",
    "\n",
    "Usamos una cartera de consumo sintética que viene en el paquete (6.000 operaciones,\n",
    "determinista), para que este cuaderno corra igual en cualquier máquina. En tu caso, `datos`\n",
    "es la ruta de tu `.parquet` o `.csv`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "execution_count": 1,
     "data": {
      "text/plain": [
       "           ingreso_mensual  deuda_ingreso  ...  cohorte  bad_flag\n",
       "loan_id                                    ...                   \n",
       "op-000000        332752.50         0.2874  ...   2023Q2         0\n",
       "op-000001        377467.40         0.4386  ...   2023Q1         0\n",
       "op-000002       1663079.61         0.1881  ...   2024Q1         0\n",
       "op-000003        472874.83         0.4824  ...   2024Q2         1\n",
       "op-000004        321162.90         0.1270  ...   2024Q1         1\n",
       "\n",
       "[5 rows x 8 columns]"
      ],
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>ingreso_mensual</th>\n",
       "      <th>deuda_ingreso</th>\n",
       "      <th>utilizacion_linea</th>\n",
       "      <th>mora_max_12m</th>\n",
       "      <th>antiguedad_meses</th>\n",
       "      <th>segmento</th>\n",
       "      <th>cohorte</th>\n",
       "      <th>bad_flag</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>loan_id</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>op-000000</th>\n",
       "      <td>332752.50</td>\n",
       "      <td>0.2874</td>\n",
       "      <td>0.4299</td>\n",
       "      <td>6</td>\n",
       "      <td>87</td>\n",
       "      <td>pensionado</td>\n",
       "      <td>2023Q2</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>op-000001</th>\n",
       "      <td>377467.40</td>\n",
       "      <td>0.4386</td>\n",
       "      <td>0.2493</td>\n",
       "      <td>6</td>\n",
       "      <td>84</td>\n",
       "      <td>pensionado</td>\n",
       "      <td>2023Q1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>op-000002</th>\n",
       "      <td>1663079.61</td>\n",
       "      <td>0.1881</td>\n",
       "      <td>0.5301</td>\n",
       "      <td>6</td>\n",
       "      <td>3</td>\n",
       "      <td>asalariado</td>\n",
       "      <td>2024Q1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>op-000003</th>\n",
       "      <td>472874.83</td>\n",
       "      <td>0.4824</td>\n",
       "      <td>0.1010</td>\n",
       "      <td>10</td>\n",
       "      <td>7</td>\n",
       "      <td>independiente</td>\n",
       "      <td>2024Q2</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>op-000004</th>\n",
       "      <td>321162.90</td>\n",
       "      <td>0.1270</td>\n",
       "      <td>0.5967</td>\n",
       "      <td>5</td>\n",
       "      <td>33</td>\n",
       "      <td>asalariado</td>\n",
       "      <td>2024Q1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ]
     },
     "metadata": {}
    }
   ],
   "source": [
    "from pathlib import Path\n",
    "\n",
    "import pandas as pd\n",
    "\n",
    "from bayesrisk import Scorecard\n",
    "from bayesrisk.ui.datasets import materialize\n",
    "\n",
    "datos = materialize(\"consumo_comportamiento\", workdir=Path(\"bayesrisk-runs\"))\n",
    "\n",
    "pd.read_parquet(datos).head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. La corrida completa\n",
    "\n",
    "`Scorecard(...)` pide sólo lo institucional: cuál es la columna de incumplimiento, cuál\n",
    "identifica la operación y cómo se separan las muestras. Todo lo demás —el esquema, qué\n",
    "columnas son predictoras, cuáles son categóricas— **se infiere y se declara** en el\n",
    "registro de auditoría.\n",
    "\n",
    "`run()` corre las once etapas y **cada una cuenta lo que hizo** mientras avanza."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "── Datos y muestras ──\n",
      "Archivo: bayesrisk-runs\\datasets\\consumo_comportamiento.parquet (copia en bayesrisk-runs\\consumo_v01\\input\\data-f7e0ff42e1fc1c9d.parquet)\n",
      "6.000 filas · 1.407 malos (23,45 %) · 8 columnas\n",
      "Muestras: Desarrollo 3.961 (23,33 %) · Holdout 1.031 (23,67 %) · Fuera de tiempo (OOT) 1.008 (23,71 %) — cohortes fuera de tiempo: 2024Q2 (columna «cohorte»); holdout 20 % del resto\n",
      "Se infirió: esquema de 8 columnas (6 numéricas o de fecha, 2 de texto); 6 predictoras (1 categórica); fuera: cohorte (cohorte de la partición), bad_flag (define el incumplimiento, sería una fuga de información)\n",
      "Identificador: loan_id (índice del archivo)\n",
      "Evidencia de la corrida: bayesrisk-runs\\consumo_v01\\run\n",
      "── Análisis exploratorio ──\n",
      "Tasa de malos por cohorte: 5 períodos, media 23,33 %\n",
      "Deterioro de la tasa en el tiempo: no evaluable (eje de cohorte, sin orden cronológico)\n",
      "6 columnas descritas frente al incumplimiento\n",
      "Marcas de calidad del archivo: casi única: ingreso_mensual\n",
      "── Tramos y WoE ──\n",
      "6 de 6 variables tramificadas\n",
      "Poder predictivo (IV): fuerte: ingreso_mensual · medio: deuda_ingreso · débil: utilizacion_linea, mora_max_12m, antiguedad_meses · sin poder: segmento\n",
      "⚠ antiguedad_meses: la tasa de malos invierte la tendencia en Holdout\n",
      "⚠ deuda_ingreso: la tasa de malos invierte la tendencia en Fuera de tiempo (OOT)\n",
      "⚠ ingreso_mensual: la tasa de malos invierte la tendencia en Fuera de tiempo (OOT)\n",
      "⚠ mora_max_12m: la tasa de malos invierte la tendencia en Holdout y Fuera de tiempo (OOT)\n",
      "── Selección de variables ──\n",
      "Entran 5 de 6 variables candidatas\n",
      "Salen: segmento (IV insuficiente)\n",
      "Correlación máxima entre las finales 0,030 y VIF máximo 1,00\n",
      "── Modelo ──\n",
      "Variables finales (5): antiguedad_meses, deuda_ingreso, ingreso_mensual, mora_max_12m, utilizacion_linea\n",
      "Stepwise bidireccional: 5 iteraciones, 5 entradas y 0 salidas\n",
      "Ajuste en Desarrollo: pseudo-R² de McFadden 0,097 · AIC 3898,7 · p-valor del test de razón de verosimilitud < 0,001 · convergió\n",
      "⚠ Concentra más del 90 % del IV del modelo: ingreso_mensual\n",
      "── Tarjeta de puntuación ──\n",
      "Escala: 20 puntos por duplicar las odds, 600 puntos a odds 50:1 (factor 28,85, desplazamiento 487,12)\n",
      "Puntajes observados: de 446 a 622 (media 526,1)\n",
      "5 variables con puntos; un puntaje más alto indica menor riesgo\n",
      "── Calibración ──\n",
      "Método: desplazamiento del intercepto (intercept offset); ancla a través del ciclo (TTC): la tasa de incumplimiento observada en Desarrollo = 23,33 %\n",
      "PD media en Desarrollo: cruda 23,33 % → calibrada 23,33 % (desplazamiento del intercepto -0,0000)\n",
      "Orden de riesgo preservado\n",
      "── Desempeño ──\n",
      "Desarrollo: AUC 0,712 · Gini 0,425 · KS 0,320\n",
      "Holdout: AUC 0,695 · Gini 0,389 · KS 0,312\n",
      "Fuera de tiempo (OOT): AUC 0,656 · Gini 0,312 · KS 0,252\n",
      "Caída Desarrollo → Fuera de tiempo (OOT): AUC -0,056 (-7,9 %) · KS -0,068 (-21,3 %)\n",
      "── Estabilidad ──\n",
      "Desarrollo vs. Holdout: peor PSI 0,0132 (PD calibrada) → Estable\n",
      "Desarrollo vs. OOT: peor PSI 0,0068 (score) → Estable\n",
      "CSI más alto: mora_max_12m (0,0102)\n",
      "Estabilidad temporal del score por cohorte: 6 períodos\n",
      "── Validación formal ──\n",
      "Estado técnico: Falla — lo decide Hosmer-Lemeshow en Fuera de tiempo (OOT) (p-valor 0,013; PD media agregada 23,34 % frente a 23,71 % observada)\n",
      "3 pruebas con veredicto, 1 fallida; familias: discriminación, calibración y estabilidad\n",
      "El estado técnico es una síntesis del motor; el veredicto lo firma un validador\n",
      "⚠ Estado técnico «Falla»: revisar Hosmer-Lemeshow en Fuera de tiempo (OOT) (p-valor 0,013; PD media agregada 23,34 % frente a 23,71 % observada)\n",
      "── Informe y ficha ──\n",
      "Informe HTML: bayesrisk-runs\\consumo_v01\\reports\\scorecard_report.html\n",
      "Informe Word: bayesrisk-runs\\consumo_v01\\reports\\scorecard_report.docx\n",
      "Informe PDF: no se generó (falta el extra de PDF o su motor nativo)\n",
      "Fuente editable (Quarto): bayesrisk-runs\\consumo_v01\\reports\\scorecard_report.qmd\n",
      "Registro de auditoría: bayesrisk-runs\\consumo_v01\\run\\audit_trail.jsonl\n",
      "Ejecución: completada\n",
      "Validación técnica: Falla — lo decide Hosmer-Lemeshow en Fuera de tiempo (OOT) (p-valor 0,013; PD media agregada 23,34 % frente a 23,71 % observada)\n"
     ]
    },
    {
     "output_type": "execute_result",
     "execution_count": 2,
     "data": {
      "text/plain": [
       "Scorecard(name='consumo_v01', project_dir='bayesrisk-runs\\\\consumo_v01', estado='done')"
      ],
      "text/html": [
       "<div class=\"bayesrisk-summary\"><h2>Resumen del scorecard</h2><p><b>Ejecución:</b> completada</p><p><b>Validación técnica:</b> Falla — lo decide Hosmer-Lemeshow en Fuera de tiempo (OOT) (p-valor 0,013; PD media agregada 23,34 % frente a 23,71 % observada)</p><table><tbody><tr><th>AUC en Fuera de tiempo (OOT)</th><td>0,656</td></tr><tr><th>Gini en Fuera de tiempo (OOT)</th><td>0,312</td></tr><tr><th>KS en Fuera de tiempo (OOT)</th><td>0,252</td></tr><tr><th>Caída del AUC Desarrollo → Fuera de tiempo (OOT)</th><td>-0,056 (-7,9 %)</td></tr><tr><th>Peor PSI entre score y PD</th><td>0,0132 (Desarrollo vs. Holdout) → Estable</td></tr></tbody></table><h4>Qué revisar</h4><ul><li>⚠ Tramos y WoE: antiguedad_meses: la tasa de malos invierte la tendencia en Holdout</li><li>⚠ Tramos y WoE: deuda_ingreso: la tasa de malos invierte la tendencia en Fuera de tiempo (OOT)</li><li>⚠ Tramos y WoE: ingreso_mensual: la tasa de malos invierte la tendencia en Fuera de tiempo (OOT)</li><li>⚠ Tramos y WoE: mora_max_12m: la tasa de malos invierte la tendencia en Holdout y Fuera de tiempo (OOT)</li><li>⚠ Modelo: Concentra más del 90 % del IV del modelo: ingreso_mensual</li><li>⚠ Validación formal: Estado técnico «Falla»: revisar Hosmer-Lemeshow en Fuera de tiempo (OOT) (p-valor 0,013; PD media agregada 23,34 % frente a 23,71 % observada)</li></ul><h4>Decisiones humanas registradas</h4><ul><li>Ninguna decisión humana registrada; lo que se decidió vive en el config de la corrida.</li></ul><h4>Dónde quedó cada archivo</h4><ul><li>Carpeta del proyecto: <code>bayesrisk-runs\\consumo_v01</code></li><li>Config vigente: <code>bayesrisk-runs\\consumo_v01\\config.yaml</code></li><li>Evidencia de la corrida: <code>bayesrisk-runs\\consumo_v01\\run</code></li><li>Registro de auditoría: <code>bayesrisk-runs\\consumo_v01\\run\\audit_trail.jsonl</code></li><li>Informe HTML: <code>bayesrisk-runs\\consumo_v01\\reports\\scorecard_report.html</code></li><li>Informe Word: <code>bayesrisk-runs\\consumo_v01\\reports\\scorecard_report.docx</code></li><li>Fuente editable (Quarto): <code>bayesrisk-runs\\consumo_v01\\reports\\scorecard_report.qmd</code></li></ul></div>"
      ]
     },
     "metadata": {}
    }
   ],
   "source": [
    "sc = Scorecard(\n",
    "    data=datos,\n",
    "    target=\"bad_flag\",          # 1 = malo\n",
    "    id=\"loan_id\",\n",
    "    cohort=\"cohorte\",           # la añada de cada operación\n",
    "    oot_cohorts=[\"2024Q2\"],     # la muestra fuera de tiempo la decide la institución\n",
    "    name=\"consumo_v01\",\n",
    ")\n",
    "sc.run()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. Mirar una etapa por dentro\n",
    "\n",
    "Cada etapa deja su resumen y su tabla de decisión. Aquí, la selección de variables: qué\n",
    "entró, qué salió y **por qué**."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "execution_count": 3,
     "data": {
      "text/plain": [
       "         Variable Entra          Motivo    IV   AUC    KS Correlación máxima  VIF IV Desarrollo IV Holdout IV Fuera de tiempo (OOT)\n",
       " antiguedad_meses    sí       inclusión 0,041 0,548 0,061                  — 1,00         0,041      0,109                    0,101\n",
       "    deuda_ingreso    sí       inclusión 0,164 0,602 0,160                  — 1,00         0,164      0,107                    0,170\n",
       "  ingreso_mensual    sí       inclusión 0,305 0,647 0,212                  — 1,00         0,305      0,252                    0,140\n",
       "     mora_max_12m    sí       inclusión 0,022 0,540 0,064                  — 1,00         0,022      0,033                    0,081\n",
       "         segmento    no IV insuficiente 0,003 0,515 0,023                  —    —         0,003      0,009                    0,006\n",
       "utilizacion_linea    sí       inclusión 0,061 0,566 0,098                  — 1,00         0,061      0,219                    0,085"
      ],
      "text/html": [
       "<table class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th>Variable</th>\n",
       "      <th>Entra</th>\n",
       "      <th>Motivo</th>\n",
       "      <th>IV</th>\n",
       "      <th>AUC</th>\n",
       "      <th>KS</th>\n",
       "      <th>Correlación máxima</th>\n",
       "      <th>VIF</th>\n",
       "      <th>IV Desarrollo</th>\n",
       "      <th>IV Holdout</th>\n",
       "      <th>IV Fuera de tiempo (OOT)</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>antiguedad_meses</td>\n",
       "      <td>sí</td>\n",
       "      <td>inclusión</td>\n",
       "      <td>0,041</td>\n",
       "      <td>0,548</td>\n",
       "      <td>0,061</td>\n",
       "      <td>—</td>\n",
       "      <td>1,00</td>\n",
       "      <td>0,041</td>\n",
       "      <td>0,109</td>\n",
       "      <td>0,101</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>deuda_ingreso</td>\n",
       "      <td>sí</td>\n",
       "      <td>inclusión</td>\n",
       "      <td>0,164</td>\n",
       "      <td>0,602</td>\n",
       "      <td>0,160</td>\n",
       "      <td>—</td>\n",
       "      <td>1,00</td>\n",
       "      <td>0,164</td>\n",
       "      <td>0,107</td>\n",
       "      <td>0,170</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>ingreso_mensual</td>\n",
       "      <td>sí</td>\n",
       "      <td>inclusión</td>\n",
       "      <td>0,305</td>\n",
       "      <td>0,647</td>\n",
       "      <td>0,212</td>\n",
       "      <td>—</td>\n",
       "      <td>1,00</td>\n",
       "      <td>0,305</td>\n",
       "      <td>0,252</td>\n",
       "      <td>0,140</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>mora_max_12m</td>\n",
       "      <td>sí</td>\n",
       "      <td>inclusión</td>\n",
       "      <td>0,022</td>\n",
       "      <td>0,540</td>\n",
       "      <td>0,064</td>\n",
       "      <td>—</td>\n",
       "      <td>1,00</td>\n",
       "      <td>0,022</td>\n",
       "      <td>0,033</td>\n",
       "      <td>0,081</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>segmento</td>\n",
       "      <td>no</td>\n",
       "      <td>IV insuficiente</td>\n",
       "      <td>0,003</td>\n",
       "      <td>0,515</td>\n",
       "      <td>0,023</td>\n",
       "      <td>—</td>\n",
       "      <td>—</td>\n",
       "      <td>0,003</td>\n",
       "      <td>0,009</td>\n",
       "      <td>0,006</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>utilizacion_linea</td>\n",
       "      <td>sí</td>\n",
       "      <td>inclusión</td>\n",
       "      <td>0,061</td>\n",
       "      <td>0,566</td>\n",
       "      <td>0,098</td>\n",
       "      <td>—</td>\n",
       "      <td>1,00</td>\n",
       "      <td>0,061</td>\n",
       "      <td>0,219</td>\n",
       "      <td>0,085</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>"
      ]
     },
     "metadata": {}
    }
   ],
   "source": [
    "sc.results[\"selection\"]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4. Una decisión humana\n",
    "\n",
    "El modelador manda. `exclude(...)` —siempre con su `reason=`— escribe el config y queda en\n",
    "el registro de auditoría con autor y motivo. `resume()` es una **corrida nueva y completa**\n",
    "sobre el config vigente: la anterior queda al lado como respaldo, con su informe.\n",
    "\n",
    "Aquí sacamos una variable que en la práctica no está disponible al originar el crédito."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "Decisión registrada: exclude mora_max_12m — «no estará disponible al originar». Se aplica en la corrida siguiente: resume().\n",
      "── Datos y muestras ──\n",
      "Archivo: bayesrisk-runs\\datasets\\consumo_comportamiento.parquet (copia en bayesrisk-runs\\consumo_v01\\input\\data-f7e0ff42e1fc1c9d.parquet)\n",
      "6.000 filas · 1.407 malos (23,45 %) · 8 columnas\n",
      "Muestras: Desarrollo 3.961 (23,33 %) · Holdout 1.031 (23,67 %) · Fuera de tiempo (OOT) 1.008 (23,71 %) — cohortes fuera de tiempo: 2024Q2 (columna «cohorte»); holdout 20 % del resto\n",
      "Se infirió: esquema de 8 columnas (6 numéricas o de fecha, 2 de texto); 6 predictoras (1 categórica); fuera: cohorte (cohorte de la partición), bad_flag (define el incumplimiento, sería una fuga de información)\n",
      "Identificador: loan_id (índice del archivo)\n",
      "Evidencia de la corrida: bayesrisk-runs\\consumo_v01\\run\n",
      "── Análisis exploratorio ──\n",
      "Tasa de malos por cohorte: 5 períodos, media 23,33 %\n",
      "Deterioro de la tasa en el tiempo: no evaluable (eje de cohorte, sin orden cronológico)\n",
      "6 columnas descritas frente al incumplimiento\n",
      "Marcas de calidad del archivo: casi única: ingreso_mensual\n",
      "── Tramos y WoE ──\n",
      "5 de 5 variables tramificadas\n",
      "Poder predictivo (IV): fuerte: ingreso_mensual · medio: deuda_ingreso · débil: utilizacion_linea, antiguedad_meses · sin poder: segmento\n",
      "⚠ antiguedad_meses: la tasa de malos invierte la tendencia en Holdout\n",
      "⚠ deuda_ingreso: la tasa de malos invierte la tendencia en Fuera de tiempo (OOT)\n",
      "⚠ ingreso_mensual: la tasa de malos invierte la tendencia en Fuera de tiempo (OOT)\n",
      "── Selección de variables ──\n",
      "Entran 4 de 5 variables candidatas\n",
      "Salen: segmento (IV insuficiente)\n",
      "Correlación máxima entre las finales 0,014 y VIF máximo 1,00\n",
      "── Modelo ──\n",
      "Variables finales (4): antiguedad_meses, deuda_ingreso, ingreso_mensual, utilizacion_linea\n",
      "Stepwise bidireccional: 4 iteraciones, 4 entradas y 0 salidas\n",
      "Ajuste en Desarrollo: pseudo-R² de McFadden 0,094 · AIC 3909,7 · p-valor del test de razón de verosimilitud < 0,001 · convergió\n",
      "⚠ Concentra más del 90 % del IV del modelo: ingreso_mensual\n",
      "── Tarjeta de puntuación ──\n",
      "Escala: 20 puntos por duplicar las odds, 600 puntos a odds 50:1 (factor 28,85, desplazamiento 487,12)\n",
      "Puntajes observados: de 441 a 624 (media 526,0)\n",
      "4 variables con puntos; un puntaje más alto indica menor riesgo\n",
      "── Calibración ──\n",
      "Método: desplazamiento del intercepto (intercept offset); ancla a través del ciclo (TTC): la tasa de incumplimiento observada en Desarrollo = 23,33 %\n",
      "PD media en Desarrollo: cruda 23,33 % → calibrada 23,33 % (desplazamiento del intercepto 0,0000)\n",
      "Orden de riesgo preservado\n",
      "── Desempeño ──\n",
      "Desarrollo: AUC 0,709 · Gini 0,418 · KS 0,309\n",
      "Holdout: AUC 0,696 · Gini 0,392 · KS 0,298\n",
      "Fuera de tiempo (OOT): AUC 0,648 · Gini 0,295 · KS 0,232\n",
      "Caída Desarrollo → Fuera de tiempo (OOT): AUC -0,062 (-8,7 %) · KS -0,077 (-25,0 %)\n",
      "── Estabilidad ──\n",
      "Desarrollo vs. Holdout: peor PSI 0,0057 (PD calibrada) → Estable\n",
      "Desarrollo vs. OOT: peor PSI 0,0172 (score) → Estable\n",
      "CSI más alto: ingreso_mensual (0,0098)\n",
      "Estabilidad temporal del score por cohorte: 6 períodos\n",
      "── Validación formal ──\n",
      "Estado técnico: Falla — lo decide Hosmer-Lemeshow en Fuera de tiempo (OOT) (p-valor 0,026; PD media agregada 23,31 % frente a 23,71 % observada)\n",
      "3 pruebas con veredicto, 1 fallida; familias: discriminación, calibración y estabilidad\n",
      "El estado técnico es una síntesis del motor; el veredicto lo firma un validador\n",
      "⚠ Estado técnico «Falla»: revisar Hosmer-Lemeshow en Fuera de tiempo (OOT) (p-valor 0,026; PD media agregada 23,31 % frente a 23,71 % observada)\n",
      "── Informe y ficha ──\n",
      "Informe HTML: bayesrisk-runs\\consumo_v01\\reports\\scorecard_report.html\n",
      "Informe Word: bayesrisk-runs\\consumo_v01\\reports\\scorecard_report.docx\n",
      "Informe PDF: no se generó (falta el extra de PDF o su motor nativo)\n",
      "Fuente editable (Quarto): bayesrisk-runs\\consumo_v01\\reports\\scorecard_report.qmd\n",
      "Registro de auditoría: bayesrisk-runs\\consumo_v01\\run\\audit_trail.jsonl\n",
      "Ejecución: completada\n",
      "Validación técnica: Falla — lo decide Hosmer-Lemeshow en Fuera de tiempo (OOT) (p-valor 0,026; PD media agregada 23,31 % frente a 23,71 % observada)\n"
     ]
    },
    {
     "output_type": "execute_result",
     "execution_count": 4,
     "data": {
      "text/plain": [
       "Scorecard(name='consumo_v01', project_dir='bayesrisk-runs\\\\consumo_v01', estado='done')"
      ],
      "text/html": [
       "<div class=\"bayesrisk-summary\"><h2>Resumen del scorecard</h2><p><b>Ejecución:</b> completada</p><p><b>Validación técnica:</b> Falla — lo decide Hosmer-Lemeshow en Fuera de tiempo (OOT) (p-valor 0,026; PD media agregada 23,31 % frente a 23,71 % observada)</p><table><tbody><tr><th>AUC en Fuera de tiempo (OOT)</th><td>0,648</td></tr><tr><th>Gini en Fuera de tiempo (OOT)</th><td>0,295</td></tr><tr><th>KS en Fuera de tiempo (OOT)</th><td>0,232</td></tr><tr><th>Caída del AUC Desarrollo → Fuera de tiempo (OOT)</th><td>-0,062 (-8,7 %)</td></tr><tr><th>Peor PSI entre score y PD</th><td>0,0172 (Desarrollo vs. OOT) → Estable</td></tr></tbody></table><h4>Qué revisar</h4><ul><li>⚠ Tramos y WoE: antiguedad_meses: la tasa de malos invierte la tendencia en Holdout</li><li>⚠ Tramos y WoE: deuda_ingreso: la tasa de malos invierte la tendencia en Fuera de tiempo (OOT)</li><li>⚠ Tramos y WoE: ingreso_mensual: la tasa de malos invierte la tendencia en Fuera de tiempo (OOT)</li><li>⚠ Modelo: Concentra más del 90 % del IV del modelo: ingreso_mensual</li><li>⚠ Validación formal: Estado técnico «Falla»: revisar Hosmer-Lemeshow en Fuera de tiempo (OOT) (p-valor 0,026; PD media agregada 23,31 % frente a 23,71 % observada)</li></ul><h4>Decisiones humanas registradas</h4><ul><li>exclude mora_max_12m — «no estará disponible al originar»</li></ul><h4>Dónde quedó cada archivo</h4><ul><li>Carpeta del proyecto: <code>bayesrisk-runs\\consumo_v01</code></li><li>Config vigente: <code>bayesrisk-runs\\consumo_v01\\config.yaml</code></li><li>Evidencia de la corrida: <code>bayesrisk-runs\\consumo_v01\\run</code></li><li>Registro de auditoría: <code>bayesrisk-runs\\consumo_v01\\run\\audit_trail.jsonl</code></li><li>Informe HTML: <code>bayesrisk-runs\\consumo_v01\\reports\\scorecard_report.html</code></li><li>Informe Word: <code>bayesrisk-runs\\consumo_v01\\reports\\scorecard_report.docx</code></li><li>Fuente editable (Quarto): <code>bayesrisk-runs\\consumo_v01\\reports\\scorecard_report.qmd</code></li></ul></div>"
      ]
     },
     "metadata": {}
    }
   ],
   "source": [
    "sc.exclude(\"mora_max_12m\", reason=\"no estará disponible al originar\")\n",
    "sc.resume()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 5. El resumen final\n",
    "\n",
    "Separa dos cosas que no son lo mismo: si la corrida **terminó** y si el modelo **pasa** la\n",
    "validación técnica. Las cinco cifras clave se leen de un vistazo."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "execution_count": 5,
     "data": {
      "text/plain": [
       "FinalSummary(execution='completada', validation='Falla — lo decide Hosmer-Lemeshow en Fuera de tiempo (OOT) (p-valor 0,026; PD media agregada 23,31 % frente a 23,71 % observada)', figures=(('AUC en Fuera de tiempo (OOT)', '0,648'), ('Gini en Fuera de tiempo (OOT)', '0,295'), ('KS en Fuera de tiempo (OOT)', '0,232'), ('Caída del AUC Desarrollo → Fuera de tiempo (OOT)', '-0,062 (-8,7 %)'), ('Peor PSI entre score y PD', '0,0172 (Desarrollo vs. OOT) → Estable')), review=('Tramos y WoE: antiguedad_meses: la tasa de malos invierte la tendencia en Holdout', 'Tramos y WoE: deuda_ingreso: la tasa de malos invierte la tendencia en Fuera de tiempo (OOT)', 'Tramos y WoE: ingreso_mensual: la tasa de malos invierte la tendencia en Fuera de tiempo (OOT)', 'Modelo: Concentra más del 90 % del IV del modelo: ingreso_mensual', 'Validación formal: Estado técnico «Falla»: revisar Hosmer-Lemeshow en Fuera de tiempo (OOT) (p-valor 0,026; PD media agregada 23,31 % frente a 23,71 % observada)'), decisions=('exclude mora_max_12m — «no estará disponible al originar»',), files=(('Carpeta del proyecto', 'bayesrisk-runs\\\\consumo_v01'), ('Config vigente', 'bayesrisk-runs\\\\consumo_v01\\\\config.yaml'), ('Evidencia de la corrida', 'bayesrisk-runs\\\\consumo_v01\\\\run'), ('Registro de auditoría', 'bayesrisk-runs\\\\consumo_v01\\\\run\\\\audit_trail.jsonl'), ('Informe HTML', 'bayesrisk-runs\\\\consumo_v01\\\\reports\\\\scorecard_report.html'), ('Informe Word', 'bayesrisk-runs\\\\consumo_v01\\\\reports\\\\scorecard_report.docx'), ('Fuente editable (Quarto)', 'bayesrisk-runs\\\\consumo_v01\\\\reports\\\\scorecard_report.qmd')), stages=(StageSummary(stage='data', label='Datos y muestras', lines=('Archivo: bayesrisk-runs\\\\datasets\\\\consumo_comportamiento.parquet (copia en bayesrisk-runs\\\\consumo_v01\\\\input\\\\data-f7e0ff42e1fc1c9d.parquet)', '6.000 filas · 1.407 malos (23,45 %) · 8 columnas', 'Muestras: Desarrollo 3.961 (23,33 %) · Holdout 1.031 (23,67 %) · Fuera de tiempo (OOT) 1.008 (23,71 %) — cohortes fuera de tiempo: 2024Q2 (columna «cohorte»); holdout 20 % del resto', 'Se infirió: esquema de 8 columnas (6 numéricas o de fecha, 2 de texto); 6 predictoras (1 categórica); fuera: cohorte (cohorte de la partición), bad_flag (define el incumplimiento, sería una fuga de información)', 'Identificador: loan_id (índice del archivo)', 'Evidencia de la corrida: bayesrisk-runs\\\\consumo_v01\\\\run'), alerts=(), table=                 Muestra  Filas  Malos  Tasa de malos\n",
       "0             Desarrollo   3961    924       0.233274\n",
       "1                Holdout   1031    244       0.236663\n",
       "2  Fuera de tiempo (OOT)   1008    239       0.237103, formats={'Filas': 'int', 'Malos': 'int', 'Tasa de malos': 'pct'}), StageSummary(stage='eda', label='Análisis exploratorio', lines=('Tasa de malos por cohorte: 5 períodos, media 23,33 %', 'Deterioro de la tasa en el tiempo: no evaluable (eje de cohorte, sin orden cronológico)', '6 columnas descritas frente al incumplimiento', 'Marcas de calidad del archivo: casi única: ingreso_mensual'), alerts=(), table=  Por cohorte  Filas  Malos  Tasa de malos  Poca confianza\n",
       "0      2023Q1    785    201       0.256051           False\n",
       "1      2023Q2    789    170       0.215463           False\n",
       "2      2023Q3    838    188       0.224344           False\n",
       "3      2023Q4    777    174       0.223938           False\n",
       "4      2024Q1    772    191       0.247409           False, formats={'Filas': 'int', 'Malos': 'int', 'Tasa de malos': 'pct'}), StageSummary(stage='binning', label='Tramos y WoE', lines=('5 de 5 variables tramificadas', 'Poder predictivo (IV): fuerte: ingreso_mensual · medio: deuda_ingreso · débil: utilizacion_linea, antiguedad_meses · sin poder: segmento'), alerts=('antiguedad_meses: la tasa de malos invierte la tendencia en Holdout', 'deuda_ingreso: la tasa de malos invierte la tendencia en Fuera de tiempo (OOT)', 'ingreso_mensual: la tasa de malos invierte la tendencia en Fuera de tiempo (OOT)'), table=            Variable        Tipo  Tramos        IV Banda de IV    Tendencia\n",
       "0    ingreso_mensual    numérica       6  0.304750      fuerte  descendente\n",
       "1      deuda_ingreso    numérica       6  0.163519       medio   ascendente\n",
       "2  utilizacion_linea    numérica       5  0.061031       débil   ascendente\n",
       "3   antiguedad_meses    numérica       6  0.041379       débil  descendente\n",
       "4           segmento  categórica       3  0.002922   sin poder            —, formats={'Tramos': 'int', 'IV': 'num3'}), StageSummary(stage='selection', label='Selección de variables', lines=('Entran 4 de 5 variables candidatas', 'Salen: segmento (IV insuficiente)', 'Correlación máxima entre las finales 0,014 y VIF máximo 1,00'), alerts=(), table=            Variable Entra  ... IV Holdout  IV Fuera de tiempo (OOT)\n",
       "0   antiguedad_meses    sí  ...   0.108644                  0.100682\n",
       "1      deuda_ingreso    sí  ...   0.106755                  0.169509\n",
       "2    ingreso_mensual    sí  ...   0.251714                  0.139994\n",
       "3           segmento    no  ...   0.008846                  0.006314\n",
       "4  utilizacion_linea    sí  ...   0.218567                  0.084846\n",
       "\n",
       "[5 rows x 11 columns], formats={'IV': 'num3', 'AUC': 'num3', 'KS': 'num3', 'Correlación máxima': 'num3', 'VIF': 'num2', 'IV Desarrollo': 'num3', 'IV Holdout': 'num3', 'IV Fuera de tiempo (OOT)': 'num3'}), StageSummary(stage='model', label='Modelo', lines=('Variables finales (4): antiguedad_meses, deuda_ingreso, ingreso_mensual, utilizacion_linea', 'Stepwise bidireccional: 4 iteraciones, 4 entradas y 0 salidas', 'Ajuste en Desarrollo: pseudo-R² de McFadden 0,094 · AIC 3909,7 · p-valor del test de razón de verosimilitud < 0,001 · convergió'), alerts=('Concentra más del 90 % del IV del modelo: ingreso_mensual',), table=            Variable  Coeficiente  ...        IV  Contribución al IV\n",
       "0         intercepto    -1.191417  ...       NaN                 NaN\n",
       "1   antiguedad_meses    -1.090203  ...  0.041379            0.072509\n",
       "2      deuda_ingreso    -1.074346  ...  0.163519            0.286533\n",
       "3    ingreso_mensual    -1.053858  ...  0.304750            0.534013\n",
       "4  utilizacion_linea    -1.116579  ...  0.061031            0.106945\n",
       "\n",
       "[5 rows x 7 columns], formats={'Coeficiente': 'num', 'Error estándar': 'num', 'p-valor': 'pvalor', 'IV': 'num3', 'Contribución al IV': 'pct'}), StageSummary(stage='scorecard', label='Tarjeta de puntuación', lines=('Escala: 20 puntos por duplicar las odds, 600 puntos a odds 50:1 (factor 28,85, desplazamiento 487,12)', 'Puntajes observados: de 441 a 624 (media 526,0)', '4 variables con puntos; un puntaje más alto indica menor riesgo'), alerts=(), table=             Variable  ... Puntos\n",
       "0    antiguedad_meses  ...    120\n",
       "1    antiguedad_meses  ...    126\n",
       "2    antiguedad_meses  ...    130\n",
       "3    antiguedad_meses  ...    131\n",
       "4    antiguedad_meses  ...    135\n",
       "5    antiguedad_meses  ...    154\n",
       "6    antiguedad_meses  ...    130\n",
       "7    antiguedad_meses  ...    130\n",
       "8       deuda_ingreso  ...    153\n",
       "9       deuda_ingreso  ...    139\n",
       "10      deuda_ingreso  ...    137\n",
       "11      deuda_ingreso  ...    127\n",
       "12      deuda_ingreso  ...    118\n",
       "13      deuda_ingreso  ...     97\n",
       "14      deuda_ingreso  ...    130\n",
       "15      deuda_ingreso  ...    130\n",
       "16    ingreso_mensual  ...    103\n",
       "17    ingreso_mensual  ...    113\n",
       "18    ingreso_mensual  ...    123\n",
       "19    ingreso_mensual  ...    131\n",
       "20    ingreso_mensual  ...    143\n",
       "21    ingreso_mensual  ...    167\n",
       "22    ingreso_mensual  ...    130\n",
       "23    ingreso_mensual  ...    130\n",
       "24  utilizacion_linea  ...    150\n",
       "25  utilizacion_linea  ...    138\n",
       "26  utilizacion_linea  ...    132\n",
       "27  utilizacion_linea  ...    125\n",
       "28  utilizacion_linea  ...    115\n",
       "29  utilizacion_linea  ...    130\n",
       "30  utilizacion_linea  ...    130\n",
       "\n",
       "[31 rows x 4 columns], formats={'WoE': 'num3', 'Puntos': 'int'}), StageSummary(stage='calibration', label='Calibración', lines=('Método: desplazamiento del intercepto (intercept offset); ancla a través del ciclo (TTC): la tasa de incumplimiento observada en Desarrollo = 23,33 %', 'PD media en Desarrollo: cruda 23,33 % → calibrada 23,33 % (desplazamiento del intercepto 0,0000)', 'Orden de riesgo preservado'), alerts=(), table=                 Muestra  Filas  ...  PD media calibrada  Tasa de malos observada\n",
       "0             Desarrollo   3961  ...            0.233274                 0.233274\n",
       "1                Holdout   1031  ...            0.236425                 0.236663\n",
       "2  Fuera de tiempo (OOT)   1008  ...            0.233094                 0.237103\n",
       "\n",
       "[3 rows x 5 columns], formats={'Filas': 'int', 'PD media cruda': 'pct', 'PD media calibrada': 'pct', 'Tasa de malos observada': 'pct'}), StageSummary(stage='performance', label='Desempeño', lines=('Desarrollo: AUC 0,709 · Gini 0,418 · KS 0,309', 'Holdout: AUC 0,696 · Gini 0,392 · KS 0,298', 'Fuera de tiempo (OOT): AUC 0,648 · Gini 0,295 · KS 0,232', 'Caída Desarrollo → Fuera de tiempo (OOT): AUC -0,062 (-8,7 %) · KS -0,077 (-25,0 %)'), alerts=(), table=                  Muestra  Decil  ...  Captura acumulada de malos  KS en el decil\n",
       "0              Desarrollo      1  ...                    0.218615        0.154407\n",
       "1              Desarrollo      2  ...                    0.383117        0.238566\n",
       "2              Desarrollo      3  ...                    0.514069        0.278969\n",
       "3              Desarrollo      4  ...                    0.630952        0.301022\n",
       "4              Desarrollo      5  ...                    0.730519        0.300490\n",
       "5              Desarrollo      6  ...                    0.810606        0.274551\n",
       "6              Desarrollo      7  ...                    0.873377        0.226027\n",
       "7              Desarrollo      8  ...                    0.932900        0.173269\n",
       "8              Desarrollo      9  ...                    0.978355        0.102161\n",
       "9              Desarrollo     10  ...                    1.000000        0.000000\n",
       "10                Holdout      1  ...                    0.225410        0.163148\n",
       "11                Holdout      2  ...                    0.389344        0.247032\n",
       "12                Holdout      3  ...                    0.516393        0.282594\n",
       "13                Holdout      4  ...                    0.610656        0.275205\n",
       "14                Holdout      5  ...                    0.713115        0.278553\n",
       "15                Holdout      6  ...                    0.782787        0.238950\n",
       "16                Holdout      7  ...                    0.856557        0.204715\n",
       "17                Holdout      8  ...                    0.918033        0.154373\n",
       "18                Holdout      9  ...                    0.967213        0.087925\n",
       "19                Holdout     10  ...                    1.000000        0.000000\n",
       "20  Fuera de tiempo (OOT)      1  ...                    0.192469        0.120947\n",
       "21  Fuera de tiempo (OOT)      2  ...                    0.334728        0.176080\n",
       "22  Fuera de tiempo (OOT)      3  ...                    0.468619        0.220245\n",
       "23  Fuera de tiempo (OOT)      4  ...                    0.564854        0.215049\n",
       "24  Fuera de tiempo (OOT)      5  ...                    0.652720        0.198884\n",
       "25  Fuera de tiempo (OOT)      6  ...                    0.744770        0.188203\n",
       "26  Fuera de tiempo (OOT)      7  ...                    0.820084        0.155584\n",
       "27  Fuera de tiempo (OOT)      8  ...                    0.903766        0.133935\n",
       "28  Fuera de tiempo (OOT)      9  ...                    0.945607        0.058741\n",
       "29  Fuera de tiempo (OOT)     10  ...                    1.000000        0.000000\n",
       "\n",
       "[30 rows x 9 columns], formats={'Decil': 'int', 'Filas': 'int', 'Malos': 'int', 'Tasa de malos': 'pct', 'PD media': 'pct', 'Puntaje medio': 'num2', 'Captura acumulada de malos': 'pct', 'KS en el decil': 'num3'}), StageSummary(stage='stability', label='Estabilidad', lines=('Desarrollo vs. Holdout: peor PSI 0,0057 (PD calibrada) → Estable', 'Desarrollo vs. OOT: peor PSI 0,0172 (score) → Estable', 'CSI más alto: ingreso_mensual (0,0098)', 'Estabilidad temporal del score por cohorte: 6 períodos'), alerts=(), table=          Métrica             Comparación  ...     Valor    Banda\n",
       "0   PSI del score  Desarrollo vs. Holdout  ...  0.002897  Estable\n",
       "1   PSI del score      Desarrollo vs. OOT  ...  0.017171  Estable\n",
       "2    PSI de la PD  Desarrollo vs. Holdout  ...  0.005718  Estable\n",
       "3    PSI de la PD      Desarrollo vs. OOT  ...  0.012653  Estable\n",
       "4             CSI  Desarrollo vs. Holdout  ...  0.003183  Estable\n",
       "5             CSI      Desarrollo vs. OOT  ...  0.001658  Estable\n",
       "6             CSI  Desarrollo vs. Holdout  ...  0.003322  Estable\n",
       "7             CSI      Desarrollo vs. OOT  ...  0.008178  Estable\n",
       "8             CSI  Desarrollo vs. Holdout  ...  0.002994  Estable\n",
       "9             CSI      Desarrollo vs. OOT  ...  0.009808  Estable\n",
       "10            CSI  Desarrollo vs. Holdout  ...  0.007215  Estable\n",
       "11            CSI      Desarrollo vs. OOT  ...  0.003973  Estable\n",
       "12   PSI temporal                 Cohorte  ...  0.017171  Estable\n",
       "\n",
       "[13 rows x 5 columns], formats={'Valor': 'num'}), StageSummary(stage='validation', label='Validación formal', lines=('Estado técnico: Falla — lo decide Hosmer-Lemeshow en Fuera de tiempo (OOT) (p-valor 0,026; PD media agregada 23,31 % frente a 23,71 % observada)', '3 pruebas con veredicto, 1 fallida; familias: discriminación, calibración y estabilidad', 'El estado técnico es una síntesis del motor; el veredicto lo firma un validador'), alerts=('Estado técnico «Falla»: revisar Hosmer-Lemeshow en Fuera de tiempo (OOT) (p-valor 0,026; PD media agregada 23,31 % frente a 23,71 % observada)',), table=           Familia                        Prueba  ...   p-valor       Veredicto\n",
       "0   Discriminación                           AUC  ...       NaN        Evaluada\n",
       "1   Discriminación                           AUC  ...       NaN        Evaluada\n",
       "2   Discriminación                           AUC  ...       NaN        Evaluada\n",
       "3      Calibración               Hosmer-Lemeshow  ...  0.900823            Pasa\n",
       "4      Calibración              Puntaje de Brier  ...       NaN   Sin veredicto\n",
       "5      Calibración               Hosmer-Lemeshow  ...  0.026157           Falla\n",
       "6      Calibración              Puntaje de Brier  ...       NaN   Sin veredicto\n",
       "7      Calibración               Hosmer-Lemeshow  ...  0.898605            Pasa\n",
       "8      Calibración              Puntaje de Brier  ...       NaN   Sin veredicto\n",
       "9      Estabilidad         PSI del score · score  ...       NaN  Pasa (Estable)\n",
       "10     Estabilidad         PSI del score · score  ...       NaN  Pasa (Estable)\n",
       "11     Estabilidad  PSI de la PD · pd_calibrated  ...       NaN  Pasa (Estable)\n",
       "12     Estabilidad  PSI de la PD · pd_calibrated  ...       NaN  Pasa (Estable)\n",
       "13     Estabilidad        CSI · antiguedad_meses  ...       NaN  Pasa (Estable)\n",
       "14     Estabilidad        CSI · antiguedad_meses  ...       NaN  Pasa (Estable)\n",
       "15     Estabilidad           CSI · deuda_ingreso  ...       NaN  Pasa (Estable)\n",
       "16     Estabilidad           CSI · deuda_ingreso  ...       NaN  Pasa (Estable)\n",
       "17     Estabilidad         CSI · ingreso_mensual  ...       NaN  Pasa (Estable)\n",
       "18     Estabilidad         CSI · ingreso_mensual  ...       NaN  Pasa (Estable)\n",
       "19     Estabilidad       CSI · utilizacion_linea  ...       NaN  Pasa (Estable)\n",
       "20     Estabilidad       CSI · utilizacion_linea  ...       NaN  Pasa (Estable)\n",
       "21     Estabilidad          PSI temporal · score  ...       NaN  Pasa (Estable)\n",
       "\n",
       "[22 rows x 6 columns], formats={'Valor': 'num', 'p-valor': 'pvalor'}), StageSummary(stage='report', label='Informe y ficha', lines=('Informe HTML: bayesrisk-runs\\\\consumo_v01\\\\reports\\\\scorecard_report.html', 'Informe Word: bayesrisk-runs\\\\consumo_v01\\\\reports\\\\scorecard_report.docx', 'Informe PDF: no se generó (falta el extra de PDF o su motor nativo)', 'Fuente editable (Quarto): bayesrisk-runs\\\\consumo_v01\\\\reports\\\\scorecard_report.qmd', 'Registro de auditoría: bayesrisk-runs\\\\consumo_v01\\\\run\\\\audit_trail.jsonl'), alerts=(), table=None, formats={})))"
      ],
      "text/html": [
       "<div class=\"bayesrisk-summary\"><h2>Resumen del scorecard</h2><p><b>Ejecución:</b> completada</p><p><b>Validación técnica:</b> Falla — lo decide Hosmer-Lemeshow en Fuera de tiempo (OOT) (p-valor 0,026; PD media agregada 23,31 % frente a 23,71 % observada)</p><table><tbody><tr><th>AUC en Fuera de tiempo (OOT)</th><td>0,648</td></tr><tr><th>Gini en Fuera de tiempo (OOT)</th><td>0,295</td></tr><tr><th>KS en Fuera de tiempo (OOT)</th><td>0,232</td></tr><tr><th>Caída del AUC Desarrollo → Fuera de tiempo (OOT)</th><td>-0,062 (-8,7 %)</td></tr><tr><th>Peor PSI entre score y PD</th><td>0,0172 (Desarrollo vs. OOT) → Estable</td></tr></tbody></table><h4>Qué revisar</h4><ul><li>⚠ Tramos y WoE: antiguedad_meses: la tasa de malos invierte la tendencia en Holdout</li><li>⚠ Tramos y WoE: deuda_ingreso: la tasa de malos invierte la tendencia en Fuera de tiempo (OOT)</li><li>⚠ Tramos y WoE: ingreso_mensual: la tasa de malos invierte la tendencia en Fuera de tiempo (OOT)</li><li>⚠ Modelo: Concentra más del 90 % del IV del modelo: ingreso_mensual</li><li>⚠ Validación formal: Estado técnico «Falla»: revisar Hosmer-Lemeshow en Fuera de tiempo (OOT) (p-valor 0,026; PD media agregada 23,31 % frente a 23,71 % observada)</li></ul><h4>Decisiones humanas registradas</h4><ul><li>exclude mora_max_12m — «no estará disponible al originar»</li></ul><h4>Dónde quedó cada archivo</h4><ul><li>Carpeta del proyecto: <code>bayesrisk-runs\\consumo_v01</code></li><li>Config vigente: <code>bayesrisk-runs\\consumo_v01\\config.yaml</code></li><li>Evidencia de la corrida: <code>bayesrisk-runs\\consumo_v01\\run</code></li><li>Registro de auditoría: <code>bayesrisk-runs\\consumo_v01\\run\\audit_trail.jsonl</code></li><li>Informe HTML: <code>bayesrisk-runs\\consumo_v01\\reports\\scorecard_report.html</code></li><li>Informe Word: <code>bayesrisk-runs\\consumo_v01\\reports\\scorecard_report.docx</code></li><li>Fuente editable (Quarto): <code>bayesrisk-runs\\consumo_v01\\reports\\scorecard_report.qmd</code></li></ul></div>"
      ]
     },
     "metadata": {}
    }
   ],
   "source": [
    "sc.summary()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 6. Los entregables\n",
    "\n",
    "La carpeta del proyecto queda con todo: el config completo que reproduce la corrida sin\n",
    "este cuaderno, la copia de los datos que se leyeron, el registro de auditoría, el estudio\n",
    "y el informe en HTML, Word y fuente editable.\n",
    "\n",
    "`export_excel()` añade, si lo quieres, un libro por etapa con las mismas tablas del\n",
    "informe."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "bayesrisk-runs\\consumo_v01\n",
      "Excel por etapa: 11 libros en bayesrisk-runs\\consumo_v01\\excel\n",
      "01 Datos y muestras.xlsx\n",
      "02 Análisis exploratorio.xlsx\n",
      "03 Tramos y WoE.xlsx\n",
      "04 Selección de variables.xlsx\n",
      "05 Modelo.xlsx\n",
      "06 Tarjeta de puntuación.xlsx\n",
      "07 Calibración.xlsx\n",
      "08 Desempeño.xlsx\n",
      "09 Estabilidad.xlsx\n",
      "10 Validación formal.xlsx\n",
      "11 Decisiones.xlsx\n"
     ]
    }
   ],
   "source": [
    "print(sc.project_dir)\n",
    "for libro in sc.export_excel():\n",
    "    print(libro.name)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python",
   "version": "3.12.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
