Hiperparámetros de XGBoost
--------------------------

XGBoost construye un ensemble de árboles de decisión de forma
secuencial: cada nuevo árbol corrige los errores residuales de los
anteriores. Los hiperparámetros controlan qué tan agresivamente aprende
el modelo (**ajuste**) y qué tan fuertemente lo restringimos para que
generalice (**regularización**). Encontrar el balance entre ambos es la
clave del tuning.

1. Estructura del Árbol
~~~~~~~~~~~~~~~~~~~~~~~

Estos hiperparámetros definen la forma y complejidad de cada árbol
individual. Son los controles más directos sobre la capacidad del
modelo.

``max_depth``

Profundidad máxima permitida para cada árbol. Un árbol más profundo
puede capturar interacciones más complejas entre features, pero también
es más propenso a memorizar el ruido de los datos de entrenamiento.

============ ==========
Propiedad    Valor
============ ==========
Default      ``6``
Rango típico ``3 – 10``
============ ==========

**Cómo funciona:** un árbol de profundidad 6 puede crear hasta
``2⁶ = 64`` hojas, lo que significa hasta 64 regiones de decisión
distintas. Cada nivel adicional duplica esa capacidad.

-  **→ Más ajuste:** aumentar ``max_depth`` (por ejemplo, de ``6`` a
   ``8`` o ``10``). El modelo tendrá más capacidad para capturar
   relaciones no lineales y combinaciones complejas de features.

-  **→ Más regularización:** reducir ``max_depth`` (por ejemplo, de
   ``6`` a ``3`` o ``4``). Árboles más cortos generan decisiones más
   simples y generalizables. Este suele ser el **primer hiperparámetro**
   que se reduce cuando hay overfitting.

``min_child_weight``

Suma mínima de pesos (en problemas estándar, equivale al número mínimo
de muestras) que debe tener un nodo hijo para que se permita una nueva
partición. Controla cuánta evidencia necesita el modelo antes de crear
una rama.

``min_child_weight`` es la suma mínima de la segunda derivada de la
función de pérdida (el hessiano) que debe acumularse en un nodo hijo
para que XGBoost permita hacer ese split. Si alguno de los dos hijos
resultantes no alcanza ese umbral, la partición se rechaza y el nodo
queda como hoja.

+--------------+------------------------------------------------------+
| Propiedad    | Valor                                                |
+==============+======================================================+
| Default      | ``1``                                                |
+--------------+------------------------------------------------------+
| Rango típico | ``1 – 10`` (datasets pequeños), ``1 – 100+``         |
|              | (datasets grandes)                                   |
+--------------+------------------------------------------------------+

**Cómo funciona:** antes de hacer un split, XGBoost verifica que ambos
nodos hijos resultantes tengan al menos ``min_child_weight`` de peso
acumulado. Si no se cumple, la partición no se realiza. Con el valor
default de ``1``, basta con que una sola muestra caiga en un nodo para
que sea válido.

-  **→ Más ajuste:** reducir ``min_child_weight`` (hacia ``1``). El
   modelo puede crear nodos con muy pocas muestras, capturando patrones
   más finos.

-  **→ Más regularización:** aumentar ``min_child_weight`` (por ejemplo,
   ``5``, ``10``, ``20``). Obliga a que cada hoja represente un grupo
   más grande de muestras, lo que suaviza las predicciones y previene
   que el modelo reaccione a observaciones aisladas.

``gamma`` (γ) — ``min_split_loss``

Reducción mínima de la función de pérdida que debe lograr una partición
para ser aceptada. Es un umbral de “rentabilidad” para cada split.

============ ==============================================
Propiedad    Valor
============ ==============================================
Default      ``0``
Rango típico ``0 – 5`` (depende de la escala de la pérdida)
============ ==============================================

**Cómo funciona:** al evaluar un split candidato, XGBoost calcula la
ganancia (reducción de la pérdida). Si esa ganancia es menor que ``γ``,
el split no se realiza y el nodo queda como hoja. Es un mecanismo de
**poda durante la construcción** del árbol, no después.

-  **→ Más ajuste:** reducir ``γ`` hacia ``0`` o dejarlo en ``0``.
   Cualquier split que mejore mínimamente la pérdida será aceptado,
   permitiendo árboles más detallados.

-  **→ Más regularización:** aumentar ``γ`` (por ejemplo, ``0.1``,
   ``0.5``, ``1`` o más). Solo se aceptarán splits que produzcan mejoras
   sustanciales, lo que genera árboles más conservadores con menos
   ramas.

2. Regularización Directa
~~~~~~~~~~~~~~~~~~~~~~~~~

Estos parámetros penalizan directamente la complejidad del modelo en la
función objetivo, de forma análoga a la regularización L1 y L2 en
regresión lineal.

``lambda`` (λ) — ``reg_lambda``

Término de regularización **L2** aplicado sobre los pesos (scores) de
las hojas. Penaliza hojas con valores de predicción grandes.

============ ==========
Propiedad    Valor
============ ==========
Default      ``1``
Rango típico ``0 – 10``
============ ==========

**Cómo funciona:** la función objetivo de XGBoost incluye un término
``λ · Σ(w²)``, donde ``w`` son los pesos de las hojas. Valores altos de
``λ`` “comprimen” los pesos hacia cero, haciendo que cada árbol
contribuya de forma más conservadora.

-  **→ Más ajuste:** reducir ``λ`` hacia ``0``. Las hojas pueden tomar
   valores de predicción más extremos, dándole al modelo más libertad
   para ajustarse a los datos.

-  **→ Más regularización:** aumentar ``λ`` (por ejemplo, ``3``, ``5``,
   ``10``). Suaviza los pesos de las hojas, reduciendo la influencia de
   cualquier árbol individual. Es especialmente útil cuando se observan
   predicciones inestables o muy dispersas.

``alpha`` (α) — ``reg_alpha``

Término de regularización **L1** aplicado sobre los pesos de las hojas.
A diferencia de L2, la penalización L1 puede llevar algunos pesos
exactamente a cero.

============ ==========
Propiedad    Valor
============ ==========
Default      ``0``
Rango típico ``0 – 10``
============ ==========

**Cómo funciona:** la función objetivo incluye un término ``α · Σ|w|``.
La regularización L1 produce *sparsity*: en datasets con muchas features
irrelevantes, ``α`` alto puede efectivamente “apagar” hojas que dependen
de features ruidosas.

-  **→ Más ajuste:** reducir ``α`` hacia ``0`` (el default). Sin
   penalización L1, todas las hojas pueden contribuir libremente.

-  **→ Más regularización:** aumentar ``α`` (por ejemplo, ``0.1``,
   ``1``, ``5``). Útil cuando tienes muchas features y sospechas que
   varias son irrelevantes. Combina bien con ``λ``: usarlos juntos
   (elastic net implícito) suele ser más efectivo que uno solo.

3. Tasa de Aprendizaje y Número de Iteraciones
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Estos dos parámetros trabajan en conjunto y controlan el proceso de
boosting: cuántos árboles se construyen y cuánto pesa cada uno.

``learning_rate`` (η) — ``eta``

Factor de contracción (*shrinkage*) aplicado a la contribución de cada
árbol nuevo. Después de construir un árbol, su predicción se multiplica
por ``η`` antes de sumarse al ensemble.

============ ==============
Propiedad    Valor
============ ==============
Default      ``0.3``
Rango típico ``0.01 – 0.3``
============ ==============

**Cómo funciona:** si ``η = 0.1``, cada árbol solo contribuye el 10% de
su predicción completa. Esto obliga al modelo a necesitar más árboles
para alcanzar la misma capacidad, pero el camino es más suave y
generaliza mejor. La relación con ``n_estimators`` es **inversa**: al
reducir ``η``, necesitas aumentar ``n_estimators`` proporcionalmente.

-  **→ Más ajuste:** aumentar ``η`` (por ejemplo, ``0.3``). Cada árbol
   tiene más impacto, el modelo converge rápido y se necesitan menos
   árboles. Riesgo: *overshoot* en el ajuste.

-  **→ Más regularización:** reducir ``η`` (por ejemplo,
   ``0.01 – 0.05``). El modelo aprende de forma más gradual y estable.
   Es la estrategia más consistente para mejorar generalización, siempre
   que se compense con suficientes árboles y se use ``early_stopping``.

``n_estimators``

Número máximo de árboles (rondas de boosting) que se construyen. Es la
“duración” del entrenamiento.

============ ==================================
Propiedad    Valor
============ ==================================
Default      ``100``
Rango típico ``100 – 10000`` (depende de ``η``)
============ ==================================

**Cómo funciona:** cada iteración añade un árbol que intenta corregir
los errores residuales del ensemble actual. Con demasiados árboles (y
sin early stopping), el modelo eventualmente empieza a ajustarse al
ruido.

-  **→ Más ajuste:** aumentar ``n_estimators``. Más árboles permiten al
   modelo refinar su predicción progresivamente. Sin embargo, pasado
   cierto punto, las mejoras son marginales o contraproducentes.

-  **→ Más regularización:** reducir ``n_estimators`` o, mucho mejor,
   usar ``early_stopping`` para que se detenga automáticamente.

``early_stopping_rounds``

No es un hiperparámetro del modelo en sí, sino del proceso de
entrenamiento. Detiene el entrenamiento si la métrica de validación no
mejora durante N rondas consecutivas.

============ ===========
Propiedad    Valor
============ ===========
Default      No activo
Rango típico ``10 – 50``
============ ===========

**Cómo funciona:** necesitas un conjunto de validación separado. En cada
ronda, XGBoost evalúa la métrica en validación. Si tras
``early_stopping_rounds`` iteraciones no hay mejora, se detiene y usa el
modelo de la mejor ronda. Esto convierte a ``n_estimators`` en un
**techo máximo** y elimina la necesidad de adivinarlo.

4. Muestreo (Stochastic Boosting)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Estos parámetros introducen aleatoriedad en el entrenamiento al usar
solo una fracción de los datos o features en cada árbol. Es el mismo
principio que hace funcionar a Random Forest, adaptado al boosting.

``subsample``

Fracción de muestras (filas) usadas para entrenar cada árbol individual.
El muestreo se hace sin reemplazo.

============ ============================
Propiedad    Valor
============ ============================
Default      ``1.0`` (todas las muestras)
Rango típico ``0.5 – 1.0``
============ ============================

**Cómo funciona:** con ``subsample=0.8``, cada árbol se entrena con el
80% de las filas, seleccionadas al azar. Las filas excluidas actúan como
una mini-validación implícita. Esto reduce la correlación entre árboles
y la varianza del ensemble.

-  **→ Más ajuste:** aumentar hacia ``1.0``. Cada árbol ve todos los
   datos y puede extraer la máxima información.

-  **→ Más regularización:** reducir a ``0.6 – 0.8``. Introduce
   diversidad entre árboles y previene que todos memoricen los mismos
   patrones ruidosos. No se recomienda bajar de ``0.5`` porque los
   árboles tendrían muy poca información.

``colsample_bytree``

Fracción de features (columnas) seleccionadas al azar para cada árbol.
Cada árbol nuevo recibe un subconjunto diferente de features.

============ ============================
Propiedad    Valor
============ ============================
Default      ``1.0`` (todas las features)
Rango típico ``0.3 – 1.0``
============ ============================

**Cómo funciona:** con ``colsample_bytree=0.7``, cada árbol solo puede
usar el 70% de las features disponibles. Esto fuerza al modelo a no
depender excesivamente de unas pocas features dominantes y explorar
combinaciones alternativas.

-  **→ Más ajuste:** aumentar hacia ``1.0``. Todos los árboles ven todas
   las features y pueden encontrar los splits óptimos.

-  **→ Más regularización:** reducir a ``0.5 – 0.8``. Especialmente
   efectivo cuando tienes muchas features y sospechas que algunas son
   ruidosas o redundantes. Es el equivalente al ``max_features`` de
   Random Forest.

Resumen
~~~~~~~

+------------------+---------+-----------------+------------------+
| Hiperparámetro   | Default | Para más ajuste | Para regularizar |
+==================+=========+=================+==================+
| ``max_depth``    | ``6``   | ↑ Aumentar      | ↓ Reducir        |
+------------------+---------+-----------------+------------------+
| ``mi             | ``1``   | ↓ Reducir       | ↑ Aumentar       |
| n_child_weight`` |         |                 |                  |
+------------------+---------+-----------------+------------------+
| ``gamma`` (γ)    | ``0``   | ↓ Reducir a 0   | ↑ Aumentar       |
+------------------+---------+-----------------+------------------+
| ``lambda`` (λ)   | ``1``   | ↓ Reducir       | ↑ Aumentar       |
+------------------+---------+-----------------+------------------+
| ``alpha`` (α)    | ``0``   | Dejar en 0      | ↑ Aumentar       |
+------------------+---------+-----------------+------------------+
| `                | ``0.3`` | ↑ Aumentar      | ↓ Reducir        |
| `learning_rate`` |         |                 |                  |
| (η)              |         |                 |                  |
+------------------+---------+-----------------+------------------+
| ``n_estimators`` | ``100`` | ↑ Aumentar      | ↓ Reducir /      |
|                  |         |                 | early stopping   |
+------------------+---------+-----------------+------------------+
| ``early_s        | —       | ↑ Más paciencia | ↓ Menos          |
| topping_rounds`` |         |                 | paciencia        |
+------------------+---------+-----------------+------------------+
| ``subsample``    | ``1.0`` | ↑ Hacia 1.0     | ↓ Hacia 0.6 –    |
|                  |         |                 | 0.8              |
+------------------+---------+-----------------+------------------+
| ``co             | ``1.0`` | ↑ Hacia 1.0     | ↓ Hacia 0.5 –    |
| lsample_bytree`` |         |                 | 0.8              |
+------------------+---------+-----------------+------------------+
