ScikitLearn
Tutorial ScikitLearn: Pipelines y Validación Cruzada
Domina la integración de Pipelines en Scikit-Learn con `cross_val_score` para evaluar modelos de aprendizaje automático con precisión y evitar fugas de datos.
Aprende ScikitLearn GRATIS y certifícateIntegración con cross_val_score
La integración de Pipelines con la función cross_val_score
de Scikit-Learn permite evaluar modelos de manera eficiente y estructurada. Al combinar ambos, se asegura que todas las etapas, desde el preprocesamiento hasta la predicción, se validen correctamente sin causar fugas de datos.
Por ejemplo, supongamos que estamos trabajando con el conjunto de datos de dígitos escrito a mano:
from sklearn.datasets import load_digits
from sklearn.pipeline import Pipeline
from sklearn.model_selection import cross_val_score
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
# Cargar los datos
digits = load_digits()
X, y = digits.data, digits.target
# Crear el Pipeline con memoria
pipeline = Pipeline([
('escalador', StandardScaler()),
('clasificador', LogisticRegression())
], memory='cache_directory')
# Evaluar el modelo usando validación cruzada
puntuaciones = cross_val_score(pipeline, X, y, cv=5)
print("Puntuaciones de validación cruzada:", puntuaciones)
print("Precisión media:", puntuaciones.mean())
En este ejemplo, se crea un Pipeline que primero estandariza las características con StandardScaler
y luego aplica un clasificador de regresión logística. El parámetro memory
almacena en caché los transformadores, optimizando la ejecución. La función cross_val_score
realiza una validación cruzada con 5 particiones, proporcionando una estimación fiable del rendimiento del modelo.
Al utilizar cross_val_score
con un Pipeline, garantizamos que el escalado y cualquier otra transformación se ajusten únicamente con los datos de entrenamiento en cada pliegue. Esto evita el sobreajuste y asegura una evaluación más realista.
También es posible personalizar la validación cruzada. Por ejemplo, para utilizar una validación cruzada estratificada:
from sklearn.model_selection import StratifiedKFold
# Definir la estrategia de validación cruzada
cv = StratifiedKFold(n_splits=5)
# Evaluar el modelo con la estrategia personalizada
puntuaciones = cross_val_score(pipeline, X, y, cv=cv)
print("Puntuaciones de validación cruzada:", puntuaciones)
print("Precisión media:", puntuaciones.mean())
La estrategia StratifiedKFold
mantiene la proporción de clases en cada partición, lo cual es crucial en problemas con clases desequilibradas.
Además, los Pipelines facilitan la incorporación de múltiples etapas de preprocesamiento. Por ejemplo, para añadir una selección de características:
from sklearn.feature_selection import SelectKBest, chi2
from sklearn.preprocessing import MinMaxScaler
# Crear un Pipeline con selección de características
pipeline = Pipeline([
('escalador', MinMaxScaler()),
('seleccion', SelectKBest(score_func=chi2, k=30)),
('clasificador', LogisticRegression(max_iter=1000, random_state=42))
], memory='cache_directory')
# Evaluar el modelo
puntuaciones = cross_val_score(pipeline, X, y, cv=5)
print("Puntuaciones de validación cruzada:", puntuaciones)
print("Precisión media:", puntuaciones.mean())
Aquí se utiliza SelectKBest
para seleccionar las 30 mejores características basadas en la prueba chi-cuadrado, antes de aplicar el clasificador. La integración con cross_val_score
permite evaluar todo el flujo de trabajo de manera cohesiva.
Integrar Pipelines con cross_val_score
no solo simplifica el código, sino que también mejora la reproducibilidad y la integridad del proceso de validación, aspectos fundamentales en proyectos de aprendizaje automático.
Uso de GridSearchCV
y RandomizedSearchCV
con Pipelines
La combinación de Pipelines con herramientas de búsqueda de hiperparámetros como GridSearchCV
y RandomizedSearchCV
en Scikit-Learn simplifica el proceso de optimización de modelos. Al integrar estas técnicas, se pueden ajustar los hiperparámetros de los pasos individuales del Pipeline de forma conjunta, facilitando la experimentación y mejorando el rendimiento del modelo.
Por ejemplo, supongamos que queremos optimizar un modelo de clasificación que incluye una etapa de preprocesamiento y un clasificador. Podemos utilizar un Pipeline para encapsular estas etapas y GridSearchCV
para encontrar la mejor combinación de hiperparámetros:
from sklearn.datasets import fetch_openml
from sklearn.model_selection import GridSearchCV
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
# Cargar el conjunto de datos MNIST
X, y = fetch_openml('mnist_784', version=1, return_X_y=True)
# Definir el Pipeline con memoria
pipeline = Pipeline([
('escalador', StandardScaler()),
('clasificador', SVC())
], memory='memory_cache')
# Definir el espacio de hiperparámetros a explorar
parametros = {
'clasificador__C': [0.1, 1, 10],
'clasificador__gamma': [1, 0.1, 0.01],
'clasificador__kernel': ['rbf', 'linear']
}
# Configurar GridSearchCV
grid_search = GridSearchCV(pipeline, parametros, cv=3)
# Ejecutar la búsqueda de hiperparámetros
grid_search.fit(X, y)
# Mostrar los mejores parámetros encontrados
print("Mejores parámetros:", grid_search.best_params_)
print("Mejor puntuación:", grid_search.best_score_)
En este ejemplo, el Pipeline consta de un escalador StandardScaler
y un clasificador SVM (SVC
). El diccionario parametros
especifica los hiperparámetros a optimizar, utilizando la notación nombre_etapa__nombre_parametro
. Al ajustar el Pipeline con GridSearchCV
, se exploran todas las combinaciones posibles de hiperparámetros definidos.
Es importante destacar que al usar Pipelines con GridSearchCV
, se evitan fugas de datos, ya que cada combinación de hiperparámetros se evalúa siguiendo el flujo completo del Pipeline, garantizando que las transformaciones se apliquen correctamente en cada pliegue de validación cruzada.
Si el espacio de hiperparámetros es muy grande y el tiempo de cómputo es una limitación, RandomizedSearchCV
ofrece una alternativa eficiente al realizar una búsqueda aleatoria:
from sklearn.model_selection import RandomizedSearchCV
from scipy.stats import uniform
# Definir el espacio de hiperparámetros con distribuciones
parametros_aleatorios = {
'clasificador__C': uniform(0.1, 10),
'clasificador__gamma': uniform(0.001, 1),
'clasificador__kernel': ['rbf']
}
# Configurar RandomizedSearchCV
random_search = RandomizedSearchCV(pipeline, parametros_aleatorios, n_iter=10, cv=3, random_state=42)
# Ejecutar la búsqueda aleatoria
random_search.fit(X, y)
# Mostrar los mejores parámetros encontrados
print("Mejores parámetros:", random_search.best_params_)
print("Mejor puntuación:", random_search.best_score_)
En este caso, RandomizedSearchCV
explora una muestra aleatoria de combinaciones de hiperparámetros, lo que puede ser más práctico en problemas con espacios de búsqueda grandes. Al igual que con GridSearchCV
, la integración con el Pipeline asegura que todas las etapas se consideren durante el proceso de optimización.
Además, es posible optimizar hiperparámetros de pasos intermedios del Pipeline. Por ejemplo, si queremos ajustar el número de características seleccionadas por un transformador:
from sklearn.feature_selection import SelectKBest, chi2
# Actualizar el Pipeline incluyendo SelectKBest
pipeline = Pipeline([
('escalador', StandardScaler()),
('seleccion', SelectKBest(score_func=chi2)),
('clasificador', SVC())
], memory='memory_cache')
# Definir el espacio de hiperparámetros incluyendo el transformador
parametros = {
'seleccion__k': [50, 100, 200],
'clasificador__C': [1, 10],
'clasificador__gamma': [0.01, 0.001],
'clasificador__kernel': ['rbf']
}
# Configurar GridSearchCV
grid_search = GridSearchCV(pipeline, parametros, cv=3)
# Ejecutar la búsqueda de hiperparámetros
grid_search.fit(X, y)
# Mostrar los mejores parámetros encontrados
print("Mejores parámetros:", grid_search.best_params_)
print("Mejor puntuación:", grid_search.best_score_)
Al incluir el hiperparámetro seleccion__k
, GridSearchCV
evalúa diferentes números de características seleccionadas por SelectKBest
. Esta capacidad de ajustar múltiples etapas simultáneamente es una de las ventajas clave de usar Pipelines con herramientas de búsqueda de hiperparámetros.
También se pueden definir pasos personalizados e incluirlos en el Pipeline. Por ejemplo, si necesitamos un transformador específico:
from sklearn.base import BaseEstimator, TransformerMixin
class TransformadorPersonalizado(BaseEstimator, TransformerMixin):
def fit(self, X, y=None):
# Ajustar el transformador
return self
def transform(self, X):
# Aplicar la transformación
return X
# Actualizar el Pipeline con el transformador personalizado
pipeline = Pipeline([
('transformador', TransformadorPersonalizado()),
('clasificador', SVC())
], memory='memory_cache')
# Definir los hiperparámetros del transformador
parametros = {
'clasificador__C': [1, 10],
'clasificador__gamma': [0.01, 0.001],
'clasificador__kernel': ['rbf']
}
# Configurar GridSearchCV
grid_search = GridSearchCV(pipeline, parametros, cv=3)
# Ejecutar la búsqueda de hiperparámetros
grid_search.fit(X, y)
# Mostrar los mejores parámetros encontrados
print("Mejores parámetros:", grid_search.best_params_)
print("Mejor puntuación:", grid_search.best_score_)
En este ejemplo, TransformadorPersonalizado
es un transformador definido por el usuario que se integra en el Pipeline. Al incluirlo, podemos ajustar tanto los hiperparámetros del transformador como los del clasificador.
Es fundamental gestionar adecuadamente el parámetro memory
en el Pipeline, especialmente cuando algunas etapas son costosas de computar. Al establecer memory='memory_cache'
, se habilita la memorización de las transformaciones, evitando cálculos redundantes y mejorando la eficiencia.
Por último, al trabajar con grandes conjuntos de datos, es recomendable utilizar validación cruzada más eficiente o limitar el número de combinaciones de hiperparámetros. Tanto GridSearchCV
como RandomizedSearchCV
permiten ajustar el parámetro cv
y otros parámetros de control para optimizar el proceso de búsqueda de hiperparámetros.
Integrar GridSearchCV
y RandomizedSearchCV
con Pipelines en Scikit-Learn es una práctica esencial para construir modelos robustos y optimizados, aprovechando al máximo las capacidades de estas herramientas en un flujo de trabajo coherente y reproducible.
Evitando el sobreajuste y fugas de datos
El sobreajuste ocurre cuando un modelo de aprendizaje automático se ajusta demasiado a los datos de entrenamiento, capturando incluso el ruido y las fluctuaciones aleatorias. Esto resulta en un rendimiento pobre en datos nuevos. Una causa común de sobreajuste es la fuga de datos, que sucede cuando información del conjunto de prueba se filtra en el conjunto de entrenamiento, dando lugar a estimaciones demasiado optimistas.
Para evitar fugas de datos, es esencial asegurar que todas las etapas de preprocesamiento se ajusten únicamente con los datos de entrenamiento en cada partición de validación cruzada. Los Pipelines de Scikit-Learn proporcionan una estructura que garantiza este aislamiento, manteniendo el proceso de transformación y modelado encapsulado.
Por ejemplo, consideremos un escenario donde imputamos valores faltantes y luego aplicamos una clasificación:
import numpy as np
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score
from sklearn.datasets import load_breast_cancer
# Cargar los datos
data = load_breast_cancer()
X, y = data.data, data.target
# Introducir valores faltantes artificialmente
rng = np.random.default_rng(seed=42) # Crear el generador con una semilla fija
X_missing = X.copy()
random_rows = rng.integers(0, X.shape[0], size=50)
random_cols = rng.integers(0, X.shape[1], size=50)
X_missing[random_rows, random_cols] = np.nan
# Crear el Pipeline con memoria
pipeline = Pipeline([
('imputacion', SimpleImputer(strategy='mean')),
('escalado', StandardScaler()),
('clasificacion', LogisticRegression())
], memory='cache_memory')
# Evaluar el modelo usando validación cruzada
puntuaciones = cross_val_score(pipeline, X_missing, y, cv=5)
print("Puntuaciones de validación cruzada:", puntuaciones)
print("Precisión media:", puntuaciones.mean())
En este ejemplo, se introducen valores faltantes en el conjunto de datos. Si realizáramos la imputación fuera del Pipeline, antes de la validación cruzada, podríamos introducir una fuga de datos, ya que la imputación estaría influenciada por todo el conjunto de datos, incluyendo información del conjunto de prueba. Al incluir la imputación dentro del Pipeline, garantizamos que en cada iteración de la validación cruzada, la estrategia de imputación se ajusta solo con los datos de entrenamiento, evitando fugas.
Otro aspecto crítico es evitar el sobreajuste al seleccionar características o ajustar hiperparámetros. Por ejemplo, si seleccionamos características utilizando todo el conjunto de datos antes de la validación cruzada, podemos introducir una fuga de datos. Lo correcto es incluir la selección de características dentro del Pipeline:
from sklearn.feature_selection import SelectKBest, f_classif
# Crear el Pipeline con selección de características
pipeline = Pipeline([
('imputacion', SimpleImputer(strategy='mean')),
('seleccion', SelectKBest(score_func=f_classif, k=10)),
('escalado', StandardScaler()),
('clasificacion', LogisticRegression())
], memory='cache_memory')
# Evaluar el modelo
puntuaciones = cross_val_score(pipeline, X_missing, y, cv=5)
print("Puntuaciones de validación cruzada:", puntuaciones)
print("Precisión media:", puntuaciones.mean())
Al incorporar SelectKBest
dentro del Pipeline, aseguramos que la selección de características se realiza solo con los datos de entrenamiento en cada pliegue, evitando el sobreajuste y manteniendo la integridad del proceso.
Además, al ajustar hiperparámetros con GridSearchCV
o RandomizedSearchCV
, es importante que la validación cruzada interna se gestione adecuadamente. Podemos combinar Pipelines con búsqueda de hiperparámetros y cuidar de evitar fugas:
from sklearn.model_selection import GridSearchCV
# Definir el espacio de hiperparámetros
parametros = {
'seleccion__k': [5, 10, 15],
'clasificacion__C': [0.1, 1, 10]
}
# Configurar GridSearchCV
grid_search = GridSearchCV(pipeline, parametros, cv=5)
# Ejecutar la búsqueda
grid_search.fit(X_missing, y)
# Mostrar los mejores parámetros
print("Mejores parámetros:", grid_search.best_params_)
print("Mejor puntuación:", grid_search.best_score_)
Al utilizar GridSearchCV
con el Pipeline, cada combinación de hiperparámetros se evalúa correctamente, evitando fugas de datos durante la selección de características y el entrenamiento del modelo.
Un error común es aplicar transformaciones que utilizan información futura. Por ejemplo, al escalar datos por características utilizando la media y desviación estándar del conjunto completo. Esto puede evitarse incluyendo el escalado dentro del Pipeline, garantizando que en cada pliegue, las estadísticas se calculen solo con los datos de entrenamiento.
Es fundamental tener en cuenta las etapas del Pipeline y cómo interactúan durante la validación cruzada. Mantener todas las transformaciones y ajustes dentro del Pipeline asegura que no haya interferencias entre el conjunto de entrenamiento y el de prueba, preservando la validez de las evaluaciones del modelo.
Otro ejemplo es al manejar variables categóricas. Si utilizamos OneHotEncoder
fuera del Pipeline, podemos introducir nuevas categorías presentes en el conjunto de prueba que no estaban en el de entrenamiento. Al incluir el codificador dentro del Pipeline, evitamos este problema:
from sklearn.preprocessing import OneHotEncoder
from sklearn.compose import ColumnTransformer
import pandas as pd
# Crear un generador de números aleatorios moderno
rng = np.random.default_rng(seed=42)
# Supongamos que tenemos datos en un DataFrame
df = pd.DataFrame({
'numerico': rng.standard_normal(100), # Generar datos numéricos
'categorico': rng.choice(['A', 'B', 'C'], size=100), # Generar datos categóricos
'objetivo': rng.choice([0, 1], size=100) # Generar datos de objetivo
})
X = df[['numerico', 'categorico']]
y = df['objetivo']
# Definir el preprocesador
preprocesador = ColumnTransformer(transformers=[
('num', StandardScaler(), ['numerico']),
('cat', OneHotEncoder(handle_unknown='ignore'), ['categorico'])
])
# Crear el Pipeline completo
pipeline = Pipeline([
('preprocesado', preprocesador),
('clasificacion', LogisticRegression())
], memory='cache_memory')
# Evaluar el modelo
puntuaciones = cross_val_score(pipeline, X, y, cv=5)
print("Puntuaciones de validación cruzada:", puntuaciones)
print("Precisión media:", puntuaciones.mean())
Al usar handle_unknown='ignore'
en OneHotEncoder
y al incluirlo en el Pipeline, garantizamos que el modelo pueda manejar categorías desconocidas en el conjunto de prueba sin causar errores o fugas de datos.
En resumen, para evitar sobreajuste y fugas de datos, es crucial encapsular todas las etapas de preprocesamiento, selección de características y modelado dentro de un Pipeline. Esto asegura que en cada iteración de validación cruzada o durante el ajuste de hiperparámetros, no se filtrará información del conjunto de prueba al conjunto de entrenamiento, manteniendo la integridad y la generalización del modelo.
Validación cruzada anidada con Pipelines
La validación cruzada anidada es una técnica esencial para obtener estimaciones imparciales del rendimiento de un modelo cuando se realiza ajuste de hiperparámetros. Al combinar Pipelines con validación cruzada anidada en Scikit-Learn, se integran todas las etapas del preprocesamiento y modelado, garantizando una evaluación robusta y evitando el sobreajuste.
La necesidad de este enfoque surge porque al optimizar hiperparámetros utilizando validación cruzada, se corre el riesgo de obtener estimaciones optimistas del rendimiento. La validación cruzada anidada resuelve este problema introduciendo dos bucles: un bucle externo para evaluar el modelo y un bucle interno para seleccionar los hiperparámetros óptimos.
A continuación, se muestra un ejemplo práctico de cómo implementar la validación cruzada anidada con Pipelines en Scikit-Learn. Utilizaremos el conjunto de datos de dígitos escritos a mano y un clasificador SVM.
from sklearn.datasets import load_digits
from sklearn.model_selection import GridSearchCV, cross_val_score, KFold
from sklearn.svm import SVC
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
import numpy as np
# Cargar los datos
X, y = load_digits(return_X_y=True)
# Definir el Pipeline con memoria
pipeline = Pipeline([
('escalado', StandardScaler()),
('clasificador', SVC())
], memory='memoria_cache')
# Definir el espacio de hiperparámetros
parametros = {
'clasificador__C': [0.1, 1, 10],
'clasificador__gamma': [0.01, 0.001],
'clasificador__kernel': ['rbf', 'linear']
}
# Configurar GridSearchCV para la validación interna
busqueda = GridSearchCV(pipeline, parametros, cv=5)
# Definir la validación cruzada externa
cv_externo = KFold(n_splits=5, shuffle=True, random_state=42)
# Realizar la validación cruzada anidada
puntuaciones = cross_val_score(busqueda, X, y, cv=cv_externo)
print("Puntuaciones de validación cruzada anidada:", puntuaciones)
print("Precisión media:", np.mean(puntuaciones))
En este ejemplo, el Pipeline incluye un escalado de los datos con StandardScaler
y un clasificador SVM. La búsqueda de los mejores hiperparámetros se realiza con GridSearchCV
dentro del bucle interno de validación cruzada. El bucle externo, definido por KFold
, se utiliza para evaluar el rendimiento del modelo con los hiperparámetros óptimos en datos no vistos.
La función cross_val_score
ejecuta la validación cruzada anidada, asegurando que en cada partición externa, el modelo se entrene y valide utilizando exclusivamente los datos de entrenamiento, evitando cualquier fuga de datos. Esto proporciona una estimación más realista y generalizable del rendimiento del modelo.
Si el espacio de hiperparámetros es amplio y se desea reducir el tiempo de cómputo, es posible utilizar RandomizedSearchCV
:
from sklearn.model_selection import RandomizedSearchCV
from scipy.stats import uniform
# Definir distribuciones de hiperparámetros
parametros_distribucion = {
'clasificador__C': uniform(0.1, 10),
'clasificador__gamma': uniform(0.001, 0.1),
'clasificador__kernel': ['rbf']
}
# Configurar RandomizedSearchCV
busqueda_aleatoria = RandomizedSearchCV(pipeline, parametros_distribucion, n_iter=10, cv=5, random_state=42)
# Realizar la validación cruzada anidada
puntuaciones = cross_val_score(busqueda_aleatoria, X, y, cv=cv_externo)
print("Puntuaciones de validación cruzada anidada:", puntuaciones)
print("Precisión media:", np.mean(puntuaciones))
Con RandomizedSearchCV
, se exploran aleatoriamente combinaciones de hiperparámetros, lo que puede ser más eficiente computacionalmente mientras se mantiene la efectividad en la búsqueda de parámetros óptimos.
También es posible incluir etapas adicionales en el Pipeline, como la selección de características, y ajustar sus hiperparámetros dentro de la validación cruzada anidada:
from sklearn.feature_selection import SelectKBest, chi2
from sklearn.preprocessing import MinMaxScaler
# Actualizar el Pipeline con selección de características
pipeline = Pipeline([
('escalado', MinMaxScaler()),
('seleccion', SelectKBest(score_func=chi2)),
('clasificador', SVC())
], memory='memoria_cache')
# Definir el espacio de hiperparámetros incluyendo 'k'
parametros = {
'seleccion__k': [20, 30, 40],
'clasificador__C': [0.1, 1, 10],
'clasificador__gamma': [0.01, 0.001],
'clasificador__kernel': ['rbf']
}
# Configurar GridSearchCV
busqueda = GridSearchCV(pipeline, parametros, cv=5)
# Realizar la validación cruzada anidada
puntuaciones = cross_val_score(busqueda, X, y, cv=cv_externo)
print("Puntuaciones de validación cruzada anidada:", puntuaciones)
print("Precisión media:", np.mean(puntuaciones))
En este caso, SelectKBest
se utiliza para seleccionar las mejores características basadas en la prueba chi-cuadrado, y el valor de k
se optimiza durante el ajuste de hiperparámetros. La validación cruzada anidada garantiza que tanto la selección de características como el ajuste del modelo se realicen de manera imparcial, utilizando únicamente los datos de entrenamiento en cada pliegue externo.
La combinación de Pipelines y validación cruzada anidada es especialmente útil para prevenir el sobreajuste y obtener estimaciones fiables del rendimiento del modelo. Al encapsular todas las etapas del preprocesamiento y modelado dentro del Pipeline, se asegura una separación estricta entre los datos de entrenamiento y prueba, evitando fugas de datos y mejorando la generalización del modelo.
Es importante tener en cuenta que la validación cruzada anidada puede ser computacionalmente costosa debido a la naturaleza doblemente iterativa del proceso. Sin embargo, las estimaciones de rendimiento obtenidas son más realistas y ayudan a seleccionar modelos que realmente funcionarán bien en datos nuevos.
Al aplicar estas técnicas con Scikit-Learn en Python, aprovechamos las funcionalidades más recientes y eficientes, garantizando que nuestro flujo de trabajo esté actualizado y sea robusto.
Ejemplo práctico de ajuste de hiperparámetros
En este ejemplo práctico, se demostrará el proceso de ajuste de hiperparámetros utilizando Pipelines y GridSearchCV
en Scikit-Learn para construir un modelo de clasificación. El objetivo es predecir la presencia de cáncer de mama utilizando el conjunto de datos Breast Cancer Wisconsin.
Primero, se importan las librerías necesarias y se carga el conjunto de datos:
from sklearn.datasets import load_breast_cancer
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.svm import SVC
from sklearn.model_selection import GridSearchCV, StratifiedKFold, train_test_split
from sklearn.metrics import classification_report
# Cargar los datos
data = load_breast_cancer()
X, y = data.data, data.target
A continuación, se crea un Pipeline que incluye el escalado de características, reducción de dimensionalidad con PCA y un clasificador SVM:
# Crear el Pipeline con memoria
pipeline = Pipeline([
('escalado', StandardScaler()),
('pca', PCA()),
('clasificador', SVC())
], memory='cache_dir')
El parámetro memory='cache_dir'
permite almacenar en caché los transformadores para mejorar la eficiencia en cálculos repetitivos.
Se define el espacio de hiperparámetros para realizar la búsqueda:
# Definir el espacio de hiperparámetros
parametros = {
'pca__n_components': [5, 10, 15],
'clasificador__kernel': ['rbf', 'linear'],
'clasificador__C': [0.1, 1, 10],
'clasificador__gamma': [0.001, 0.01, 0.1]
}
Este espacio incluye diferentes números de componentes principales para el PCA y varios valores para los parámetros kernel
, C
y gamma
del SVM.
Se configura la validación cruzada y se crea GridSearchCV
:
# Definir la estrategia de validación cruzada
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
# Configurar GridSearchCV
grid_search = GridSearchCV(pipeline, parametros, cv=cv, scoring='accuracy', n_jobs=-1)
El uso de StratifiedKFold
garantiza que la proporción de clases se mantenga en cada partición, lo cual es crucial para problemas de clasificación.
Se ejecuta la búsqueda de hiperparámetros:
# Ejecutar la búsqueda de hiperparámetros
grid_search.fit(X, y)
# Mostrar los mejores parámetros y precisión obtenida
print("Mejores parámetros:", grid_search.best_params_)
print("Mejor precisión en validación cruzada:", grid_search.best_score_)
Después de encontrar los mejores parámetros, se evalúa el rendimiento del modelo en un conjunto de prueba independiente:
# Dividir los datos en entrenamiento y prueba
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, stratify=y, random_state=42)
# Entrenar el mejor modelo con los datos de entrenamiento
mejor_modelo = grid_search.best_estimator_
mejor_modelo.fit(X_train, y_train)
# Predecir en el conjunto de prueba
y_pred = mejor_modelo.predict(X_test)
# Generar el informe de clasificación
print(classification_report(y_test, y_pred))
El informe de clasificación proporciona métricas detalladas como precisión, exhaustividad y puntaje F1 para cada clase, permitiendo una comprensión profunda del rendimiento del modelo.
Si se desea reducir el tiempo de cómputo explorando aleatoriamente el espacio de hiperparámetros, se puede utilizar RandomizedSearchCV
:
from sklearn.model_selection import RandomizedSearchCV
from scipy.stats import randint, uniform
# Definir distribuciones de hiperparámetros
param_dist = {
'pca__n_components': randint(5, 15),
'clasificador__kernel': ['rbf', 'linear'],
'clasificador__C': uniform(0.1, 10),
'clasificador__gamma': uniform(0.001, 0.1)
}
# Configurar RandomizedSearchCV
random_search = RandomizedSearchCV(pipeline, param_distributions=param_dist, n_iter=20, cv=cv, scoring='accuracy', n_jobs=-1, random_state=42)
# Ejecutar la búsqueda aleatoria
random_search.fit(X, y)
# Mostrar los mejores parámetros y precisión obtenida
print("Mejores parámetros (RandomizedSearchCV):", random_search.best_params_)
print("Mejor precisión en validación cruzada:", random_search.best_score_)
Esta técnica permite una exploración más amplia del espacio de hiperparámetros con menos iteraciones, siendo más eficiente en términos computacionales.
Para visualizar el impacto de los hiperparámetros en el rendimiento, se pueden extraer y analizar los resultados de la búsqueda:
import pandas as pd
import matplotlib.pyplot as plt
# Convertir los resultados en un DataFrame
resultados = pd.DataFrame(grid_search.cv_results_)
# Mostrar los 5 mejores resultados
print(resultados.nlargest(5, 'mean_test_score'))
Este análisis ayuda a comprender cómo afectan los diferentes hiperparámetros al modelo y a tomar decisiones informadas sobre su ajuste.
Finalmente, se puede guardar el modelo entrenado para uso futuro:
import joblib
# Guardar el mejor modelo
joblib.dump(mejor_modelo, 'mejor_modelo.pkl')
# Cargar el modelo guardado
modelo_cargado = joblib.load('mejor_modelo.pkl')
El uso de joblib
permite la persistencia del Pipeline completo, incluyendo todos los pasos de preprocesamiento y el clasificador optimizado.
Este ejemplo práctico demuestra cómo integrar todas las etapas del preprocesamiento, búsqueda de hiperparámetros y evaluación en un Pipeline, promoviendo buenas prácticas y garantizando la reproducibilidad del modelo en proyectos de aprendizaje automático.
Ejercicios de esta lección Pipelines y Validación Cruzada
Evalúa tus conocimientos de esta lección Pipelines y Validación Cruzada con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.
Todas las lecciones de ScikitLearn
Accede a todas las lecciones de ScikitLearn y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.
Aprendizaje Automático
Introducción Y Entorno
Introducción E Instalación
Introducción Y Entorno
Introducción Al Preprocesamiento De Datos
Preprocesamiento De Datos
Identificación Y Tratamiento De Valores Faltantes
Preprocesamiento De Datos
Escalado De Datos
Preprocesamiento De Datos
Normalización De Datos
Preprocesamiento De Datos
Codificación De Variables Categóricas
Preprocesamiento De Datos
Ingeniería De Características
Preprocesamiento De Datos
Selección De Características
Preprocesamiento De Datos
Extracción De Características
Preprocesamiento De Datos
Particionamiento De Datos
Preprocesamiento De Datos
Preprocesamiento De Datos Desbalanceados
Preprocesamiento De Datos
Introducción A La Regresión
Regresión
Regresión Lineal
Regresión
Regresión Knn Kneighborsregressor
Regresión
Regresión Svm Con Svr
Regresión
Regresión Con Árboles Decisiontreeregressor
Regresión
Regresión Con Algoritmos De Conjunto
Regresión
Introducción A La Clasificación
Clasificación
Clasificación Con Regresión Logística
Clasificación
Clasificación Knn Kneighborsclassifier
Clasificación
Clasificación Svm Con Svc
Clasificación
Clasificación Con Árboles Decisiontreeclassifier
Clasificación
Clasificación Con Algoritmos De Conjunto
Clasificación
Reducción De La Dimensionalidad Con Pca
Aprendizaje No Supervisado
Clustering Con Kmeans
Aprendizaje No Supervisado
Clustering Jerárquico
Aprendizaje No Supervisado
Clustering De Densidad Con Dbscan
Aprendizaje No Supervisado
Preprocesamiento De Textos Para Nlp
Nlp
Representación De Texto Y Extracción De Características
Nlp
Clasificación De Texto Con Scikit Learn
Nlp
Análisis De Sentimiento
Nlp
Técnicas Avanzadas De Extracción De Características
Nlp
Introducción Al Análisis De Series Temporales
Series Temporales
Preprocesamiento De Datos De Series Temporales
Series Temporales
Ingeniería De Características Para Series Temporales
Series Temporales
Transformación Y Escalado De Series Temporales
Series Temporales
Validación Y Evaluación De Modelos En Series Temporales
Series Temporales
Validación Y Evaluación De Modelos
Validación De Modelos
Técnicas De Validación Cruzada
Validación De Modelos
Métricas De Regresión
Validación De Modelos
Métricas De Clasificación
Validación De Modelos
Ajuste De Hiperparámetros
Validación De Modelos
Introducción A Pipelines
Pipelines Y Despliegue
Creación De Pipelines Básicos
Pipelines Y Despliegue
Preprocesamiento De Datos Con Pipelines
Pipelines Y Despliegue
Pipelines Y Validación Cruzada
Pipelines Y Despliegue
Pipelines Con Columntransformer
Pipelines Y Despliegue
Exportar E Importar Pipelines
Pipelines Y Despliegue
Objetivos de aprendizaje de esta lección
- Aprender a integrar Pipelines con
cross_val_score
. - Validar modelos sin fugas de datos.
- Dominar la configuración de
StratifiedKFold
. - Automatizar el escalado y procesamiento de características.
- Aplicar técnicas de selección de características en Pipelines.