La preparación de datos es el proceso de transformar los datos en bruto en una forma apropiada para la modelización.
Un enfoque ingenuo para preparar los datos aplica la transformación en todo el conjunto de datos antes de evaluar el rendimiento del modelo. Esto da lugar a un problema denominado fuga de datos donde el conocimiento del conjunto de pruebas se filtra en el conjunto de datos utilizado para entrenar el modelo. Esto puede dar lugar a una estimación incorrecta del rendimiento del modelo al hacer predicciones sobre nuevos datos.
Se requiere una aplicación cuidadosa de las técnicas de preparación de datos a fin de evitar la fuga de datos, y esto varía según el esquema de evaluación del modelo utilizado, como la división de la prueba del tren o la validación cruzada del pliegue k.
En este tutorial, descubrirá cómo evitar la fuga de datos durante la preparación de los datos al evaluar los modelos de aprendizaje de las máquinas.
Después de completar este tutorial, lo sabrás:
- La aplicación ingenua de los métodos de preparación de datos a todo el conjunto de datos da lugar a una fuga de datos que provoca estimaciones incorrectas del rendimiento del modelo.
- La preparación de los datos debe realizarse en el conjunto de la capacitación sólo para evitar la fuga de datos.
- Cómo implementar la preparación de datos sin fugas de datos para la división de pruebas de trenes y la validación cruzada de k-fold en Python.
Descubre la limpieza de datos, la selección de características, la transformación de datos, la reducción de la dimensionalidad y mucho más en mi nuevo libro, con 30 tutoriales paso a paso y el código fuente completo en Python.
Empecemos.
Resumen del Tutorial
Este tutorial está dividido en tres partes; son:
- Problema con la preparación de datos ingenuos
- Preparación de los datos con el tren y los equipos de prueba
- Evaluación de la prueba del tren con preparación de datos ingenua
- Evaluación de la prueba del tren con la preparación correcta de los datos
- Preparación de datos con validación cruzada de k-fold
- Evaluación de validación cruzada con preparación de datos ingenua
- Evaluación de validación cruzada con la preparación correcta de los datos
Problema con la preparación de datos ingenuos
La manera en que las técnicas de preparación de datos se aplican a los asuntos de datos.
Un enfoque común es aplicar primero una o más transformaciones a todo el conjunto de datos. Luego el conjunto de datos se divide en conjuntos de trenes y pruebas o se utiliza una validación cruzada de pliegues k para ajustar y evaluar un modelo de aprendizaje de máquina.
- 1. Preparar el conjunto de datos
- 2. 2. Dividir los datos
- 3. Evaluar los modelos
Aunque es un enfoque común, es peligrosamente incorrecto en la mayoría de los casos.
El problema de aplicar las técnicas de preparación de datos antes de dividir los datos para la evaluación del modelo es que puede dar lugar a la fuga de datos y, a su vez, es probable que dé lugar a una estimación incorrecta del rendimiento del modelo en el problema.
La fuga de datos se refiere a un problema en el que la información sobre el conjunto de datos de retención, como un conjunto de datos de prueba o validación, se pone a disposición del modelo en el conjunto de datos de capacitación. Esta fuga suele ser pequeña y sutil, pero puede tener un efecto marcado en el rendimiento.
… la fuga significa que la información se revela al modelo que le da una ventaja poco realista para hacer mejores predicciones. Esto podría suceder cuando los datos de las pruebas se filtran en el conjunto de la formación, o cuando los datos del futuro se filtran al pasado. Cada vez que a un modelo se le da información a la que no debería tener acceso cuando está haciendo predicciones en tiempo real en la producción, hay una fuga.
– Página 93, Ingeniería de características para el aprendizaje de la máquina, 2018.
Conseguimos la fuga de datos aplicando técnicas de preparación de datos a todo el conjunto de datos.
No se trata de un tipo directo de fuga de datos, en el que entrenaríamos el modelo en el conjunto de datos de prueba. En cambio, es un tipo indirecto de fuga de datos, en el que algunos conocimientos sobre el conjunto de datos de la prueba, capturados en estadísticas resumidas, están a disposición del modelo durante el entrenamiento. Esto puede hacer que sea un tipo de fuga de datos más difícil de detectar, especialmente para los principiantes.
Otro aspecto del remuestreo se relaciona con el concepto de fuga de información, que es cuando los datos del conjunto de pruebas se utilizan (directa o indirectamente) durante el proceso de capacitación. Esto puede dar lugar a resultados demasiado optimistas que no se repitan en futuros puntos de datos y puede ocurrir de manera sutil.
– Página 55, Ingeniería y selección de características, 2019.
Por ejemplo, consideremos el caso en el que queremos normalizar un dato, es decir, escalar las variables de entrada al rango 0-1.
Cuando normalizamos las variables de entrada, esto requiere que primero calculemos los valores mínimo y máximo de cada variable antes de usar estos valores para escalar las variables. El conjunto de datos se divide entonces en conjuntos de datos de entrenamiento y de prueba, pero los ejemplos del conjunto de datos de entrenamiento saben algo acerca de los datos del conjunto de datos de prueba; han sido escalados por los valores mínimos y máximos globales, por lo que saben más acerca de la distribución global de la variable de lo que deberían.
Obtenemos el mismo tipo de fuga con casi todas las técnicas de preparación de datos; por ejemplo, la normalización estima los valores medios y de desviación estándar del dominio para escalar las variables; incluso los modelos que imputan valores perdidos utilizando un modelo o estadísticas resumidas se basarán en el conjunto de datos completo para rellenar los valores del conjunto de datos de capacitación.
La solución es sencilla.
La preparación de los datos debe ajustarse únicamente al conjunto de datos de entrenamiento. Es decir, cualquier coeficiente o modelo preparado para el proceso de preparación de datos debe utilizar únicamente filas de datos en el conjunto de datos de entrenamiento.
Una vez ajustados, los algoritmos o modelos de preparación de datos pueden aplicarse al conjunto de datos de entrenamiento y al conjunto de datos de prueba.
- 1. Dividir los datos.
- 2. Preparación de datos de ajuste en el conjunto de datos de entrenamiento.
- 3. Aplicar la preparación de los datos a los conjuntos de datos del tren y de las pruebas.
- 4. Evaluar los modelos.
En términos más generales, todo el proceso de modelización debe prepararse únicamente en el conjunto de datos de capacitación para evitar la fuga de datos. Esto podría incluir transformaciones de datos, pero también otras técnicas como la selección de características, la reducción de la dimensionalidad, la ingeniería de características y más. Esto significa que la llamada «evaluación del modelo» debería llamarse realmente «evaluación de la tubería de modelización».
Para que cualquier esquema de remuestreo produzca estimaciones de rendimiento que se generalizan a nuevos datos, debe contener todos los pasos del proceso de modelación que puedan afectar significativamente a la eficacia del modelo.
– Páginas 54-55, Ingeniería y selección de características, 2019.
Ahora que estamos familiarizados con la forma de aplicar la preparación de datos para evitar la fuga de datos, veamos algunos ejemplos trabajados.
¿Quieres empezar a preparar los datos?
Toma mi curso intensivo gratuito de 7 días por correo electrónico ahora (con código de muestra).
Haga clic para inscribirse y también para obtener una versión gratuita del curso en formato PDF.
Preparación de datos con trenes y equipos de prueba
En esta sección, evaluaremos un modelo de regresión logística utilizando conjuntos de trenes y pruebas en un conjunto de datos de clasificación binaria sintética donde las variables de entrada se han normalizado.
Primero, definamos nuestro conjunto de datos sintéticos.
Usaremos la función make_classification() para crear el conjunto de datos con 1.000 filas de datos y 20 características de entrada numérica. El siguiente ejemplo crea el conjunto de datos y resume la forma de los conjuntos de variables de entrada y salida.
# Conjunto de datos de clasificación de pruebas de sklearn.conjuntos de datos importación make_classification # Definir el conjunto de datos X, y = make_classification(n_muestras=1000, n_funciones=20, n_informativo=15, n_redundante=5, estado_aleatorio=7) # resumir el conjunto de datos imprimir(X.forma, y.forma) |
Al ejecutar el ejemplo se crea el conjunto de datos y se confirma que la parte de entrada del conjunto de datos tiene 1.000 filas y 20 columnas para las 20 variables de entrada y que la variable de salida tiene 1.000 ejemplos para coincidir con las 1.000 filas de datos de entrada, un valor por fila.
A continuación, podemos evaluar nuestro modelo en el conjunto de datos a escala, empezando por su enfoque ingenuo o incorrecto.
Evaluación de la prueba del tren con preparación de datos ingenua
El enfoque ingenuo consiste en aplicar primero el método de preparación de datos, luego dividir los datos antes de evaluar finalmente el modelo.
Podemos normalizar las variables de entrada usando la clase MinMaxScaler, que se define primero con la configuración por defecto escalando los datos al rango 0-1, luego el fit_transform() se llama función para ajustar la transformación en el conjunto de datos y aplicarla al conjunto de datos en un solo paso. El resultado es una versión normalizada de las variables de entrada, en la que cada columna de la matriz se normaliza por separado (por ejemplo, tiene su propio mínimo y máximo calculado).
... # Estandarizar el conjunto de datos scaler = MinMaxScaler() X = scaler.fit_transform(X) |
A continuación, podemos dividir nuestro conjunto de datos en trenes y conjuntos de pruebas utilizando la función train_test_split(). Usaremos el 67 por ciento para el conjunto de entrenamiento y el 33 por ciento para el conjunto de pruebas.
... # Dividido en tren y conjuntos de prueba X_tren, X_test, y_tren, y_test = prueba_de_trenes_split(X, y, tamaño_de_prueba=0.33, estado_aleatorio=1) |
Podemos entonces definir nuestro algoritmo de regresión logística a través de la clase LogisticRegression, con la configuración por defecto, y ajustarlo en el conjunto de datos de entrenamiento.
... # Encaja con el modelo modelo = LogisticRegression() modelo.encajar(X_tren, y_tren) |
El modelo de ajuste puede entonces hacer una predicción para los datos de entrada del conjunto de pruebas, y podemos comparar las predicciones con los valores esperados y calcular una puntuación de precisión de la clasificación.
... # Evaluar el modelo yhat = modelo.predecir(X_test) # Evaluar las predicciones exactitud = accuracy_score(y_test, yhat) imprimir(Precisión: %.3f’. % (exactitud*100)) |
A continuación se muestra el ejemplo completo.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# Enfoque ingenuo para normalizar los datos antes de dividirlos y evaluar el modelo de sklearn.conjuntos de datos importación make_classification de sklearn.model_selection importación prueba_de_trenes_split de sklearn.preprocesamiento importación MinMaxScaler de sklearn.modelo_lineal importación LogisticRegression de sklearn.métrica importación accuracy_score # Definir el conjunto de datos X, y = make_classification(n_muestras=1000, n_funciones=20, n_informativo=15, n_redundante=5, estado_aleatorio=7) # Estandarizar el conjunto de datos scaler = MinMaxScaler() X = scaler.fit_transform(X) # Dividido en tren y conjuntos de prueba X_tren, X_test, y_tren, y_test = prueba_de_trenes_split(X, y, tamaño_de_prueba=0.33, estado_aleatorio=1) # Encaja con el modelo modelo = LogisticRegression() modelo.encajar(X_tren, y_tren) # Evaluar el modelo yhat = modelo.predecir(X_test) # Evaluar las predicciones exactitud = accuracy_score(y_test, yhat) imprimir(Precisión: %.3f’. % (exactitud*100)) |
Ejecutando el ejemplo se normalizan los datos, se dividen los datos en trenes y conjuntos de pruebas, y luego se ajusta y evalúa el modelo.
Sus resultados específicos pueden variar dada la naturaleza estocástica del algoritmo de aprendizaje y el procedimiento de evaluación.
En este caso, podemos ver que la estimación para el modelo es de alrededor de 84,848 por ciento.
Dado que sabemos que hubo una fuga de datos, sabemos que esta estimación de la precisión del modelo es errónea.
A continuación, exploremos cómo podríamos preparar correctamente los datos para evitar la fuga de datos.
Evaluación de la prueba del tren con la preparación correcta de los datos
El enfoque correcto para realizar la preparación de los datos con una evaluación de división de la prueba del tren es ajustar la preparación de los datos en el conjunto de entrenamiento, y luego aplicar la transformación al tren y a los conjuntos de pruebas.
Esto requiere que primero dividamos los datos en trenes y conjuntos de pruebas.
... # Dividido en tren y conjuntos de prueba X_tren, X_test, y_tren, y_test = prueba_de_trenes_split(X, y, tamaño_de_prueba=0.33, estado_aleatorio=1) |
Podemos entonces definir el MinMaxScaler y llamar a la fit() en el set de entrenamiento, y luego aplicar la transform() funcionan en el tren y los conjuntos de pruebas para crear una versión normalizada de cada conjunto de datos.
... # definir el escalador scaler = MinMaxScaler() # Encajar en el conjunto de datos de entrenamiento scaler.encajar(X_tren) # escalar el conjunto de datos de entrenamiento X_tren = scaler.Transformar(X_tren) # Escala el conjunto de datos de la prueba X_test = scaler.Transformar(X_test) |
Esto evita la fuga de datos, ya que el cálculo del valor mínimo y máximo de cada variable de entrada se realiza utilizando únicamente el conjunto de datos de entrenamiento (X_tren) en lugar de todo el conjunto de datos (X).
El modelo puede entonces ser evaluado como antes.
A continuación se muestra el ejemplo completo.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# Enfoque correcto para normalizar los datos después de que los datos se dividan antes de que el modelo sea evaluado de sklearn.conjuntos de datos importación make_classification de sklearn.model_selection importación prueba_de_trenes_split de sklearn.preprocesamiento importación MinMaxScaler de sklearn.modelo_lineal importación LogisticRegression de sklearn.métrica importación accuracy_score # Definir el conjunto de datos X, y = make_classification(n_muestras=1000, n_funciones=20, n_informativo=15, n_redundante=5, estado_aleatorio=7) # Dividido en tren y conjuntos de prueba X_tren, X_test, y_tren, y_test = prueba_de_trenes_split(X, y, tamaño_de_prueba=0.33, estado_aleatorio=1) # definir el escalador scaler = MinMaxScaler() # Encajar en el conjunto de datos de entrenamiento scaler.encajar(X_tren) # escalar el conjunto de datos de entrenamiento X_tren = scaler.Transformar(X_tren) # Escala el conjunto de datos de la prueba X_test = scaler.Transformar(X_test) # Encaja con el modelo modelo = LogisticRegression() modelo.encajar(X_tren, y_tren) # Evaluar el modelo yhat = modelo.predecir(X_test) # Evaluar las predicciones exactitud = accuracy_score(y_test, yhat) imprimir(Precisión: %.3f’. % (exactitud*100)) |
Al ejecutar el ejemplo, se dividen los datos en conjuntos de trenes y de pruebas, se normalizan los datos correctamente, y luego se ajusta y evalúa el modelo.
Sus resultados específicos pueden variar dada la naturaleza estocástica del algoritmo de aprendizaje y el procedimiento de evaluación.
En este caso, podemos ver que la estimación para el modelo es de alrededor de 85,455 por ciento, lo que es más exacto que la estimación con fuga de datos en la sección anterior que alcanzó una precisión del 84,848 por ciento.
Esperamos que la fuga de datos resulte en una estimación incorrecta del rendimiento del modelo. Esperamos que sea una estimación optimista con la fuga de datos, por ejemplo, un mejor rendimiento, aunque en este caso, podemos ver que la fuga de datos dio lugar a un rendimiento ligeramente peor. Esto podría deberse a la dificultad de la tarea de predicción.
Preparación de datos con validación cruzada de k-fold
En esta sección, evaluaremos un modelo de regresión logística utilizando la validación cruzada de pliegues k en un conjunto de datos de clasificación binaria sintética en el que las variables de entrada se han normalizado.
Recordarán que la validación cruzada de k implica la división de un conjunto de datos en grupos de filas k no superpuestas. El modelo es entonces entrenado en todos los grupos menos en uno para formar un conjunto de datos de entrenamiento y luego es evaluado en el pliegue sostenido. Este proceso se repite para que cada pliegue tenga la oportunidad de ser utilizado como el conjunto de pruebas de retención. Por último, se informa sobre el rendimiento medio de todas las evaluaciones.
El procedimiento de validación cruzada de pliegues k suele dar una estimación más fiable del rendimiento del modelo que una división de prueba de trenes, aunque es más costoso desde el punto de vista computacional dado el repetido ajuste y evaluación de los modelos.
Veamos primero la preparación de los datos ingenuos con validación cruzada de k-fold.
Evaluación de validación cruzada con preparación de datos ingenua
La preparación de datos ingenuos con validación cruzada implica aplicar primero las transformaciones de datos y luego utilizar el procedimiento de validación cruzada.
Utilizaremos el conjunto de datos sintéticos preparados en la sección anterior y normalizaremos los datos directamente.
... # Estandarizar el conjunto de datos scaler = MinMaxScaler() X = scaler.fit_transform(X) |
Primero hay que definir el procedimiento de validación cruzada del pliegue k. Utilizaremos la validación cruzada estratificada por 10 veces, que es la mejor práctica para la clasificación. Repetido significa que todo el procedimiento de validación cruzada se repite varias veces, tres en este caso. Estratificado significa que cada grupo de filas tendrá la composición relativa de ejemplos de cada clase como el conjunto de datos completo. Utilizaremos k=10 o una validación cruzada de 10 veces.
Esto puede lograrse utilizando el RepeatedStratifiedKFold, que puede configurarse en tres repeticiones y 10 pliegues, y luego utilizando la función cross_val_score() para realizar el procedimiento, pasando en el modelo definido, el objeto de validación cruzada y la métrica para calcular, en este caso, la precisión.
... # Definir el procedimiento de evaluación cv = RepeatedStratifiedKFold(n_splits=10, n_repeticiones=3, estado_aleatorio=1) # Evaluar el modelo usando validación cruzada resultados = puntaje_valor_cruzado(modelo, X, y, puntuación=«exactitud, cv=cv, n_jobs=–1) |
Podemos entonces reportar la precisión promedio en todas las repeticiones y pliegues.
Enlazando todo esto, el ejemplo completo de evaluación de un modelo con validación cruzada utilizando la preparación de datos con fuga de datos se enumera a continuación.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# Preparación de datos ingenuos para la evaluación del modelo con validación cruzada de k-fold de numpy importación significa de numpy importación std de sklearn.conjuntos de datos importación make_classification de sklearn.model_selection importación puntaje_valor_cruzado de sklearn.model_selection importación RepeatedStratifiedKFold de sklearn.preprocesamiento importación MinMaxScaler de sklearn.modelo_lineal importación LogisticRegression # Definir el conjunto de datos X, y = make_classification(n_muestras=1000, n_funciones=20, n_informativo=15, n_redundante=5, estado_aleatorio=7) # Estandarizar el conjunto de datos scaler = MinMaxScaler() X = scaler.fit_transform(X) # Definir el modelo modelo = LogisticRegression() # Definir el procedimiento de evaluación cv = RepeatedStratifiedKFold(n_splits=10, n_repeticiones=3, estado_aleatorio=1) # Evaluar el modelo usando validación cruzada resultados = puntaje_valor_cruzado(modelo, X, y, puntuación=«exactitud, cv=cv, n_jobs=–1) # Informe de rendimiento imprimir(«Precisión: %.3f (%.3f) % (significa(resultados)*100, std(resultados)*100)) |
Al ejecutar el ejemplo se normalizan los datos primero, y luego se evalúa el modelo mediante la validación cruzada estratificada repetida.
Sus resultados específicos pueden variar dada la naturaleza estocástica del algoritmo de aprendizaje y el procedimiento de evaluación.
En este caso, podemos ver que el modelo alcanzó una precisión estimada de alrededor del 85.300 por ciento, que sabemos que es incorrecta dada la fuga de datos permitida a través del procedimiento de preparación de datos.
A continuación, veamos cómo podemos evaluar el modelo con validación cruzada y evitar la fuga de datos.
Evaluación de validación cruzada con la preparación correcta de los datos
La preparación de datos sin fuga de datos cuando se utiliza la validación cruzada es un poco más difícil.
Requiere que el método de preparación de datos se prepare en el conjunto de capacitación y se aplique a los conjuntos de capacitación y pruebas dentro del procedimiento de validación cruzada, por ejemplo, los grupos de pliegues de filas.
Podemos lograrlo definiendo una tubería de modelación que defina una secuencia de pasos de preparación de datos para realizar y que termine en el modelo para ajustar y evaluar.
Para proporcionar una metodología sólida, deberíamos limitarnos a elaborar la lista de técnicas de preprocesamiento, estimarlas sólo en presencia de los puntos de datos de capacitación, y luego aplicar las técnicas a los datos futuros (incluido el conjunto de pruebas).
– Página 55, Ingeniería y selección de características, 2019.
El procedimiento de evaluación pasa de evaluar simple e incorrectamente sólo el modelo a evaluar correctamente todo el proceso de preparación de datos y el modelo juntos como una sola unidad atómica.
Esto se puede lograr usando la clase Pipeline.
Esta clase toma una lista de pasos que definen la tubería. Cada paso de la lista es una tupla con dos elementos. El primer elemento es el nombre del paso (una cadena) y el segundo es el objeto configurado del paso, como una transformación o un modelo. El modelo sólo se admite como el paso final, aunque podemos tener tantas transformaciones como queramos en la secuencia.
... # Definir el oleoducto pasos = lista() pasos.anexar((«escarificador, MinMaxScaler())) pasos.anexar((«modelo, LogisticRegression())) tubería = Oleoducto(pasos=pasos) |
Podemos entonces pasar el objeto configurado a la cross_val_score() para la evaluación.
... # Definir el procedimiento de evaluación cv = RepeatedStratifiedKFold(n_splits=10, n_repeticiones=3, estado_aleatorio=1) # Evaluar el modelo usando validación cruzada resultados = puntaje_valor_cruzado(tubería, X, y, puntuación=«exactitud, cv=cv, n_jobs=–1) |
Enlazando todo esto, a continuación se enumera el ejemplo completo de la preparación correcta de datos sin fugas de datos cuando se utiliza la validación cruzada.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# Preparación correcta de los datos para la evaluación del modelo con validación cruzada de k-fold de numpy importación significa de numpy importación std de sklearn.conjuntos de datos importación make_classification de sklearn.model_selection importación puntaje_valor_cruzado de sklearn.model_selection importación RepeatedStratifiedKFold de sklearn.preprocesamiento importación MinMaxScaler de sklearn.modelo_lineal importación LogisticRegression de sklearn.tubería importación Oleoducto # Definir el conjunto de datos X, y = make_classification(n_muestras=1000, n_funciones=20, n_informativo=15, n_redundante=5, estado_aleatorio=7) # Definir el oleoducto pasos = lista() pasos.anexar((«escarificador, MinMaxScaler())) pasos.anexar((«modelo, LogisticRegression())) tubería = Oleoducto(pasos=pasos) # Definir el procedimiento de evaluación cv = RepeatedStratifiedKFold(n_splits=10, n_repeticiones=3, estado_aleatorio=1) # Evaluar el modelo usando validación cruzada resultados = puntaje_valor_cruzado(tubería, X, y, puntuación=«exactitud, cv=cv, n_jobs=–1) # Informe de rendimiento imprimir(«Precisión: %.3f (%.3f) % (significa(resultados)*100, std(resultados)*100)) |
La ejecución del ejemplo normaliza los datos correctamente dentro de los pliegues de validación cruzada del procedimiento de evaluación para evitar la fuga de datos.
Sus resultados específicos pueden variar dada la naturaleza estocástica del algoritmo de aprendizaje y el procedimiento de evaluación.
En este caso, podemos ver que el modelo tiene una precisión estimada de alrededor de 85,433 por ciento, en comparación con el enfoque con fuga de datos que alcanzó una precisión de alrededor de 85,300 por ciento.
Al igual que en el ejemplo de la prueba del tren de la sección anterior, la eliminación de la fuga de datos ha dado lugar a una ligera mejora en el rendimiento cuando nuestra intuición podría sugerir una caída dado que la fuga de datos a menudo da lugar a una estimación optimista del rendimiento del modelo. No obstante, los ejemplos demuestran claramente que la fuga de datos sí afecta a la estimación del rendimiento del modelo y a la forma de corregir la fuga de datos realizando correctamente la preparación de los datos después de su división.