Quinto artículo de la parte técnica de la serie sobre retención. En el artículo sobre XGBoost introdujimos las primeras defensas contra el desbalance; aquí vamos al fondo del problema y al estado del arte de las técnicas para corregirlo. Seguimos con Ficticia Commerce.
Por qué el churn siempre está desbalanceado
Empecemos por lo evidente, que es justamente lo que hace al problema escurridizo: en cualquier negocio sano, la inmensa mayoría de los clientes no abandona en un periodo dado. Las tasas de churn típicas se mueven entre un puñado de puntos porcentuales y, en los casos más altos, en torno al 20 o 30 %. Eso significa que cuando entrenas un modelo, le estás mostrando muchísimos más ejemplos de clientes que se quedan que de clientes que se van. El desequilibrio no es una anomalía de tus datos: es la naturaleza misma del fenómeno.
El problema es que la mayoría de algoritmos de clasificación están diseñados para maximizar el número total de aciertos, y cuando una clase domina abrumadoramente, la forma más fácil de acertar mucho es ignorar a la minoría. El modelo descubre que prediciendo "se queda" para casi todo el mundo acierta la mayoría de las veces, y se acomoda en esa estrategia perezosa. Como vimos en el artículo sobre predicción de churn, ese es exactamente el modelo trivial que tiene un accuracy excelente y una utilidad nula: el desbalance es la fuerza que empuja a cualquier modelo hacia esa trampa si no lo corriges.
Analogía
Imagina entrenar a alguien para detectar billetes falsos mostrándole 980 billetes auténticos y solo 20 falsos. Aprenderá rápido que decir "auténtico" a todo le da un 98 % de acierto, y dejará de mirar los detalles que delatan a los falsos. No es que sea incapaz de distinguirlos: es que los datos le enseñaron que no merece la pena intentarlo. El desbalance le quita al modelo el incentivo de aprender lo único que de verdad importa.
Las dos defensas que ya conocemos, y por qué se quedan cortas
En artículos anteriores introdujimos dos mecanismos para contrarrestar el desbalance sin tocar los datos. El primero es el ajuste de pesos por clase: el class_weight="balanced" de Random Forest y el scale_pos_weight de XGBoost, que le indican al modelo que penalice más los errores sobre la clase minoritaria, obligándole a prestarle atención. El segundo es el ajuste del umbral de decisión, que en lugar de cambiar el entrenamiento cambia cómo interpretamos las probabilidades de salida: bajar el corte hace que el modelo marque a más clientes como en riesgo, recuperando recall.
Estas dos defensas son baratas, no distorsionan la distribución original de los datos y, en muchos casos, son suficientes. Pero tienen un techo. Cuando el desbalance es extremo —tasas de churn de un solo dígito bajo— o cuando la frontera entre clientes que se van y que se quedan es muy difusa, ajustar pesos y umbrales no basta: el modelo simplemente no ha visto suficientes ejemplos de la clase minoritaria como para aprender a caracterizarla bien. Ahí es donde entran las técnicas que actúan directamente sobre los datos, remodelando la proporción antes de entrenar.
Sobremuestreo, submuestreo y el problema de cada uno
La idea de remuestrear es directa: si el problema es que hay muy pocos ejemplos de la clase minoritaria en relación con la mayoritaria, cambiamos esa proporción antes de entrenar. Hay dos formas opuestas de hacerlo, y cada una tiene un coste.
El submuestreo reduce la clase mayoritaria: descarta ejemplos de clientes que se quedan hasta equilibrar las proporciones. Es rápido y aligera el entrenamiento, pero tira información potencialmente útil, y si tu dataset no es enorme, esa pérdida puede hacer que el modelo generalice peor. El sobremuestreo hace lo contrario: aumenta la clase minoritaria. La versión ingenua simplemente duplica ejemplos de clientes que abandonaron, pero eso introduce un riesgo evidente de sobreajuste, porque el modelo ve los mismos casos repetidos una y otra vez y acaba memorizándolos en lugar de aprender el patrón general.
El remuestreo solo se aplica al entrenamiento
Un error grave y sorprendentemente común: remuestrear antes de separar train y test. Si lo haces, ejemplos sintéticos o duplicados acaban en el conjunto de prueba y las métricas se inflan de forma irreal. El balanceo se aplica única y exclusivamente sobre los datos de entrenamiento, después del split, y la evaluación se hace siempre sobre la distribución real, sin tocar.
SMOTE: generar ejemplos sintéticos en lugar de duplicar
SMOTE —Synthetic Minority Over-sampling Technique— es la respuesta elegante al problema del sobremuestreo ingenuo. En lugar de duplicar clientes que abandonaron, genera ejemplos sintéticos nuevos. Su funcionamiento es geométricamente intuitivo: para cada cliente de la clase minoritaria, busca a sus vecinos más cercanos dentro de esa misma clase y crea puntos nuevos en algún lugar de la línea que los une. El resultado son clientes sintéticos que se parecen a los reales sin ser copias exactas, lo que enriquece la clase minoritaria sin caer en la repetición que provoca sobreajuste.
El sobremuestreo ingenuo repite los mismos casos y favorece el sobreajuste. SMOTE genera ejemplos nuevos interpolando entre clientes reales cercanos, enriqueciendo la frontera de decisión sin duplicar.
En Python, SMOTE vive en la librería imbalanced-learn, que se integra con scikit-learn. El siguiente código aplica SMOTE solo sobre el conjunto de entrenamiento de Ficticia Commerce —respetando la regla de oro de no tocar el test— y entrena el modelo sobre los datos rebalanceados.
from imblearn.over_sampling import SMOTE
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report
# X_train, y_train vienen del split estratificado previo
# SMOTE se aplica DESPUÉS del split, solo sobre entrenamiento
smote = SMOTE(sampling_strategy=0.5, random_state=42)
X_res, y_res = smote.fit_resample(X_train, y_train)
# sampling_strategy=0.5 -> la minoría pasa a ser el 50% de la mayoría
print(f"Antes: {y_train.value_counts().to_dict()}")
print(f"Después: {pd.Series(y_res).value_counts().to_dict()}")
modelo = RandomForestClassifier(n_estimators=300, random_state=42)
modelo.fit(X_res, y_res)
# Evaluación SIEMPRE sobre el test original, sin remuestrear
print(classification_report(y_test, modelo.predict(X_test)))
El parámetro sampling_strategy controla hasta dónde se rebalancea: un 0,5 lleva la clase minoritaria a la mitad del tamaño de la mayoritaria, no al 50 % del total. Rara vez conviene igualar las clases por completo, porque eso aleja demasiado los datos de entrenamiento de la realidad que el modelo encontrará en producción. La proporción óptima se busca experimentando, y el criterio para elegirla no es teórico: es qué configuración da el mejor recall sobre el conjunto de prueba real.
El estado del arte: más allá de SMOTE
SMOTE tiene casi dos décadas y, aunque sigue siendo el punto de referencia, ha generado toda una familia de variantes que corrigen sus limitaciones. SMOTE trata por igual a todos los clientes de la minoría, pero no todos son igual de informativos: los que están en la frontera entre las dos clases —los casos ambiguos, los clientes que podrían irse o quedarse— son los que más cuesta clasificar y los que más valor tiene reforzar.
Borderline-SMOTE se centra precisamente en esos casos fronterizos, generando ejemplos sintéticos solo cerca de la frontera de decisión, donde el modelo más se equivoca. ADASYN va un paso más allá y genera más ejemplos sintéticos en las zonas donde la clase minoritaria es más difícil de aprender, adaptando la densidad de generación a la dificultad local. Y las técnicas combinadas, como SMOTE-Tomek o SMOTE-ENN, encadenan sobremuestreo con una limpieza posterior que elimina ejemplos ruidosos o ambiguos, afinando la frontera por ambos lados a la vez.
En la frontera más avanzada, para bases de datos con muchos huecos y alta dimensionalidad, se exploran enfoques basados en redes neuronales: autoencoders que aprenden una representación comprimida del cliente y permiten generar o completar perfiles de forma más rica que la interpolación lineal de SMOTE. Es territorio de proyectos con equipos de datos maduros, pero conviene conocer que existe, porque marca hacia dónde evoluciona la disciplina cuando el desbalance se combina con datos dispersos.
Qué técnica elegir: un framework de decisión
Con tantas opciones, la pregunta práctica es por dónde empezar. La respuesta sensata es escalonada y empieza por lo más barato. Antes de remuestrear nada, prueba los pesos por clase y el ajuste de umbral: si con eso alcanzas un recall operativo, no necesitas complicarte. Si el desbalance es más severo, SMOTE básico es el siguiente escalón y resuelve la mayoría de los casos. Solo cuando SMOTE no llega —porque las clases se solapan mucho o la minoría es muy escasa— tiene sentido pasar a Borderline-SMOTE, ADASYN o las técnicas combinadas.
El criterio de elección, en todos los casos, es el mismo y es empírico: cuál de las técnicas da el mejor recall y F1 sobre el conjunto de prueba real, evaluado siempre sobre la distribución original sin tocar. No existe una técnica universalmente superior; existe la que mejor funciona sobre tus datos concretos, y descubrirla es cuestión de probar de forma ordenada, de menos a más complejo, justificando cada salto con números.
Regla práctica escalonada
Pesos por clase y umbral primero, SMOTE básico después, variantes avanzadas solo si los números lo justifican. La complejidad del balanceo se gana con evidencia sobre el conjunto de prueba, no se asume por defecto, y siempre se evalúa sobre la distribución real para no engañarse con métricas infladas.
Con el desbalance bajo control, el arsenal técnico de la detección está completo: sabemos predecir, explicar, ubicar el riesgo en el tiempo y corregir el sesgo estructural de los datos. Pero todo lo que hemos visto ha usado un caso de ecommerce como referencia. Los principios son transversales, pero cada sector tiene su propia anatomía de churn, sus propias señales y sus propias técnicas más sofisticadas. ¿Cómo cambia el problema cuando lo que está en juego no son pedidos, sino una red de clientes conectados entre sí que se influyen unos a otros?
¿Te ha resultado útil?
¿Tienes un problema que
los datos podrían resolver?
Sin formularios largos. Una conversación de 30 minutos para ver si tiene sentido.
Hablamos