Por Jose R. Zapata
Ultima actualización: 24/May/2025
La validación train-test es un proceso fundamental utilizado en proyectos de machine learning que se enfoca en la validación y comparación de dos subconjuntos de datos, típicamente el conjunto de entrenamiento y el conjunto de prueba, o cualquier otro par de lotes de datos relevantes. Su aplicación es crucial antes de entrenar un modelo, al preparar los datos para la validación cruzada, o al contrastar un nuevo lote de datos que llega para inferencia con datos anteriores.
El objetivo principal de esta validación es identificar y comprender las diferencias o inconsistencias entre estos subconjuntos, como la presencia de fugas de datos (data leakage), que ocurre si información del conjunto de prueba se “filtra” al de entrenamiento de forma indebida, o el desvío de datos (data drift), que implica cambios en la distribución de las características o la etiqueta entre los conjuntos. Al realizar la validación train-test, los equipos de datos pueden asegurarse de que los conjuntos de datos utilizados para construir y evaluar modelos sean representativos y consistentes, lo cual es esencial para garantizar la fiabilidad y el rendimiento de los modelos de machine learning en entornos de producción.
📚 Importar librerias
# base libraries for data science
import warnings
import pandas as pd
from deepchecks.tabular import Dataset
from deepchecks.tabular.suites import train_test_validation
from sklearn.model_selection import train_test_split
warnings.filterwarnings("ignore", category=FutureWarning)
warnings.filterwarnings("ignore", category=RuntimeWarning)
# Leer datos desde un URL
url_data = "https://www.openml.org/data/get_csv/16826755/phpMYEkMl"
dataset = pd.read_csv(url_data, low_memory=False, na_values="?")
Definicion de tipos de datos
# Features numericas
cols_numeric_float = ["age", "fare"]
cols_numeric_int = ["sibsp", "parch"]
cols_numeric = cols_numeric_float + cols_numeric_int
# Features categoricas
cols_categoric = ["sex", "embarked"]
cols_categoric_ord = ["pclass"]
cols_categorical = cols_categoric + cols_categoric_ord
Categoricas
dataset[cols_categoric] = dataset[cols_categoric].astype("category")
dataset["pclass"] = pd.Categorical(dataset["pclass"], categories=[3, 2, 1], ordered=True)
Numericas
dataset[cols_numeric_float] = dataset[cols_numeric_float].astype("float")
dataset[cols_numeric_int] = dataset[cols_numeric_int].astype("int8")
Variable Target
target = "survived"
dataset[target] = dataset[target].astype("int8")
Si existen duplicados en el dataset, es importante eliminarlos para evitar cualquier sesgo en el conjunto de datos o fuga de datos (data leak) cuando se entrena un modelo de aprendizaje automático.
dataset = dataset.drop_duplicates()
Train / Test split
# split data into features and target
X_features = dataset.drop(target, axis="columns")
Y_target = dataset[target]
# 80% train, 20% test
x_train, x_test, y_train, y_test = train_test_split(
X_features, Y_target, stratify=Y_target, test_size=0.2, random_state=42
)
Train / Test Validation
train_ds = Dataset(
pd.concat([x_train, y_train], axis="columns"),
label=target,
cat_features=cols_categorical,
set_index_from_dataframe_index=True,
)
test_ds = Dataset(
pd.concat([x_test, y_test], axis="columns"),
label=target,
cat_features=cols_categorical,
set_index_from_dataframe_index=True,
)
validation_suite = train_test_validation()
suite_result = validation_suite.run(train_ds, test_ds)
# Note: the result can be saved as html using suite_result.save_as_html()
# or exported to json using suite_result.to_json()
suite_result.show_not_interactive()
Train Test Validation Suite
The suite is composed of various checks such as: Feature Drift, New Category Train Test, Index Train Test Leakage, etc...
Each check may contain conditions (which will result in pass ✓ /
fail ✖ / warning ! / error ⁈) as well as
other outputs such as plots or tables.
Suites, checks and conditions can all be modified. Read more about
custom suites.
Conditions Summary
Status | Check | Condition | More Info |
---|---|---|---|
✖ | Feature Label Correlation Change | Train-Test features' Predictive Power Score difference is less than 0.2 | Found 3 out of 13 features with PPS difference above threshold: {'boat': '0.66', 'cabin': '0.21', 'ticket': '0.26'} |
✖ | Feature Drift | categorical drift score < 0.2 and numerical drift score < 0.2 | Failed for 1 out of 8 columns. Found 1 numeric columns with Kolmogorov-Smirnov above threshold: {'body': '0.26'} |
✓ | Feature Label Correlation Change | Train features' Predictive Power Score is less than 0.7 | Passed for 13 relevant columns |
✓ | Datasets Size Comparison | Test-Train size ratio is greater than 0.01 | Test-Train size ratio is 0.25 |
✓ | New Category Train Test | Ratio of samples with a new category is less or equal to 0% | Passed for 3 relevant features |
✓ | Label Drift | Label drift score < 0.15 | Label's drift score Cramer's V is 0 |
✓ | Multivariate Drift | Drift value is less than 0.25 | Found drift value of: 0.09, corresponding to a domain classifier AUC of: 0.55 |
✓ | New Label Train Test | Number of new label values is less or equal to 0 | Found 0 new labels in test data: [] |
✓ | String Mismatch Comparison | No new variants allowed in test data | Passed for 7 relevant columns |
✓ | Index Train-Test Leakage | Ratio of leaking indices is less or equal to 0% | No index leakage found |
✓ | Train Test Samples Mix | Percentage of test data samples that appear in train data is less or equal to 5% | No samples mix found |
Check With Conditions Output
Feature Label Correlation Change
Return the Predictive Power Score of all features, in order to estimate each feature's ability to predict the label. Read More...
Conditions Summary
Status | Condition | More Info |
---|---|---|
✖ | Train-Test features' Predictive Power Score difference is less than 0.2 | Found 3 out of 13 features with PPS difference above threshold: {'boat': '0.66', 'cabin': '0.21', 'ticket': '0.26'} |
✓ | Train features' Predictive Power Score is less than 0.7 | Passed for 13 relevant columns |
Additional Outputs
Feature Drift
Calculate drift between train dataset and test dataset per feature, using statistical measures. Read More...
Conditions Summary
Status | Condition | More Info |
---|---|---|
✖ | categorical drift score < 0.2 and numerical drift score < 0.2 | Failed for 1 out of 8 columns. Found 1 numeric columns with Kolmogorov-Smirnov above threshold: {'body': '0.26'} |
Additional Outputs
The check shows the drift score and distributions for the features, sorted by drift score and showing only the top 5 features, according to drift score.
Datasets Size Comparison
Verify test dataset size comparing it to the train dataset size. Read More...
Conditions Summary
Status | Condition | More Info |
---|---|---|
✓ | Test-Train size ratio is greater than 0.01 | Test-Train size ratio is 0.25 |
Additional Outputs
Train | Test | |
---|---|---|
Size | 1047 | 262 |
New Category Train Test
Find new categories in the test set. Read More...
Conditions Summary
Status | Condition | More Info |
---|---|---|
✓ | Ratio of samples with a new category is less or equal to 0% | Passed for 3 relevant features |
Additional Outputs
# New Categories | Ratio of New Categories | New Categories Names | |
---|---|---|---|
Feature Name | |||
pclass | 0 | 0% | [] |
embarked | 0 | 0% | [] |
sex | 0 | 0% | [] |
Label Drift
Calculate label drift between train dataset and test dataset, using statistical measures. Read More...
Conditions Summary
Status | Condition | More Info |
---|---|---|
✓ | Label drift score < 0.15 | Label's drift score Cramer's V is 0 |
Additional Outputs
The check shows the drift score and distributions for the label.
Multivariate Drift
Calculate drift between the entire train and test datasets using a model trained to distinguish between them. Read More...
Conditions Summary
Status | Condition | More Info |
---|---|---|
✓ | Drift value is less than 0.25 | Found drift value of: 0.09, corresponding to a domain classifier AUC of: 0.55 |
Additional Outputs
Main features contributing to drift
Check Without Conditions Output
Other Checks That Weren't Displayed
Check | Reason |
---|---|
Date Train Test Leakage Duplicates | DatasetValidationError: Dataset does not contain a datetime. see Dataset docs |
Date Train Test Leakage Overlap | DatasetValidationError: Dataset does not contain a datetime. see Dataset docs |
New Label Train Test | Nothing found |
String Mismatch Comparison | Nothing found |
Index Train-Test Leakage | Nothing found |
Train Test Samples Mix | Nothing found |
Análisis de los resultados
Se detectó que la correlación característica-etiqueta cambió significativamente entre los conjuntos de entrenamiento y prueba para algunas características, y también se identificó desvío en una característica numérica. Aunque la mayoría de las condiciones se cumplieron, incluyendo la ausencia de nuevas categorías o etiquetas en el conjunto de prueba, el tamaño relativo de los conjuntos fue aceptable, no se encontró fuga de índices ni mezcla de muestras, y el desvío multivariado y el desvío de etiquetas estaban dentro de los umbrales aceptables, los problemas detectados en la correlación y el desvío de características sugieren la necesidad de investigar y posiblemente revisar la división de los datos o entender el origen del desvío.
Aquí se detallan los resultados obtenidos para cada check en la validación train-test:
- Cambio en la Correlación Característica-Etiqueta (Feature Label Correlation Change): Esta prueba falló (✖). La condición que verificaba que la diferencia del Predictive Power Score (PPS) entre los conjuntos de entrenamiento y prueba fuera menor a 0.2 no se cumplió. Se encontraron 3 de 13 características con una diferencia de PPS por encima del umbral: ‘boat’ (0.66), ‘cabin’ (0.21) y ’ticket’ (0.26). Una gran diferencia (especialmente si el PPS del conjunto de entrenamiento es mayor) puede indicar fuga de datos, mientras que si el PPS del conjunto de prueba es mayor, podría señalar desvío en el conjunto de prueba que causó una correlación coincidente con la etiqueta objetivo.
- Desvío de Características (Feature Drift): Esta prueba falló (✖). La condición que requería que el puntaje de desvío categórico y numérico fuera menor a 0.2 no se cumplió para una columna. Se encontró 1 columna numérica (‘body’) con un puntaje de Kolmogorov-Smirnov por encima del umbral (0.26). El puntaje de desvío mide la diferencia entre las distribuciones de entrenamiento y prueba para cada característica.
- Cambio en la Correlación Característica-Etiqueta (Feature Label Correlation Change): Esta prueba adicional (no la que falló anteriormente, pero relacionada) pasó (✓). La condición que verificaba que el Predictive Power Score de las características en el conjunto de entrenamiento fuera menor a 0.7 se cumplió para las 13 características relevantes.
- Comparación del Tamaño de los Conjuntos de Datos (Datasets Size Comparison): Esta prueba pasó (✓). La condición que verificaba que la proporción del tamaño del conjunto de prueba respecto al de entrenamiento fuera mayor a 0.01 se cumplió, siendo la proporción 0.25.
- Nueva Categoría Train Test (New Category Train Test): Esta prueba pasó (✓). La condición que verificaba que la proporción de muestras con una nueva categoría en el conjunto de prueba fuera menor o igual a 0% se cumplió para las 3 características relevantes; no se encontraron nuevas categorías.
- Desvío de Etiquetas (Label Drift): Esta prueba pasó (✓). La condición que verificaba que el puntaje de desvío de etiquetas fuera menor a 0.15 se cumplió; el puntaje de desvío Cramer’s V de la etiqueta fue 0. El puntaje de desvío de etiquetas mide la diferencia en la distribución de la etiqueta entre los conjuntos.
- Desvío Multivariado (Multivariate Drift): Esta prueba pasó (✓). La condición que verificaba que el valor de desvío fuera menor a 0.25 se cumplió, encontrándose un valor de desvío de 0.09, que corresponde a un AUC del clasificador de dominio de 0.55. El desvío multivariado se calcula utilizando un modelo entrenado para distinguir entre los conjuntos de entrenamiento y prueba.
- Nueva Etiqueta Train Test (New Label Train Test): Esta prueba pasó (✓). La condición que verificaba que el número de nuevos valores de etiqueta en el conjunto de prueba fuera menor o igual a 0 se cumplió; no se encontraron nuevas etiquetas.
- Comparación de Discrepancia de Cadenas (String Mismatch Comparison): Esta prueba pasó (✓). La condición que no permitía nuevas variantes de cadena en el conjunto de prueba se cumplió para las 7 columnas relevantes.
- Fuga de Índice Train-Test (Index Train-Test Leakage): Esta prueba pasó (✓). La condición que verificaba que la proporción de índices con fuga fuera menor o igual a 0% se cumplió; no se encontró fuga de índices.
- Mezcla de Muestras Train Test (Train Test Samples Mix): Esta prueba pasó (✓). La condición que verificaba que el porcentaje de muestras del conjunto de prueba que aparecen en el conjunto de entrenamiento fuera menor o igual a 5% se cumplió; no se encontró mezcla de muestras.
- Date Train Test Leakage Duplicates y Date Train Test Leakage Overlap: Estas pruebas no se mostraron debido a un error
DatasetValidationError
, indicando que el conjunto de datos no contenía una columna de tipo datetime.
Conclusion
los resultados indicaron que no todas las expectativas se cumplieron. Se identificaron fallos clave en el cambio de correlación entre algunas características y la etiqueta, donde características como ‘boat’, ‘cabin’ y ’ticket’ mostraron una diferencia significativa en su Predictive Power Score (PPS) entre los conjuntos.
Además, se detectó desvío en la distribución de una característica numérica, específicamente en la columna ‘body’, cuyo puntaje de Kolmogorov-Smirnov superó el umbral definido. Estos hallazgos son importantes porque sugieren que los datos de entrenamiento y prueba podrían no ser lo suficientemente similares en aspectos críticos para el modelado, lo que podría afectar la capacidad de generalización de un modelo. A pesar de estas fallas, la suite confirmó que la mayoría de las otras verificaciones pasaron, incluyendo una proporción aceptable del tamaño de los conjuntos, la ausencia de nuevas categorías o etiquetas en el conjunto de prueba, la no detección de fuga de índices ni mezcla de muestras, y que el desvío multivariado y de etiquetas estaban dentro de los umbrales aceptables, lo que indica consistencia en varios aspectos de la estructura de los datos entre los conjuntos.
No obstante, los problemas identificados en la correlación característica-etiqueta y el desvío de la característica ‘body’ requieren una investigación más profunda de los datos y posible ajuste en el manejo de los datos antes de proceder al entrenamiento o evaluación del modelo.
📖 References
- https://docs.deepchecks.com/stable/tabular/auto_tutorials/quickstarts/plot_quick_train_test_validation.html
- https://joserzapata.github.io/courses/python-ciencia-datos/ml/
- https://joserzapata.github.io/courses/python-ciencia-datos/clasificacion/
- https://joserzapata.github.io/post/lista-proyecto-machine-learning/