ScikitLearn
Tutorial ScikitLearn: Preprocesamiento de datos con pipelines
Scikit-Learn: Aprende a integrar escalado y normalización en un pipeline. Optimización del preprocesamiento de datos para mejorar la precisión del modelo.
Aprende ScikitLearn GRATIS y certifícateEscalado y normalización de características en pipeline
El escalado y la normalización de características son pasos fundamentales en el preprocesamiento de datos para muchos algoritmos de aprendizaje automático. Integrar estas transformaciones dentro de un pipeline de Scikit-Learn permite automatizar y encadenar procesos, garantizando que todas las etapas se apliquen de manera consistente durante el entrenamiento y la predicción.
Para ilustrar cómo incorporar el escalado y la normalización en un pipeline, consideremos un ejemplo práctico. Supongamos que tenemos un conjunto de datos y queremos aplicar una regresión logística. Primero, importamos las bibliotecas necesarias:
import numpy as np
import pandas as pd
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler, MinMaxScaler, Normalizer
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import make_classification
from joblib import Memory
A continuación, generamos datos sintéticos:
# Habilitar caching
memory = Memory(location='cachedir', verbose=0)
# Generar datos sintéticos
X, y = make_classification(n_samples=1000, n_features=20,
n_informative=15, n_redundant=5,
random_state=42)
Crearemos diferentes pipelines que incluyen distintas técnicas de escalado.
El StandardScaler estandariza las características restando la media y dividiendo entre la desviación estándar:
pipeline_std = Pipeline(
[
("scaler", StandardScaler()),
("classifier", LogisticRegression(
penalty="l2",
solver="liblinear",
random_state=42,
max_iter=100
)),
],
memory=memory
)
El MinMaxScaler escala las características al rango [0, 1]:
pipeline_minmax = Pipeline(
[
("scaler", MinMaxScaler()),
("classifier", LogisticRegression(
penalty="l2",
solver="liblinear",
random_state=42,
max_iter=100
)),
],
memory=memory
)
El Normalizer normaliza cada muestra individual para tener una norma unitaria:
pipeline_norm = Pipeline(
[
("normalizer", Normalizer()),
("classifier", LogisticRegression(
penalty="l2",
solver="liblinear",
random_state=42,
max_iter=100
)),
],
memory=memory
)
Procedemos a entrenar y evaluar los pipelines utilizando validación cruzada:
from sklearn.model_selection import cross_val_score
scores_std = cross_val_score(pipeline_std, X, y, cv=5)
print("Precisión con StandardScaler:", scores_std.mean())
scores_minmax = cross_val_score(pipeline_minmax, X, y, cv=5)
print("Precisión con MinMaxScaler:", scores_minmax.mean())
scores_norm = cross_val_score(pipeline_norm, X, y, cv=5)
print("Precisión con Normalizer:", scores_norm.mean())
Es importante comparar los resultados obtenidos con cada método de escalado para determinar cuál mejora el rendimiento del modelo. La elección del escalador puede afectar significativamente la precisión de las predicciones.
Incorporar el escalado y la normalización dentro de un pipeline no solo simplifica el código sino que también garantiza que las transformaciones se apliquen correctamente tanto en el conjunto de entrenamiento como en los datos nuevos. Las buenas prácticas recomiendan siempre incluir los pasos de preprocesamiento en los pipelines para evitar inconsistencias y facilitar el mantenimiento del código.
Manejo de valores faltantes en pipeline
Los valores faltantes en los conjuntos de datos pueden afectar negativamente el rendimiento de los algoritmos de aprendizaje automático. Integrar el manejo de estos valores dentro de un pipeline garantiza que el procesamiento sea consistente tanto durante el entrenamiento como en la predicción.
Para abordar los valores faltantes, Scikit-Learn ofrece transformadores como SimpleImputer y KNNImputer, que pueden incorporarse fácilmente en un pipeline. Supongamos que tenemos un conjunto de datos con características numéricas y categóricas, y algunos de sus valores están ausentes. Importamos las bibliotecas necesarias:
import numpy as np
import pandas as pd
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer, KNNImputer
from sklearn.preprocessing import OneHotEncoder
from sklearn.compose import ColumnTransformer
from sklearn.ensemble import RandomForestClassifier
from joblib import Memory
Creamos un conjunto de datos de ejemplo:
# Habilitar caching
memory = Memory(location='cachedir', verbose=0)
# Crear datos de ejemplo
data = {'edad': [25, np.nan, 35, 45, np.nan],
'ingresos': [50000, 60000, np.nan, 80000, 90000],
'género': ['M', 'F', np.nan, 'F', 'M'],
'compra': [0, 1, 0, 1, 1]}
df = pd.DataFrame(data)
X = df.drop('compra', axis=1)
y = df['compra']
Identificamos las columnas numéricas y categóricas:
# Identificar columnas numéricas y categóricas
columnas_numericas = ['edad', 'ingresos']
columnas_categoricas = ['género']
Definimos transformadores para manejar los valores faltantes. Para las columnas numéricas utilizaremos SimpleImputer con estrategia de imputación por la media, y para las categóricas, imputación con el valor más frecuente:
# Transformador para columnas numéricas
transformador_numerico = Pipeline(steps=[
('imputar', SimpleImputer(strategy='mean'))
], memory=memory)
# Transformador para columnas categóricas
transformador_categorico = Pipeline(steps=[
('imputar', SimpleImputer(strategy='most_frequent')),
('codificar', OneHotEncoder(handle_unknown='ignore'))
], memory=memory)
Combinamos los transformadores utilizando ColumnTransformer:
preprocesamiento = ColumnTransformer(transformers=[
('numerico', transformador_numerico, columnas_numericas),
('categorico', transformador_categorico, columnas_categoricas)
])
Creamos el pipeline completo agregando un clasificador al final. Utilizaremos un RandomForestClassifier:
pipeline = Pipeline(steps=[
('preprocesamiento', preprocesamiento),
('clasificador', RandomForestClassifier())
], memory=memory)
Entrenamos el pipeline con los datos:
pipeline.fit(X, y)
Podemos realizar predicciones sobre nuevos datos, asegurándonos de que el preprocesamiento se aplique de manera consistente:
# Nuevos datos con valores faltantes
nuevos_datos = {'edad': [30, np.nan],
'ingresos': [70000, 85000],
'género': ['F', np.nan]}
df_nuevos = pd.DataFrame(nuevos_datos)
predicciones = pipeline.predict(df_nuevos)
print("Predicciones:", predicciones)
Es importante destacar que manejar los valores faltantes dentro del pipeline garantiza que cualquier transformación se aplique de manera idéntica durante el entrenamiento y la inferencia. Las mejores prácticas sugieren integrar todas las etapas de preprocesamiento en el pipeline para evitar inconsistencias y simplificar el proceso de despliegue.
Para conjuntos de datos más grandes o cuando los valores faltantes tienen patrones complejos, puede ser útil utilizar imputadores más sofisticados como KNNImputer. Por ejemplo:
# Usando KNNImputer para columnas numéricas
transformador_numerico_knn = Pipeline(steps=[
('imputar', KNNImputer(n_neighbors=3))
])
preprocesamiento_knn = ColumnTransformer(transformers=[
('numerico', transformador_numerico_knn, columnas_numericas),
('categorico', transformador_categorico, columnas_categoricas)
])
pipeline_knn = Pipeline(steps=[
('preprocesamiento', preprocesamiento_knn),
('clasificador', RandomForestClassifier())
], memory=memory)
De esta manera, el KNNImputer utilizará los valores de los vecinos más cercanos para imputar los datos faltantes, lo que puede mejorar la precisión del modelo en ciertos casos.
Integrar el manejo de valores faltantes en los pipelines no solo mejora la robustez del modelo, sino que también facilita su uso en producción, asegurando que todas las transformaciones estén encapsuladas y sean reproducibles.
Codificación de variables categóricas en pipeline
La codificación de variables categóricas es un paso crucial en el preprocesamiento de datos para muchos algoritmos de aprendizaje automático, ya que estos generalmente requieren datos numéricos. Integrar esta codificación dentro de un pipeline en Scikit-Learn garantiza que el proceso sea consistente durante el entrenamiento y la predicción.
Para ilustrar cómo incorporar la codificación de variables categóricas en un pipeline, consideremos un ejemplo práctico. Supongamos que tenemos un conjunto de datos que incluye tanto características numéricas como categóricas y deseamos aplicar una regresión logística. Primero, importamos las bibliotecas necesarias:
import numpy as np
import pandas as pd
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sklearn.compose import ColumnTransformer
from sklearn.linear_model import LogisticRegression
from joblib import Memory
Creamos un conjunto de datos de ejemplo:
# Habilitar caching
memory = Memory(location='cachedir', verbose=0)
# Crear datos de ejemplo
data = {
'edad': [25, 32, 47, 51, 62],
'ingresos': [50000, 60000, 80000, 72000, 90000],
'género': ['M', 'F', 'F', 'M', 'F'],
'estado_civil': ['Soltero', 'Casado', 'Casado', 'Soltero', 'Viudo'],
'compra': [0, 1, 0, 1, 1]
}
df = pd.DataFrame(data)
X = df.drop('compra', axis=1)
y = df['compra']
Identificamos las columnas numéricas y categóricas:
# Identificar columnas numéricas y categóricas
columnas_numericas = ['edad', 'ingresos']
columnas_categoricas = ['género', 'estado_civil']
Definimos transformadores para cada tipo de dato. Para las columnas numéricas, utilizaremos StandardScaler para estandarizar las características. Para las columnas categóricas, emplearemos OneHotEncoder para convertir las categorías en variables binarias:
# Transformador para columnas numéricas
transformador_numerico = Pipeline(steps=[
('escalar', StandardScaler())
], memory=memory)
# Transformador para columnas categóricas
transformador_categorico = Pipeline(steps=[
('codificar', OneHotEncoder(handle_unknown='ignore'))
], memory=memory)
Combinamos los transformadores utilizando ColumnTransformer:
preprocesamiento = ColumnTransformer(transformers=[
('numerico', transformador_numerico, columnas_numericas),
('categorico', transformador_categorico, columnas_categoricas)
])
Creamos el pipeline completo agregando el modelo de regresión logística al final:
pipeline = Pipeline(steps=[
('preprocesamiento', preprocesamiento),
('clasificador', LogisticRegression())
], memory=memory)
Entrenamos el pipeline con los datos:
pipeline.fit(X, y)
Podemos realizar predicciones sobre nuevos datos, asegurándonos de que el preprocesamiento se aplique de manera consistente:
# Nuevos datos para predicción
nuevos_datos = {
'edad': [29, 55],
'ingresos': [58000, 85000],
'género': ['F', 'M'],
'estado_civil': ['Soltero', 'Casado']
}
df_nuevos = pd.DataFrame(nuevos_datos)
predicciones = pipeline.predict(df_nuevos)
print("Predicciones:", predicciones)
El uso de OneHotEncoder convierte las variables categóricas en una representación numérica adecuada para el modelo. Integrar este proceso dentro del pipeline garantiza una transformación coherente tanto en el entrenamiento como en la inferencia.
Si preferimos utilizar una codificación ordinal, podemos emplear OrdinalEncoder. Sin embargo, es importante tener en cuenta que OrdinalEncoder asigna un valor entero a cada categoría según su orden, lo que implica una relación ordinal que puede no existir:
from sklearn.preprocessing import OrdinalEncoder
# Transformador categórico con OrdinalEncoder
transformador_categorico_ordinal = Pipeline(steps=[
('codificar', OrdinalEncoder())
], memory=memory)
preprocesamiento_ordinal = ColumnTransformer(transformers=[
('numerico', transformador_numerico, columnas_numericas),
('categorico', transformador_categorico_ordinal, columnas_categoricas)
])
pipeline_ordinal = Pipeline(steps=[
('preprocesamiento', preprocesamiento_ordinal),
('clasificador', LogisticRegression())
], memory=memory)
pipeline_ordinal.fit(X, y)
En algunos casos, puede ser necesario aplicar diferentes estrategias de codificación a distintas columnas categóricas. Por ejemplo, podríamos codificar 'género' con OneHotEncoder y 'estado_civil' con OrdinalEncoder:
# Aplicar diferentes codificadores a columnas categóricas
preprocesamiento_mixto = ColumnTransformer(transformers=[
('numerico', transformador_numerico, columnas_numericas),
('onehot', OneHotEncoder(handle_unknown='ignore'), ['género']),
('ordinal', OrdinalEncoder(), ['estado_civil'])
])
pipeline_mixto = Pipeline(steps=[
('preprocesamiento', preprocesamiento_mixto),
('clasificador', LogisticRegression())
], memory=memory)
pipeline_mixto.fit(X, y)
De esta manera, adaptamos la codificación a las características específicas de cada variable, lo que puede mejorar la eficacia del modelo.
Integrar la codificación de variables categóricas dentro del pipeline no solo simplifica el código, sino que también garantiza que todas las transformaciones se apliquen correctamente tanto en el conjunto de entrenamiento como en los nuevos datos. Las buenas prácticas recomiendan incluir todos los pasos de preprocesamiento y modelado en un pipeline para asegurar la reproducibilidad y facilitar el mantenimiento del código.
Además, si trabajamos con datos que pueden contener categorías desconocidas en el conjunto de validación o prueba, es fundamental configurar el parámetro handle_unknown='ignore' en OneHotEncoder. Esto evita errores durante la predicción cuando se encuentran categorías nuevas que no estuvieron presentes durante el entrenamiento.
Es importante prestar atención al orden de las transformaciones y asegurarse de que todas las variables estén correctamente procesadas antes de ser enviadas al modelo. La implementación cuidadosa de la codificación de variables categóricas en el pipeline contribuye significativamente a la robustez y precisión del modelo.
Selección de características dentro del Pipeline
La selección de características es un paso esencial en el preprocesamiento de datos que busca reducir la dimensionalidad, eliminar ruido y mejorar el rendimiento de los modelos. Integrar la selección de características dentro de un pipeline en Scikit-Learn permite automatizar y encadenar este proceso con otras transformaciones, asegurando coherencia y eficiencia durante el entrenamiento y la predicción.
Scikit-Learn ofrece diversas técnicas de selección de características que pueden incorporarse fácilmente en un pipeline. A continuación, exploraremos cómo integrar estas técnicas mediante ejemplos prácticos.
Para empezar, creamos un conjunto de datos de clasificación utilizando make_classification
:
import numpy as np
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
# Crear datos sintéticos
X, y = make_classification(
n_samples=1000,
n_features=20,
n_informative=5,
n_redundant=2,
random_state=42
)
# Dividir datos en entrenamiento y prueba
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
Creamos un pipeline que incluye escalado, selección de características y el modelo:
from sklearn.pipeline import Pipeline
from sklearn.feature_selection import SelectKBest, chi2
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import MinMaxScaler
from joblib import Memory
# Configurar memoria para caching
memory = Memory(location='cachedir', verbose=0)
# Construir el pipeline
pipeline = Pipeline([
('escalar', MinMaxScaler()), # Escalado para garantizar valores no negativos
('seleccionar', SelectKBest(score_func=chi2, k=10)), # Selección de características
('clasificador', LogisticRegression(random_state=42)) # Modelo
], memory=memory)
# Entrenar el pipeline
pipeline.fit(X_train, y_train)
# Evaluar el pipeline
precision = pipeline.score(X_test, y_test)
print("Precisión del modelo:", precision)
En este ejemplo, SelectKBest selecciona las 10 características más relevantes según la prueba chi-cuadrado. Integrar esta selección dentro del pipeline asegura que solo se utilicen las características significativas para el modelo, mejorando su eficacia.
También podemos utilizar métodos de selección basados en modelos. Por ejemplo, empleando SelectFromModel con un RandomForestClassifier:
from sklearn.ensemble import RandomForestClassifier
from sklearn.feature_selection import SelectFromModel
from sklearn.preprocessing import StandardScaler
pipeline_modelo = Pipeline([
('escalar', StandardScaler()),
('seleccionar', SelectFromModel(RandomForestClassifier(n_estimators=100, random_state=42))),
('clasificador', LogisticRegression(random_state=42))
], memory=memory)
pipeline_modelo.fit(X_train, y_train)
# Ver las características seleccionadas
selector = pipeline_modelo.named_steps['seleccionar']
print("Características seleccionadas:", selector.get_support())
Con SelectFromModel, el modelo base (en este caso, un bosque aleatorio) determina la importancia de las características, y se seleccionan aquellas con mayor relevancia. Esta técnica es útil cuando se desea incorporar conocimientos de modelos más complejos en la selección de variables.
Otra opción es utilizar Recursive Feature Elimination (RFE), que elimina recursivamente las características menos importantes:
from sklearn.feature_selection import RFE
pipeline_rfe = Pipeline([
('escalar', StandardScaler()),
('seleccionar', RFE(estimator=LogisticRegression(random_state=42), n_features_to_select=10)),
('clasificador', LogisticRegression(random_state=42))
], memory=memory)
pipeline_rfe.fit(X_train, y_train)
La eliminación recursiva de características es especialmente útil cuando se quiere identificar un subconjunto óptimo de características que maximice el rendimiento del modelo.
Hablando de ajuste de hiperparámetros, es común integrarlo con herramientas como GridSearchCV para encontrar los valores óptimos. Por ejemplo:
from sklearn.model_selection import GridSearchCV
parametros = {
'seleccionar__n_features_to_select': [5, 10, 15],
'clasificador__C': [0.1, 1, 10]
}
grid = GridSearchCV(pipeline_rfe, parametros, cv=5)
grid.fit(X_train, y_train)
print("Mejores parámetros:", grid.best_params_)
print("Mejor score:", grid.best_score_)
Al integrar la selección de características en el pipeline y combinarla con la búsqueda de hiperparámetros, garantizamos un enfoque sistemático y reproducible para optimizar el modelo.
Es importante destacar que integrar la selección de características dentro del pipeline previene fugas de datos, ya que todas las transformaciones se ajustan únicamente en los datos de entrenamiento y luego se aplican al conjunto de prueba.
Además de los métodos mencionados, Scikit-Learn ofrece otros transformadores que pueden integrarse en el pipeline, como VarianceThreshold para eliminar características con baja varianza o SelectPercentile para seleccionar un porcentaje de características según una prueba estadística.
Por ejemplo, utilizando VarianceThreshold:
from sklearn.feature_selection import VarianceThreshold
pipeline_varianza = Pipeline([
('escalar', StandardScaler()),
('seleccionar', VarianceThreshold(threshold=0.1)),
('clasificador', LogisticRegression(random_state=42))
], memory=memory)
pipeline_varianza.fit(X_train, y_train)
Este transformador elimina características cuya varianza no supera el umbral especificado, lo que puede ser útil para eliminar características constantes o casi constantes.
Integrar la selección de características dentro del pipeline no solo simplifica el código sino que también mejora la robustez y mantenibilidad del modelo. Al encadenar los pasos de preprocesamiento y modelado, nos aseguramos de que todas las transformaciones se apliquen de manera consistente, tanto en el entrenamiento como en la predicción sobre nuevos datos.
En resumen, la selección de características es un componente fundamental en el desarrollo de modelos de aprendizaje automático, y su integración dentro de los pipelines de Scikit-Learn es una práctica recomendada que aporta claridad y eficiencia al proceso de modelado.
Implementación de transformaciones personalizadas
En ocasiones, las transformaciones estándar que ofrece Scikit-Learn no son suficientes para satisfacer necesidades específicas de preprocesamiento. En estos casos, es útil implementar transformaciones personalizadas que se adapten a las particularidades de los datos. Integrar estas transformaciones en un pipeline permite encadenar procesos y garantizar que todas las etapas se apliquen de manera consistente durante el entrenamiento y la predicción.
Para crear un transformador personalizado en Scikit-Learn, se define una clase que hereda de BaseEstimator
y TransformerMixin
y se implementan los métodos fit
y transform
. A continuación, se muestra un ejemplo práctico de cómo hacerlo.
Supongamos que queremos crear una transformación que añada una nueva característica calculando el número de vocales en una columna de texto. Primero, importamos las bibliotecas necesarias:
import numpy as np
import pandas as pd
from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from joblib import Memory
Definimos la clase del transformador personalizado:
class ContadorDeVocalesTransformer(BaseEstimator, TransformerMixin):
def __init__(self, columna):
self.columna = columna
def fit(self, X, y=None):
return self # No requiere ajuste
def transform(self, X):
X = X.copy()
X['numero_vocales'] = X[self.columna].apply(self._contar_vocales)
return X
def _contar_vocales(self, texto):
texto = str(texto).lower()
return sum(1 for char in texto if char in 'aeiou')
Este transformador añade una nueva columna numero_vocales
que contiene el conteo de vocales en cada entrada de texto.
Creamos un conjunto de datos de ejemplo:
# Datos de ejemplo
data = {
'frase': ['Hola Mundo', 'Scikit Learn', 'Transformación', 'Pipeline Personalizado', 'Machine Learning'],
'valor_numerico': [10, 20, 30, 40, 50],
'clase': [0, 1, 0, 1, 1]
}
df = pd.DataFrame(data)
X = df[['frase', 'valor_numerico']]
y = df['clase']
Identificamos las columnas numéricas y establecemos el preprocesamiento correspondiente:
# Columnas numéricas
columnas_numericas = ['valor_numerico', 'numero_vocales']
# Pipeline para características numéricas
pipeline_numerico = Pipeline(steps=[
('escalar', StandardScaler())
], memory=memory)
Utilizamos ColumnTransformer para aplicar el escalado solo a las columnas numéricas:
preprocesamiento = ColumnTransformer(transformers=[
('numerico', pipeline_numerico, columnas_numericas)
])
Creamos el pipeline completo integrando el transformador personalizado y el modelo de clasificación:
pipeline = Pipeline([
('contador_vocales', ContadorDeVocalesTransformer(columna='frase')),
('preprocesamiento', preprocesamiento),
('clasificador', LogisticRegression())
], memory=memory)
Entrenamos el pipeline con los datos:
pipeline.fit(X, y)
Podemos realizar predicciones sobre nuevos datos:
# Nuevos datos
nuevos_datos = pd.DataFrame({
'frase': ['Aprendizaje Automático', 'Datos y Ciencia'],
'valor_numerico': [25, 35]
})
predicciones = pipeline.predict(nuevos_datos)
print("Predicciones:", predicciones)
El transformador personalizado se integra sin problemas en el pipeline, permitiendo que la nueva característica se genere y procese automáticamente durante el entrenamiento y la inferencia.
En algunos casos, puede ser útil implementar el método get_feature_names_out
para mantener un seguimiento de los nombres de las características después de la transformación:
class ContadorDeVocalesTransformer(BaseEstimator, TransformerMixin):
# ... código previo ...
def get_feature_names_out(self, input_features=None):
if input_features is None:
input_features = []
return np.append(input_features, 'numero_vocales')
Esto es especialmente útil cuando se trabaja con herramientas que dependen de los nombres de las características para interpretación o visualización.
Si se requiere aplicar una transformación sencilla, como convertir textos a minúsculas, se puede utilizar FunctionTransformer:
from sklearn.preprocessing import FunctionTransformer
def convertir_minusculas(X):
X = X.copy()
X['frase'] = X['frase'].str.lower()
return X
transformador_minusculas = FunctionTransformer(convertir_minusculas)
pipeline = Pipeline([
('minusculas', transformador_minusculas),
('contador_vocales', ContadorDeVocalesTransformer(columna='frase')),
('preprocesamiento', preprocesamiento),
('clasificador', LogisticRegression())
], memory=memory)
El uso de FunctionTransformer es práctico para funciones simples, pero para transformaciones más complejas o cuando se necesitan parámetros adicionales, es preferible crear un transformador personalizado.
Es posible combinar múltiples transformadores personalizados dentro del mismo pipeline. Por ejemplo, si queremos añadir una característica que cuente el número de consonantes:
class ContadorDeConsonantesTransformer(BaseEstimator, TransformerMixin):
def __init__(self, columna):
self.columna = columna
def fit(self, X, y=None):
return self
def transform(self, X):
X = X.copy()
X['numero_consonantes'] = X[self.columna].apply(self._contar_consonantes)
return X
def _contar_consonantes(self, texto):
texto = str(texto).lower()
return sum(1 for char in texto if char.isalpha() and char not in 'aeiou')
def get_feature_names_out(self, input_features=None):
if input_features is None:
input_features = []
return np.append(input_features, 'numero_consonantes')
Actualizamos las columnas numéricas y el preprocesamiento:
# Nuevas columnas numéricas
columnas_numericas = ['valor_numerico', 'numero_vocales', 'numero_consonantes']
# Actualizar preprocesamiento
preprocesamiento = ColumnTransformer(transformers=[
('numerico', pipeline_numerico, columnas_numericas)
])
Integramos el nuevo transformador en el pipeline:
pipeline = Pipeline([
('minusculas', transformador_minusculas),
('contador_vocales', ContadorDeVocalesTransformer(columna='frase')),
('contador_consonantes', ContadorDeConsonantesTransformer(columna='frase')),
('preprocesamiento', preprocesamiento),
('clasificador', LogisticRegression())
], memory=memory)
Entrenamos el pipeline actualizado:
pipeline.fit(X, y)
De esta forma, el pipeline aplica múltiples transformaciones personalizadas, enriqueciendo el conjunto de características y potencialmente mejorando la precisión del modelo.
Implementar transformadores personalizados es una excelente manera de adaptar el preprocesamiento a necesidades específicas y puede ser fundamental para extraer información valiosa de los datos. Al integrarlos en un pipeline, se asegura que todo el proceso sea coherente, reproducible y fácil de mantener.
Es importante seguir las buenas prácticas al crear transformadores personalizados, como manejar correctamente copias de los datos para evitar modificaciones no deseadas y documentar claramente el propósito y funcionamiento de cada transformador. Esto facilita la colaboración y el mantenimiento a largo plazo del código.
Ejercicios de esta lección Preprocesamiento de datos con pipelines
Evalúa tus conocimientos de esta lección Preprocesamiento de datos con pipelines 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
- Entender el concepto de escalado y normalización como pasos de preprocesamiento clave en pipelines de algoritmos de aprendizaje automático.
- Ser capaz de implementar transformaciones de escalado y normalización en pipelines utilizando bibliotecas como Scikit-Learn.
- Evaluar la precisión de diferentes métodos de escalado y normalización a través de validación cruzada.
- Conocer la importancia de la consistencia en la aplicación de transformaciones de datos para evitar errores durante el entrenamiento y la predicción.
- Comprender las buenas prácticas para optimizar el rendimiento del pipeline, incluyendo la caché de resultados intermedios.