A pesar de que los datos tabulares son el pan de cada día de la ciencia de datos de la industria, los cambios de datos a menudo se pasan por alto al analizar el rendimiento del modelo.
A todos nos ha pasado: usted desarrolla un modelo de aprendizaje automático, logra excelentes resultados en su conjunto de validación y luego lo implementa (o lo prueba) en un nuevo conjunto de datos del mundo real. De repente, el rendimiento baja.
Entonces, ¿cuál es el problema?
Por lo general, señalamos con el dedo el cambio de covarianza. La distribución de características en los nuevos datos es diferente a la de los datos de entrenamiento. Usamos esto como una tarjeta para “Salir libre de la cárcel”: “Los datos cambiaron, por lo que, naturalmente, el rendimiento es menor. Es culpa de los datos, no del modelo”.
Pero, ¿qué pasaría si dejáramos de utilizar el cambio de covarianza como excusa y empezáramos a utilizarlo como herramienta?
Creo que hay una mejor manera de manejar esto y crear un “estándar de oro” para analizar el desempeño del modelo. Ese método nos permitirá estimar el rendimiento con precisión, incluso cuando el suelo se mueve bajo nuestros pies.
El problema: comparar manzanas con naranjas
Veamos un ejemplo sencillo del mundo médico.
Imaginemos que entrenamos un modelo en pacientes de entre 40 y 89 años. Sin embargo, en nuestros nuevos datos de pruebas objetivo, el rango de edad es más estricto: 50-80.
Si simplemente ejecutamos el modelo con los datos de la prueba y lo comparamos con nuestras puntuaciones de validación originales, nos estamos engañando a nosotros mismos. Para comparar “manzanas con manzanas”, un buen científico de datos volvería al conjunto de validación, filtraría por pacientes de entre 50 y 80 años y volvería a calcular el rendimiento inicial.
Pero hagámoslo más difícil
Supongamos que nuestro conjunto de datos de prueba contiene millones de registros de entre 50 y 80 años y un solo paciente de 40 años.
¿Comparamos nuestros resultados con el rango de validación 40-80? ¿Nos comparamos con el rango 50-80?
Si ignoramos la distribución de edad específica (lo que hacen la mayoría de los análisis estándar), ese único paciente de 40 años teóricamente cambia la definición de cohorte. En la práctica, podríamos simplemente eliminar ese valor atípico. ¿Pero qué pasaría si hubiera 100 o 1.000 pacientes menores de 50 años? ¿Podemos hacerlo mejor? ¿Podemos automatizar este proceso para manejar diferencias en múltiples variables simultáneamente sin filtrar datos manualmente? Además, filtrar datos no es una buena solución. Sólo tiene en cuenta el rango correcto pero ignora el cambio de distribución dentro de ese rango.
La solución: ponderación de probabilidad inversa
La solución es volver a ponderar matemáticamente nuestros datos de validación para que se parezcan a los datos de prueba. En lugar de inclusión/exclusión binaria (mantener o eliminar una fila), asignamos un peso continuo a cada registro en nuestro conjunto de validación. Es como una extensión del método de filtrado simple anterior para que coincida con el mismo rango de edad.
Peso = 1: Análisis estándar. Peso = 0: Excluir el registro (filtrado). El peso es flotante no negativo: muestrear hacia abajo o hacia arriba la influencia del registro.
La intuición
En nuestro ejemplo (Prueba: 50-80 años + uno de 40 años), la solución es imitar la cohorte de prueba dentro de nuestro conjunto de validación. Queremos que nuestro conjunto de validación “finja” que tiene exactamente la misma distribución de edad que el conjunto de prueba.
Nota: Si bien es posible transformar estas ponderaciones en inclusión/exclusión binaria mediante un submuestreo aleatorio, esto generalmente no ofrece ninguna ventaja estadística sobre el uso de las ponderaciones directamente. El submuestreo es principalmente útil por intuición o si sus herramientas de análisis de rendimiento específicas no pueden manejar datos ponderados.
las matemáticas
Formalicemos esto. Necesitamos definir dos probabilidades:
Pt(x): La probabilidad de ver el valor de la característica x (p. ej., Edad) en los datos de la prueba objetivo. Pv(x): la probabilidad de ver el valor de característica x en los datos de Validación.
El peso w para cualquier registro dado con la característica x es la relación de estas probabilidades:
w(x) := Pt(x) / Pv(x)
Esto es intuitivo. Si las personas de 60 años son raras en el entrenamiento (Pv es bajo) pero comunes en la producción (Pt es alto), la proporción es grande. Ponderamos estos registros en nuestra evaluación para que coincidan con la realidad. Por otro lado, en nuestro ejemplo, donde el conjunto de pruebas tiene estrictamente entre 50 y 80 años, cualquier paciente de validación fuera de este rango recibirá una ponderación de 0 (ya que Pt(Edad)=0). En la práctica, esto equivale a excluirlos, exactamente según sea necesario.
Esta es una técnica estadística a menudo llamada muestreo de importancia o ponderación de probabilidad inversa (IPW).
Al aplicar estas ponderaciones al calcular métricas (como precisión, AUC o RMSE) en su conjunto de validación, crea una cohorte sintética que coincide perfectamente con el dominio de prueba. Ahora puedes comparar manzanas con manzanas sin quejarte del cambio.
La extensión: manejar cambios de alta dimensión
Hacer esto para una variable (Edad) es fácil. Puedes usar histogramas/bins. Pero ¿qué pasa si los datos cambian simultáneamente entre docenas de variables diferentes? No podemos construir un histograma de una docena de dimensiones. La solución es un truco inteligente que utiliza un clasificador binario.
Entrenamos un nuevo modelo (un “modelo de propensión”, llamémoslo Mp) para distinguir entre los dos conjuntos de datos.
Entrada: Las características del registro (Edad, IMC, Presión arterial, etc.) o las variables que deseamos controlar. Objetivo: 0 si el registro es de Validación, 1 si el registro es del conjunto de Prueba.
Si este modelo puede distinguir fácilmente los datos (AUC > 0,5), significa que hay un cambio de covariable. El AUC de Mp también sirve como herramienta de diagnóstico. Interpreta qué tan diferentes son los datos de su prueba del conjunto de validación y qué tan importante fue tenerlos en cuenta. Fundamentalmente, el resultado probabilístico de este modelo nos proporciona exactamente lo que necesitamos para calcular las ponderaciones.
Usando el teorema de Bayes, el peso de una muestra x se convierte en las probabilidades de que la muestra pertenezca al conjunto de prueba:
w(x) := Mp(x) / (1 – Mp(x))
Si Mp(x) ~ 0,5, los puntos de datos son indistinguibles y el peso es 1. Si Mp(x) -> 1, el modelo está muy seguro de que se parecen a los datos de prueba y el peso aumenta.
Nota: La aplicación de estas ponderaciones no necesariamente conduce a una caída en el rendimiento esperado. En algunos casos, la distribución de la prueba podría desplazarse hacia subgrupos en los que su modelo sea realmente más preciso. En ese escenario, el método ampliará esas instancias y su rendimiento estimado lo reflejará.
¿Funciona?
Sí, como por arte de magia. Si toma su conjunto de validación, aplica estas ponderaciones y luego traza las distribuciones de sus variables, se superpondrán perfectamente a las distribuciones de su conjunto de prueba objetivo.
Es incluso más poderoso que eso: alinea la distribución conjunta de todas las variables, no solo su distribución individual. Sus datos de validación ponderados se vuelven prácticamente indistinguibles de los datos de prueba objetivo cuando el predictor es óptimo.
Esta es una generalización de la variable única que vimos anteriormente y produce exactamente el mismo resultado para una sola variable. Mp aprende intuitivamente las diferencias entre nuestros conjuntos de datos de prueba y validación. Luego utilizamos esta “comprensión” aprendida para contrarrestar matemáticamente la diferencia.
Por ejemplo, puede mirar este fragmento de código para generar 2 distribuciones de edad: una uniforme (conjunto de validación) y la otra distribución normal (conjunto de prueba objetivo), con nuestras ponderaciones.
Fragmento de código importar pandas como pd importar numpy como np importar plotly.graph_objects como go df = pd.DataFrame({“Edad”: np.random.randint(40,89, 10000) }) df2 = pd.DataFrame({“Edad”: np.random.normal(65, 10, 10000) }) df2[“Age”] = df2[“Age”].round().astype(int) df2 = df2[df2[“Age”].between(40,89)].reset_index(drop=True) df3 = df.copy() def get_fig(df:pd.DataFrame, title:str): si ‘peso’ no está en df.columns: df[“weight”] = 1 recuento_edad = df.groupby(“Edad”)[“weight”].sum().reset_index().sort_values(“Edad”) tot = df[“weight”].sum() recuento_edad[“Percentage”] = 100 * recuento_edad[“weight”] /tot f = ir.Bar(x=cuenta_edad[“Age”]y=recuento_edad[“Percentage”]nombre=título) return f, age_count f1, age_count1 = get_fig(df, “ValidationSet”) f2, age_count2 = get_fig(df2, “TargetTestSet”) age_stats = age_count1[[“Age”, “Percentage”]].merge(edad_count2[[“Age”, “Percentage”]].rename(columnas={“Porcentaje”: “Porcentaje2”}), en=[“Age”]) estadísticas_edad[“weight”] = estadísticas_edad[“Percentage2”] / estadísticas_edad[“Percentage”]
df3 = df3.merge(age_stats[[“Age”, “weight”]], en =[“Age”]) f3, _ = get_fig(df3, “ValidationSet-Weighted”) fig = go.Figure(layout={“title”:”Age Distribution”}) fig.add_trace(f1) fig.add_trace(f2) fig.add_trace(f3) fig.update_xaxes(title_text=’Edad’) # Establece el título del eje x fig.update_yaxes(title_text=’Porcentaje’) # Establece el título del eje y fig.show()
Limitaciones
Si bien esta es una técnica poderosa, no siempre funciona. Hay tres limitaciones estadísticas principales:
Factores de confusión ocultos: si el cambio es causado por una variable que no midió (por ejemplo, un marcador genético que no tiene en sus datos tabulares), no puede sopesarlo. Sin embargo, como desarrolladores de modelos, normalmente intentamos utilizar las funciones más predictivas en nuestro modelo cuando es posible. Ignorabilidad (falta de superposición): no se puede dividir por cero. Si Pv(x) es cero (por ejemplo, sus datos de entrenamiento no tienen pacientes mayores de 90 años, pero el conjunto de prueba sí), el peso explota hasta el infinito. La solución: identifique estos grupos que no se superponen. Si su conjunto de validación literalmente no contiene información sobre una subpoblación específica, debe excluir explícitamente esa subpoblación de la comparación y marcarla como “territorio desconocido”. Calidad del modelo de propensión: dado que confiamos en un modelo (Mp) para estimar los pesos, cualquier imprecisión o calibración deficiente en este modelo introducirá ruido. Para cambios de baja dimensión (como una única variable de ‘Edad’), esto es insignificante, pero para cambios complejos de alta dimensión, es fundamental garantizar que Mp esté bien calibrado.
Aunque el modelo de propensión no es perfecto en la práctica, la aplicación de estas ponderaciones reduce significativamente el cambio de distribución. Esto proporciona un indicador mucho más preciso del rendimiento en el mundo real que no hacer nada en absoluto.
Una nota sobre el poder estadístico
Tenga en cuenta que el uso de ponderaciones cambia el tamaño efectivo de la muestra. Las ponderaciones de varianza altas reducen la estabilidad de sus estimaciones.
Bootstrapping: si utiliza bootstrapping, estará seguro siempre que incorpore los pesos en el proceso de remuestreo.
Cálculos de potencia: no utilice el número bruto de filas (N). Consulte la fórmula del tamaño de muestra efectivo (ESS de Kish) para comprender el verdadero poder de su análisis ponderado.
¿Qué pasa con las imágenes y los textos?
El método del modelo de propensión también funciona en esos dominios. Sin embargo, el principal problema desde una perspectiva práctica suele ser la ignorancia. Existe una separación completa entre nuestra validación y el conjunto de pruebas objetivo, lo que conduce a la incapacidad de contrarrestar el cambio. Esto no significa que nuestro modelo funcionará mal en esos conjuntos de datos. Simplemente significa que no podemos estimar su rendimiento en función de su validación actual, que es completamente diferente.
Resumen
La mejor práctica para evaluar el rendimiento del modelo en datos tabulares es tener en cuenta estrictamente el cambio de covarianza. En lugar de utilizar el cambio como excusa para un rendimiento deficiente, utilice la ponderación de probabilidad inversa para estimar cómo debería funcionar su modelo en el nuevo entorno.
Esto le permite responder una de las preguntas más difíciles en la implementación: “¿La caída del rendimiento se debe a que los datos cambian o el modelo realmente no funciona?”
Si utiliza este método, puede explicar la brecha entre las métricas de capacitación y producción.
Si esto le resultó útil, conectémonos en LinkedIn