Búsqueda de sitios web

Cómo crear una cuadrícula de técnicas de preparación de datos de búsqueda


El rendimiento del modelado predictivo del aprendizaje automático es tan bueno como sus datos, y sus datos son tan buenos como la forma en que los prepara para el modelado.

El enfoque más común para la preparación de datos es estudiar un conjunto de datos y revisar las expectativas de los algoritmos de aprendizaje automático, luego elegir cuidadosamente las técnicas de preparación de datos más apropiadas para transformar los datos sin procesar y cumplir mejor con las expectativas del algoritmo. Esto es lento, costoso y requiere una gran cantidad de experiencia.

Un enfoque alternativo para la preparación de datos es buscar en una cuadrícula un conjunto de técnicas de preparación de datos comunes y comúnmente útiles para los datos sin procesar. Esta es una filosofía alternativa para la preparación de datos que trata las transformaciones de datos como otro hiperparámetro del proceso de modelado que se debe buscar y ajustar.

Este enfoque requiere menos experiencia que el enfoque manual tradicional para la preparación de datos, aunque es costoso desde el punto de vista computacional. El beneficio es que puede ayudar en el descubrimiento de soluciones de preparación de datos no intuitivas que logran un buen o mejor rendimiento para un problema de modelado predictivo determinado.

En este tutorial, descubrirá cómo utilizar el enfoque de búsqueda en cuadrícula para la preparación de datos con datos tabulares.

Después de completar este tutorial, sabrá:

  • La búsqueda de cuadrícula proporciona un enfoque alternativo para la preparación de datos tabulares, donde las transformaciones se prueban como hiperparámetros del proceso de modelado.
  • Cómo utilizar el método de búsqueda de cuadrícula para la preparación de datos a fin de mejorar el rendimiento del modelo con respecto a una línea de base para un conjunto de datos de clasificación estándar.
  • Cómo crear una cuadrícula de secuencias de búsqueda de métodos de preparación de datos para mejorar aún más el rendimiento del modelo.

Pon en marcha tu proyecto con mi nuevo libro Preparación de datos para el aprendizaje automático, que incluye tutoriales paso a paso y los archivos de código fuente de Python para todos los ejemplos.

Empecemos.

Descripción general del tutorial

Este tutorial se divide en tres partes; ellos son:

  1. Técnica de búsqueda en cuadrícula para la preparación de datos
  2. Conjunto de datos y línea base de rendimiento

    1. Conjunto de datos de clasificación de vinos
    2. Rendimiento del modelo de referencia
  3. Enfoque de búsqueda en cuadrícula para la preparación de datos

Técnica de búsqueda en cuadrícula para la preparación de datos

La preparación de datos puede ser un desafío.

El enfoque que se prescribe y sigue con mayor frecuencia es analizar el conjunto de datos, revisar los requisitos de los algoritmos y transformar los datos sin procesar para satisfacer mejor las expectativas de los algoritmos.

Esto puede ser eficaz, pero también lento y puede requerir una gran experiencia en análisis de datos y algoritmos de aprendizaje automático.

Un enfoque alternativo es tratar la preparación de variables de entrada como un hiperparámetro del proceso de modelado y ajustarlo junto con la elección del algoritmo y las configuraciones del algoritmo.

Esta podría ser una transformación de datos que “no debería funcionar” o “no debería ser apropiada para el algoritmo” pero da como resultado un rendimiento bueno o excelente. Alternativamente, puede ser la ausencia de una transformación de datos para una variable de entrada que se considera "absolutamente necesaria" pero que da como resultado un rendimiento bueno o excelente.

Esto se puede lograr diseñando una búsqueda en cuadrícula de técnicas de preparación de datos y/o secuencias de técnicas de preparación de datos en canalizaciones. Esto puede implicar evaluar cada uno de ellos en un único algoritmo de aprendizaje automático elegido o en un conjunto de algoritmos de aprendizaje automático.

El beneficio de este enfoque es que siempre da como resultado sugerencias de canalizaciones de modelado que dan buenos resultados relativos. Lo más importante es que puede descubrir soluciones que no son obvias ni intuitivas para los profesionales sin la necesidad de tener una gran experiencia.

Podemos explorar este enfoque para la preparación de datos con un ejemplo resuelto.

Antes de sumergirnos en un ejemplo resuelto, primero seleccionemos un conjunto de datos estándar y desarrollemos una línea de base de rendimiento.

Conjunto de datos y línea base de rendimiento

En esta sección, primero seleccionaremos un conjunto de datos de aprendizaje automático estándar y estableceremos una línea de base de rendimiento en este conjunto de datos. Esto proporcionará el contexto para explorar el método de búsqueda en cuadrícula para la preparación de datos en la siguiente sección.

Conjunto de datos de clasificación de vinos

Usaremos el conjunto de datos de clasificación de vinos.

Este conjunto de datos tiene 13 variables de entrada que describen la composición química de muestras de vino y requiere que el vino se clasifique en uno de tres tipos.

Puede obtener más información sobre el conjunto de datos aquí:

  • Conjunto de datos de vino (wine.csv)
  • Descripción del conjunto de datos de vino (wine.names)

No es necesario descargar el conjunto de datos, ya que lo descargaremos automáticamente como parte de nuestros ejemplos trabajados.

Abra el conjunto de datos y revise los datos sin procesar. Las primeras filas de datos se enumeran a continuación.

Podemos ver que es un problema de modelado predictivo de clasificación multiclase con variables de entrada numéricas, cada una de las cuales tiene diferentes escalas.

14.23,1.71,2.43,15.6,127,2.8,3.06,.28,2.29,5.64,1.04,3.92,1065,1
13.2,1.78,2.14,11.2,100,2.65,2.76,.26,1.28,4.38,1.05,3.4,1050,1
13.16,2.36,2.67,18.6,101,2.8,3.24,.3,2.81,5.68,1.03,3.17,1185,1
14.37,1.95,2.5,16.8,113,3.85,3.49,.24,2.18,7.8,.86,3.45,1480,1
13.24,2.59,2.87,21,118,2.8,2.69,.39,1.82,4.32,1.04,2.93,735,1
...

El siguiente ejemplo carga el conjunto de datos y lo divide en las columnas de entrada y salida, luego resume las matrices de datos.

# example of loading and summarizing the wine dataset
from pandas import read_csv
# define the location of the dataset
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/wine.csv'
# load the dataset as a data frame
df = read_csv(url, header=None)
# retrieve the numpy array
data = df.values
# split the columns into input and output variables
X, y = data[:, :-1], data[:, -1]
# summarize the shape of the loaded data
print(X.shape, y.shape)

Al ejecutar el ejemplo, podemos ver que el conjunto de datos se cargó correctamente y que hay 179 filas de datos con 13 variables de entrada y una única variable de destino.

(178, 13) (178,)

A continuación, evaluemos un modelo con este conjunto de datos y establezcamos una línea de base de rendimiento.

Rendimiento del modelo de referencia

Podemos establecer una línea de base en el desempeño de la tarea de clasificación de vinos evaluando un modelo con los datos de entrada sin procesar.

En este caso, evaluaremos un modelo de regresión logística.

Primero, podemos definir una función para cargar el conjunto de datos y realizar una preparación mínima de los datos para garantizar que las entradas sean numéricas y el destino esté codificado con etiquetas.

# prepare the dataset
def load_dataset():
	# load the dataset
	url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/wine.csv'
	df = read_csv(url, header=None)
	data = df.values
	X, y = data[:, :-1], data[:, -1]
	# minimally prepare dataset
	X = X.astype('float')
	y = LabelEncoder().fit_transform(y.astype('str'))
	return X, y

Evaluaremos el modelo utilizando el estándar de oro de validación cruzada repetida estratificada de k veces con 10 pliegues y tres repeticiones.

# evaluate a model
def evaluate_model(X, y, model):
	# define the cross-validation procedure
	cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
	# evaluate model
	scores = cross_val_score(model, X, y, scoring='accuracy', cv=cv, n_jobs=-1)
	return scores

Luego podemos llamar a la función para cargar el conjunto de datos, definir nuestro modelo y luego evaluarlo, informando la precisión de la media y la desviación estándar.

...
# get the dataset
X, y = load_dataset()
# define the model
model = LogisticRegression(solver='liblinear')
# evaluate the model
scores = evaluate_model(X, y, model)
# report performance
print('Accuracy: %.3f (%.3f)' % (mean(scores), std(scores)))

Uniendo todo esto, a continuación se enumera el ejemplo completo de evaluación de un modelo de regresión logística en el conjunto de datos de clasificación de vino crudo.

# baseline model performance on the wine dataset
from numpy import mean
from numpy import std
from pandas import read_csv
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression

# prepare the dataset
def load_dataset():
	# load the dataset
	url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/wine.csv'
	df = read_csv(url, header=None)
	data = df.values
	X, y = data[:, :-1], data[:, -1]
	# minimally prepare dataset
	X = X.astype('float')
	y = LabelEncoder().fit_transform(y.astype('str'))
	return X, y

# evaluate a model
def evaluate_model(X, y, model):
	# define the cross-validation procedure
	cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
	# evaluate model
	scores = cross_val_score(model, X, y, scoring='accuracy', cv=cv, n_jobs=-1)
	return scores

# get the dataset
X, y = load_dataset()
# define the model
model = LogisticRegression(solver='liblinear')
# evaluate the model
scores = evaluate_model(X, y, model)
# report performance
print('Accuracy: %.3f (%.3f)' % (mean(scores), std(scores)))

La ejecución del ejemplo evalúa el rendimiento del modelo e informa la precisión de la clasificación de la desviación estándar y media.

Nota: Sus resultados pueden variar dada la naturaleza estocástica del algoritmo o procedimiento de evaluación, o diferencias en la precisión numérica. Considere ejecutar el ejemplo varias veces y comparar el resultado promedio.

En este caso, podemos ver que el ajuste del modelo de regresión logística a los datos de entrada sin procesar logró una precisión de clasificación promedio de alrededor del 95,3 por ciento, lo que proporciona una base de referencia en el rendimiento.

Accuracy: 0.953 (0.048)

A continuación, exploremos si podemos mejorar el rendimiento utilizando el enfoque basado en búsqueda en cuadrícula para la preparación de datos.

Enfoque de búsqueda en cuadrícula para la preparación de datos

En esta sección, podemos explorar si podemos mejorar el rendimiento utilizando el enfoque de búsqueda en cuadrícula para la preparación de datos.

El primer paso es definir una serie de canales de modelado para evaluar, donde cada canal define una (o más) técnicas de preparación de datos y finaliza con un modelo que toma los datos transformados como entrada.

Definiremos una función para crear estas canalizaciones como una lista de tuplas, donde cada tupla define el nombre corto de la canalización y la canalización misma. Evaluaremos una variedad de diferentes métodos de escalado de datos (por ejemplo, MinMaxScaler y StandardScaler), transformaciones de distribución (QuantileTransformer y KBinsDiscretizer), así como transformaciones de reducción de dimensionalidad (PCA y SVD).

# get modeling pipelines to evaluate
def get_pipelines(model):
	pipelines = list()
	# normalize
	p = Pipeline([('s',MinMaxScaler()), ('m',model)])
	pipelines.append(('norm', p))
	# standardize
	p = Pipeline([('s',StandardScaler()), ('m',model)])
	pipelines.append(('std', p))
	# quantile
	p = Pipeline([('s',QuantileTransformer(n_quantiles=100, output_distribution='normal')), ('m',model)])
	pipelines.append(('quan', p))
	# discretize
	p = Pipeline([('s',KBinsDiscretizer(n_bins=10, encode='ordinal', strategy='uniform')), ('m',model)])
	pipelines.append(('kbins', p))
	# pca
	p = Pipeline([('s',PCA(n_components=7)), ('m',model)])
	pipelines.append(('pca', p))
	# svd
	p = Pipeline([('s',TruncatedSVD(n_components=7)), ('m',model)])
	pipelines.append(('svd', p))
	return pipelines

Luego podemos llamar a esta función para obtener la lista de transformaciones, luego enumerar cada una, evaluarla e informar el rendimiento a lo largo del camino.

...
# get the modeling pipelines
pipelines = get_pipelines(model)
# evaluate each pipeline
results, names = list(), list()
for name, pipeline in pipelines:
	# evaluate
	scores = evaluate_model(X, y, pipeline)
	# summarize
	print('>%s: %.3f (%.3f)' % (name, mean(scores), std(scores)))
	# store
	results.append(scores)
	names.append(name)

Al final de la ejecución, podemos crear un diagrama de caja y bigotes para cada conjunto de puntuaciones y comparar visualmente las distribuciones de los resultados.

...
# plot the result
pyplot.boxplot(results, labels=names, showmeans=True)
pyplot.show()

Uniendo todo esto, a continuación se enumera el ejemplo completo de técnicas de preparación de datos de búsqueda de cuadrículas en el conjunto de datos de clasificación de vinos.

# compare data preparation methods for the wine classification dataset
from numpy import mean
from numpy import std
from pandas import read_csv
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import MinMaxScaler
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import QuantileTransformer
from sklearn.preprocessing import KBinsDiscretizer
from sklearn.decomposition import PCA
from sklearn.decomposition import TruncatedSVD
from matplotlib import pyplot

# prepare the dataset
def load_dataset():
	# load the dataset
	url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/wine.csv'
	df = read_csv(url, header=None)
	data = df.values
	X, y = data[:, :-1], data[:, -1]
	# minimally prepare dataset
	X = X.astype('float')
	y = LabelEncoder().fit_transform(y.astype('str'))
	return X, y

# evaluate a model
def evaluate_model(X, y, model):
	# define the cross-validation procedure
	cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
	# evaluate model
	scores = cross_val_score(model, X, y, scoring='accuracy', cv=cv, n_jobs=-1)
	return scores

# get modeling pipelines to evaluate
def get_pipelines(model):
	pipelines = list()
	# normalize
	p = Pipeline([('s',MinMaxScaler()), ('m',model)])
	pipelines.append(('norm', p))
	# standardize
	p = Pipeline([('s',StandardScaler()), ('m',model)])
	pipelines.append(('std', p))
	# quantile
	p = Pipeline([('s',QuantileTransformer(n_quantiles=100, output_distribution='normal')), ('m',model)])
	pipelines.append(('quan', p))
	# discretize
	p = Pipeline([('s',KBinsDiscretizer(n_bins=10, encode='ordinal', strategy='uniform')), ('m',model)])
	pipelines.append(('kbins', p))
	# pca
	p = Pipeline([('s',PCA(n_components=7)), ('m',model)])
	pipelines.append(('pca', p))
	# svd
	p = Pipeline([('s',TruncatedSVD(n_components=7)), ('m',model)])
	pipelines.append(('svd', p))
	return pipelines

# get the dataset
X, y = load_dataset()
# define the model
model = LogisticRegression(solver='liblinear')
# get the modeling pipelines
pipelines = get_pipelines(model)
# evaluate each pipeline
results, names = list(), list()
for name, pipeline in pipelines:
	# evaluate
	scores = evaluate_model(X, y, pipeline)
	# summarize
	print('>%s: %.3f (%.3f)' % (name, mean(scores), std(scores)))
	# store
	results.append(scores)
	names.append(name)
# plot the result
pyplot.boxplot(results, labels=names, showmeans=True)
pyplot.show()

La ejecución del ejemplo evalúa el rendimiento de cada canalización e informa la precisión de la clasificación de la desviación estándar y media.

Nota: Sus resultados pueden variar dada la naturaleza estocástica del algoritmo o procedimiento de evaluación, o diferencias en la precisión numérica. Considere ejecutar el ejemplo varias veces y comparar el resultado promedio.

En este caso, podemos ver que la estandarización de las variables de entrada y el uso de una transformación cuantil logran el mejor resultado con una precisión de clasificación de aproximadamente el 98,7 por ciento, una mejora con respecto a la línea de base sin preparación de datos que logró una precisión de clasificación del 95,3 por ciento.

Puede agregar sus propios canales de modelado a la función get_pipelines() y comparar su resultado.

¿Puedes obtener mejores resultados?
Déjamelo saber en los comentarios a continuación.

>norm: 0.976 (0.031)
>std: 0.987 (0.023)
>quan: 0.987 (0.023)
>kbins: 0.968 (0.045)
>pca: 0.963 (0.039)
>svd: 0.953 (0.048)

Se crea una figura que muestra diagramas de caja y bigotes que resumen la distribución de las puntuaciones de precisión de la clasificación para cada técnica de preparación de datos. Podemos ver que la distribución de puntuaciones para la estandarización y las transformadas cuantiles son compactas y muy similares y tienen un valor atípico. Podemos ver que la dispersión de puntuaciones para las otras transformaciones es mayor y está sesgada hacia abajo.

Los resultados pueden sugerir que la estandarización del conjunto de datos es probablemente un paso importante en la preparación de datos y las transformaciones relacionadas, como la transformada cuantil, y tal vez incluso la transformada de potencia puede ofrecer beneficios si se combina con la estandarización al hacer que una o más variables de entrada sean más gaussianas.

También podemos explorar secuencias de transformaciones para ver si pueden ofrecer un aumento en el rendimiento.

Por ejemplo, es posible que deseemos aplicar la selección de características RFE después de la transformación de estandarización para ver si se pueden usar los mismos o mejores resultados con menos variables de entrada (por ejemplo, menos complejidad).

También es posible que deseemos ver si una transformación de potencia precedida por una transformación de escalado de datos puede lograr un buen rendimiento en el conjunto de datos como creemos que podría lograrse dado el éxito de la transformación cuantil.

A continuación se proporciona la función get_pipelines() actualizada con secuencias de transformaciones.

# get modeling pipelines to evaluate
def get_pipelines(model):
	pipelines = list()
	# standardize
	p = Pipeline([('s',StandardScaler()), ('r', RFE(estimator=LogisticRegression(solver='liblinear'), n_features_to_select=10)), ('m',model)])
	pipelines.append(('std', p))
	# scale and power
	p = Pipeline([('s',MinMaxScaler((1,2))), ('p', PowerTransformer()), ('m',model)])
	pipelines.append(('power', p))
	return pipelines

Uniendo esto, el ejemplo completo se enumera a continuación.

# compare sequences of data preparation methods for the wine classification dataset
from numpy import mean
from numpy import std
from pandas import read_csv
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import MinMaxScaler
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import QuantileTransformer
from sklearn.preprocessing import PowerTransformer
from sklearn.preprocessing import KBinsDiscretizer
from sklearn.decomposition import PCA
from sklearn.decomposition import TruncatedSVD
from sklearn.feature_selection import RFE
from matplotlib import pyplot

# prepare the dataset
def load_dataset():
	# load the dataset
	url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/wine.csv'
	df = read_csv(url, header=None)
	data = df.values
	X, y = data[:, :-1], data[:, -1]
	# minimally prepare dataset
	X = X.astype('float')
	y = LabelEncoder().fit_transform(y.astype('str'))
	return X, y

# evaluate a model
def evaluate_model(X, y, model):
	# define the cross-validation procedure
	cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
	# evaluate model
	scores = cross_val_score(model, X, y, scoring='accuracy', cv=cv, n_jobs=-1)
	return scores

# get modeling pipelines to evaluate
def get_pipelines(model):
	pipelines = list()
	# standardize
	p = Pipeline([('s',StandardScaler()), ('r', RFE(estimator=LogisticRegression(solver='liblinear'), n_features_to_select=10)), ('m',model)])
	pipelines.append(('std', p))
	# scale and power
	p = Pipeline([('s',MinMaxScaler((1,2))), ('p', PowerTransformer()), ('m',model)])
	pipelines.append(('power', p))
	return pipelines

# get the dataset
X, y = load_dataset()
# define the model
model = LogisticRegression(solver='liblinear')
# get the modeling pipelines
pipelines = get_pipelines(model)
# evaluate each pipeline
results, names = list(), list()
for name, pipeline in pipelines:
	# evaluate
	scores = evaluate_model(X, y, pipeline)
	# summarize
	print('>%s: %.3f (%.3f)' % (name, mean(scores), std(scores)))
	# store
	results.append(scores)
	names.append(name)
# plot the result
pyplot.boxplot(results, labels=names, showmeans=True)
pyplot.show()

La ejecución del ejemplo evalúa el rendimiento de cada canalización e informa la precisión de la clasificación de la desviación estándar y media.

Nota: Sus resultados pueden variar dada la naturaleza estocástica del algoritmo o procedimiento de evaluación, o diferencias en la precisión numérica. Considere ejecutar el ejemplo varias veces y comparar el resultado promedio.

En este caso, podemos ver que la estandarización con la selección de funciones ofrece un aumento adicional en la precisión del 98,7 por ciento al 98,9 por ciento, aunque el escalado de datos y la transformación de potencia no ofrecen ningún beneficio adicional sobre la transformación cuantil.

>std: 0.989 (0.022)
>power: 0.987 (0.023)

Se crea una figura que muestra diagramas de caja y bigotes que resumen la distribución de las puntuaciones de precisión de la clasificación para cada técnica de preparación de datos.

Podemos ver que la distribución de resultados para ambos canales de transformaciones es compacta con muy poca dispersión aparte de los valores atípicos.

Lectura adicional

Esta sección proporciona más recursos sobre el tema si desea profundizar más.

Libros

  • Ingeniería y Selección de Funciones, 2019.
  • Ingeniería de funciones para el aprendizaje automático, 2018.

API

  • sklearn.pipeline.Pipeline API.

Resumen

En este tutorial, descubrió cómo utilizar un enfoque de búsqueda en cuadrícula para la preparación de datos con datos tabulares.

Específicamente, aprendiste:

  • La búsqueda de cuadrícula proporciona un enfoque alternativo para la preparación de datos tabulares, donde las transformaciones se prueban como hiperparámetros del proceso de modelado.
  • Cómo utilizar el método de búsqueda de cuadrícula para la preparación de datos a fin de mejorar el rendimiento del modelo con respecto a una línea de base para un conjunto de datos de clasificación estándar.
  • Cómo crear una cuadrícula de secuencias de búsqueda de métodos de preparación de datos para mejorar aún más el rendimiento del modelo.

¿Tiene alguna pregunta?
Haga sus preguntas en los comentarios a continuación y haré todo lo posible para responderlas.

Artículos relacionados