Abrís un notebook, entrenás un RandomForestClassifier de scikit-learn sobre un dataset tabular chico, y el resultado es razonable. Alguien en el equipo te dice "probá con XGBoost, te va a andar mejor". Cambiás dos líneas, corrés de nuevo, y el número mejora un poco. La pregunta que casi nadie se hace en ese momento es por qué mejoró — y si esa mejora justifica el costo de tener seis hiperparámetros nuevos que tunear en lugar de dos.
Mi tesis es esta: XGBoost no es "mejor" que scikit-learn en general. Es la herramienta correcta cuando necesitás exprimir performance en datos tabulares con boosting, al costo de más superficie de configuración. Si no estás en ese escenario específico, estás pagando complejidad por nada.
Qué es XGBoost (y qué no es)
XGBoost significa Extreme Gradient Boosting. Es una implementación de gradient boosting sobre árboles de decisión, optimizada para velocidad y para exprimir cada punto de señal que el dataset tiene para dar. La documentación oficial lo describe como una librería de boosting de gradiente optimizada para ser "eficiente, flexible y portable" — no como un algoritmo nuevo, sino como una implementación particular de una idea que ya existía.
La idea de fondo, gradient boosting, es simple de explicar aunque no sea simple de implementar bien:
- Entrenás un modelo débil (típicamente un árbol chico).
- Medís el error que ese modelo comete.
- Entrenás un segundo modelo que se enfoca en corregir ese error.
- Repetís, sumando modelos, cada uno corrigiendo lo que el anterior se equivocó.
Un RandomForestClassifier de scikit-learn hace algo distinto: entrena muchos árboles en paralelo, cada uno sobre una muestra distinta de los datos, y promedia sus votos. No hay corrección secuencial de errores — hay votación. Esa diferencia de diseño es la que explica por qué, en ciertos datasets tabulares, boosting saca ventaja: cada árbol nuevo está literalmente entrenado para tapar el agujero que dejó el anterior, en lugar de simplemente aportar otro punto de vista independiente.
Lo que la documentación de XGBoost no dice es que esto vaya a pasar siempre. Documenta el algoritmo, los parámetros y la API. No documenta "en qué porcentaje de datasets gana" — eso depende del dataset, y cualquier cifra genérica que circule sobre eso no tiene fuente citable.
El ejemplo reproducible: mismo dataset, dos librerías
Para ver la diferencia sin inventar un caso de uso, usá el dataset de juguete load_breast_cancer que trae scikit-learn — 569 filas, 30 features numéricas, clasificación binaria. Es chico a propósito: no busca demostrar quién "gana", busca mostrar el flujo de trabajo y dónde aparecen los hiperparámetros nuevos.
# comparacion_basica.py
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from xgboost import XGBClassifier
X, y = load_breast_cancer(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
rf = RandomForestClassifier(random_state=42)
rf.fit(X_train, y_train)
xgb = XGBClassifier(eval_metric="logloss", random_state=42)
xgb.fit(X_train, y_train)
print("RandomForest score:", rf.score(X_test, y_test))
print("XGBoost score:", xgb.score(X_test, y_test))
Corré esto en un notebook de Jupyter y vas a tener dos números de accuracy sobre el mismo split. No voy a inventar acá qué número te va a salir a vos — depende de la versión de las librerías, del seed, del hardware. Lo que sí podés afirmar con este experimento es algo distinto: ambos modelos corrieron sobre el mismo dataset, con el mismo split, y uno de los dos tiene una API más chica para tunear. RandomForestClassifier tiene n_estimators, max_depth, min_samples_split como parámetros centrales. XGBClassifier suma learning_rate, subsample, colsample_bytree, gamma, reg_alpha, reg_lambda — y cada uno interactúa con los demás.
Eso es el costo real de XGBoost. No es que sea más lento entrenar (para datasets chicos, no lo vas a notar) ni que sea más difícil de instalar. Es que el espacio de hiperparámetros es más grande, y una búsqueda mal hecha en ese espacio te puede dar un resultado peor que el RandomForest con defaults.
flowchart LR
A[Dataset tabular] --> B{¿Necesito exprimir cada punto de performance?}
B -->|No, quiero un baseline rápido| C[RandomForest de scikit-learn]
B -->|Sí, y tengo tiempo para tunear| D[XGBoost]
D --> E{¿Tuneaste learning_rate, subsample, reg_lambda?}
E -->|No| F[Resultado probablemente peor que el baseline]
E -->|Sí, con validación cruzada| G[Resultado potencialmente mejor]
Dónde se equivoca la gente: la receta copiada sin criterio
La receta común que circula es: "usá XGBoost porque gana las competencias de Kaggle". Es cierto que XGBoost tuvo un rol protagónico en muchas competencias de datos tabulares — eso es historia documentada. El problema es el salto lógico siguiente: de ahí no se sigue que gane en tu dataset, con tus features, en tu volumen de filas.
El costo oculto de copiar esa receta sin pensarlo es doble:
-
Overfitting silencioso. XGBoost con muchos estimadores y sin regularización (
reg_alpha,reg_lambdaen cero) memoriza el dataset de entrenamiento más fácil que un RandomForest, porque cada árbol nuevo se ajusta específicamente al error residual — incluido el ruido. - Tiempo de tuneo que nadie presupuestó. Si vas a usar XGBoost en serio, necesitás una búsqueda de hiperparámetros (grid search, random search, o algo tipo Optuna) con validación cruzada. Eso es tiempo de cómputo y tiempo de persona que un RandomForest con defaults razonables no te pide.
El contraejemplo más simple: un dataset tabular con pocas filas (digamos, unos pocos cientos) y alta dimensionalidad de ruido. Ahí un RandomForest con su regularización implícita por bagging puede comportarse de forma más estable que un XGBoost mal tuneado, que va a aprender a explicar el ruido en lugar de la señal. No tengo un benchmark público para citar ese caso puntual — es un patrón de comportamiento esperado según cómo funciona cada algoritmo, no una medición que hice.
Matriz de decisión: cuándo mirar XGBoost primero
| Situación | Qué mirar primero | Por qué |
|---|---|---|
| Datos tabulares, necesitás un baseline rápido | scikit-learn (RandomForest o GradientBoosting) | Menos hiperparámetros, resultado razonable sin tuneo |
| Competencia o problema donde cada punto de performance cuenta | XGBoost, con presupuesto de tiempo para tunear | Ahí es donde el boosting secuencial rinde, si lo acompañás con validación cruzada |
| Dataset con muchas columnas categóricas sin encodear | Revisar soporte nativo de categóricas en la versión de XGBoost que uses | La documentación oficial detalla el soporte por versión — no asumas que "simplemente funciona" sin chequear |
| Poco tiempo de equipo para tuneo, plazo corto | scikit-learn primero | Un XGBoost mal tuneado puede rendir peor que un RandomForest con defaults |
| Necesitás explicar el modelo a alguien no técnico | Cualquiera de los dos, pero revisá herramientas de interpretabilidad (feature importance, SHAP) antes de elegir por performance sola | La interpretabilidad no depende de la librería, depende de qué instrumentés encima |
Esta tabla no es una conclusión cerrada sobre cuál algoritmo "gana". Es un punto de partida para decidir qué probar primero según la restricción real que tengas: tiempo, volumen de datos, necesidad de explicar el modelo.
Los límites de esto (y por qué no cierro con un número)
Ojo con la afirmación que casi escribí antes de sacarla: "XGBoost gana en la mayoría de los casos de datos tabulares". Esa frase no tiene una fuente citable que yo pueda poner acá, y es exactamente el tipo de claim sin evidencia que terminó bloqueado en un post anterior sobre scikit-learn. No la voy a repetir con otras palabras.
Lo que sí puedo decir con el nivel de certeza que la evidencia permite:
- La documentación oficial de XGBoost explica el algoritmo, los parámetros y el soporte de features. No documenta comparativas de performance contra scikit-learn en datasets generales — eso lo tenés que correr vos, con los datos.
- El experimento del snippet de arriba es reproducible: cualquiera que lo corra va a tener dos números comparables, pero esos números van a variar según versión de librería y seed. No es una medición fija que puedas citar como "XGBoost dio X% mejor".
- Sin un experimento de validación cruzada con búsqueda de hiperparámetros sobre el dataset específico que tengas, cualquier comparación de accuracy entre ambos modelos es anecdótica.
Si necesitás una decisión reproducible y medible, el próximo paso concreto es correr GridSearchCV o RandomizedSearchCV sobre ambos modelos, con el mismo esquema de validación cruzada, y comparar la distribución de scores — no un solo número de un solo split.
FAQ
¿XGBoost sirve para datos que no son tabulares, como imágenes o texto?
No es su fuerte. Para imágenes y texto, arquitecturas de redes neuronales (CNNs, transformers) suelen dominar el estado del arte. XGBoost brilla en datos estructurados en filas y columnas.
¿Necesito GPU para usar XGBoost?
No. XGBoost corre en CPU sin problema para datasets chicos y medianos. Tiene soporte de GPU para acelerar entrenamiento en datasets grandes, documentado en la página oficial, pero no es un requisito.
¿XGBoost y LightGBM son lo mismo?
Ambos implementan gradient boosting sobre árboles, pero con decisiones de diseño distintas (por ejemplo, cómo hacen el split de los árboles). Si estás evaluando cuál usar, valen los mismos criterios de esta matriz: depende del dataset y del tiempo que tengas para tunear cada uno.
¿Puedo usar XGBoost directamente con la API de scikit-learn?
Sí. XGBClassifier y XGBRegressor implementan la interfaz fit/predict de scikit-learn, así que se integran con Pipeline, GridSearchCV y el resto del ecosistema sin fricción.
¿Cuál es el hiperparámetro que más impacto tiene en XGBoost?
Según la documentación, learning_rate y n_estimators interactúan directamente: un learning_rate bajo necesita más estimadores para converger. max_depth controla cuánto puede memorizar cada árbol individual. No hay un único parámetro "mágico" — la interacción entre ellos es el punto.
¿XGBoost reemplaza la necesidad de feature engineering?
No. Sigue siendo un modelo sobre árboles: se beneficia de features bien construidas igual que scikit-learn. Ningún algoritmo de boosting resuelve un problema de datos mal preparados.
Postura final
Si estás arrancando un problema de clasificación o regresión tabular y no tenés evidencia de que necesitás exprimir cada punto de performance, arrancá con scikit-learn. Es menos superficie para romper, menos hiperparámetros para explicar en un code review, y un baseline confiable en minutos. Movete a XGBoost cuando tengas el tiempo de tuneo presupuestado y una razón concreta — una competencia, un requisito de producto que justifique el esfuerzo — no porque "es lo que usan los que ganan Kaggle".
La pregunta que te tenés que hacer antes de cambiar de librería no es "¿cuál es mejor?". Es "¿tengo el tiempo para tunear seis hiperparámetros en lugar de dos, y ese tiempo me lo van a pagar con la mejora que necesito?". Si la respuesta es no, quedate con el RandomForest y seguí iterando en otra parte del pipeline — probablemente en las features, no en el algoritmo.
Si esto te hizo pensar en cómo estructurás el resto del stack de datos, capaz te sirve repasar cómo Docker Compose maneja el healthcheck y el depends_on cuando el entrenamiento corre en un contenedor separado del servicio que sirve el modelo, o cómo sanitizar valores sensibles en Actuator si el pipeline de ML expone métricas por HTTP.
Fuente original:
- XGBoost Documentation — https://xgboost.readthedocs.io/en/stable/
Este artículo fue publicado originalmente en juanchi.dev
Top comments (0)