Aprendizaje automático: conjunto de mezclas en Python

La combinación es un algoritmo conjunto de aprendizaje automático. Este es un nombre coloquial para la generalización apilada [de aquí en adelante usaremos el término "empaque" en lugar del término "apilamiento" aceptado en trabajos científicos] o el conjunto de empaque, donde en lugar de entrenar el metamodelo en predicciones fuera de los grupos hechos por el modelo base, el modelo se entrena en predicciones realizadas en un conjunto de datos independiente.



La combinación se ha utilizado para describir modelos de procesamiento por lotes que han agrupado muchos cientos de modelos en la competencia de aprendizaje automático de Netflix de $ 1,000,000 y, como tal, la combinación sigue siendo un método y nombre popular para el procesamiento por lotes en concursos de aprendizaje automático como Kaggle. ... Especialmente para el inicio del nuevo hilo del curso de Machine Learning, estamos compartiendo un tutorial del cual aprenderá a desarrollar y evaluar un conjunto mixto en Python. Después de completar este tutorial, sabrá:



  • Los conjuntos mixtos son un tipo de procesamiento por lotes de modelos en el que se entrena un metamodelo mediante predicciones en un conjunto de datos de validación de prueba independiente en lugar de predicciones durante la validación cruzada de k veces.
  • Cómo desarrollar un conjunto mixto, incluidas funciones de predicción y entrenamiento de modelos basadas en datos nuevos.
  • Cómo evaluar conjuntos mixtos para problemas de modelado de regresión predictiva y clasificación.









Descripción general del tutorial



Este tutorial se divide en cuatro partes. Aquí están:



  • Conjunto mixto.
  • Creación de un conjunto mixto.
  • Conjunto mixto en un problema de clasificación.
  • Conjunto mixto en un problema de regresión.


Conjunto mixto



La combinación es una técnica de aprendizaje automático por conjuntos que utiliza un modelo de aprendizaje automático para aprender cómo combinar mejor las predicciones de varios modelos de miembros del conjunto.



Entonces, mezclar es lo mismo que apilar la generalización conocida como apilar. La mezcla y el procesamiento por lotes se utilizan a menudo indistintamente en el mismo artículo o descripción de modelo.



Muchos profesionales del aprendizaje automático han tenido éxito utilizando el procesamiento por lotes y técnicas relacionadas para mejorar la precisión de la predicción en cualquiera de los modelos individuales. En algunos contextos, el procesamiento por lotes también se denomina combinación. También intercambiaremos términos aquí.

Apilamiento lineal ponderado por características , 2009.


La arquitectura del modelo por lotes contiene dos o más modelos de línea base, a menudo denominados modelos de nivel cero, y el metamodelo, que combina las predicciones del modelo de línea base, es un modelo de nivel uno. El metamodelo se entrena en función de las predicciones realizadas por los modelos base en datos fuera de la muestra.



  • ( ) — , , .
  • () — , .


Sin embargo, la mezcla tiene ciertas connotaciones para construir un modelo de conjunto empaquetado. La combinación puede ofrecer el desarrollo de un conjunto de pila, donde los modelos base son cualquier tipo de modelo de aprendizaje automático, y el metamodelo es un modelo lineal que "combina" las predicciones de los modelos base. Por ejemplo, un modelo de regresión lineal al predecir un valor numérico, o un modelo de regresión logística al predecir una etiqueta de clase, calcula la suma ponderada de las predicciones realizadas por los modelos base y se tratará como predicciones de mezcla.



  • Conjunto mixto : utilice un modelo lineal, como la regresión lineal o la regresión logística, como metamodelo en un conjunto de modelos por lotes.


Mezclar era un término que se usaba comúnmente para un conjunto empaquetado durante la competencia de Netflix de 2009. La competencia involucró a equipos que buscaban modelos predictivos que funcionaran mejor que el algoritmo nativo de Netflix, con un premio de $ 1,000,000 otorgado al equipo que logró una mejora del 10 por ciento en el rendimiento.



Nuestra solución con RMSE = 0.8643 ^ 2 es una mezcla lineal de más de 100 resultados. […] A lo largo de la descripción de los métodos, destacamos los predictores específicos que participaron en la solución mixta final.

La solución BellKor 2008 para el premio Netflix , 2008.


Por lo tanto, mezclar es el término coloquial para el aprendizaje en conjunto con una arquitectura modelo como el procesamiento por lotes. Rara vez, o nunca, se utiliza en libros de texto o artículos académicos distintos de los relacionados con el aprendizaje automático en competición. Más comúnmente, el término combinación se usa para describir una aplicación específica de procesamiento por lotes donde un metamodelo se entrena en predicciones hechas por modelos base con un conjunto de datos de validación independiente. En este contexto, el empaquetado está reservado para el metamodelo entrenado en predicciones durante el procedimiento de validación cruzada.



  • Mezcla : un conjunto de tipo lote en el que el metamodelo se entrena sobre predicciones realizadas en un conjunto de datos independiente.
  • Procesamiento por lotes : un conjunto de tipo por lotes en el que el metamodelo se entrena según las predicciones realizadas durante la validación cruzada de k-fold.


Esta distinción es común en la comunidad de competencia de aprendizaje automático de Kaggle.



Mezclar es la palabra acuñada por los ganadores de Netflix. Está muy cerca de la generalización, pero un poco más simple y el riesgo de fuga de información es menor. […] Al mezclar, en lugar de generar predicciones durante la validación cruzada para el conjunto de entrenamiento, crea un pequeño conjunto independiente de, digamos, el 10% del conjunto de entrenamiento. Luego, el modelo de procesamiento por lotes se entrena solo en este pequeño conjunto.

Guía de conjuntos de Kaggle , MLWave, 2015.


Usamos la última definición de mezcla. Veamos cómo se implementa.



Desarrollo de conjuntos mixtos



La biblioteca scikit-learn no admite la mezcla lista para usar en el momento de escribir este artículo. Pero podemos implementarlo nosotros mismos utilizando modelos scikit-learn. Primero, necesita crear un conjunto de modelos base. Puede ser cualquier modelo que queramos para un problema de regresión o clasificación. Podemos definir una función get_models () que devuelve una lista de modelos, donde cada modelo se define como una tupla con un nombre y un clasificador personalizado o un objeto de regresión. Por ejemplo, para un problema de clasificación, podríamos usar regresión logística, kNN, árbol de decisión, SVM y modelo bayesiano ingenuo.



# get a list of base models
def get_models():
models = list()
models.append(('lr', LogisticRegression()))
models.append(('knn', KNeighborsClassifier()))
models.append(('cart', DecisionTreeClassifier()))
models.append(('svm', SVC(probability=True)))
models.append(('bayes', GaussianNB()))
return models
      
      





A continuación, necesitamos entrenar el modelo de mezcla. Recuerde que los modelos base se entrenan en el conjunto de datos de entrenamiento. El metamodelo se entrena sobre las predicciones realizadas por cada modelo base en un conjunto de datos independiente.



Primero, podemos recorrer los modelos en una lista y entrenar cada uno por turno en el conjunto de datos de entrenamiento. Además, en este ciclo, podemos usar un modelo entrenado para hacer una predicción en un conjunto de datos independiente (validación) y almacenar predicciones para el futuro.



...
# fit all models on the training set and predict on hold out set
meta_X = list()
for name, model in models:
# fit in training set
model.fit(X_train, y_train)
# predict on hold out set
yhat = model.predict(X_val)
# reshape predictions into a matrix with one column
yhat = yhat.reshape(len(yhat), 1)
# store predictions as input for blending
meta_X.append(yhat)
      
      





Ahora tenemos un "meta_X *" que representa la entrada que se puede usar para entrenar el metamodelo. Cada columna u objeto representa la salida de un modelo base. Cada línea representa una muestra de un conjunto de datos independiente. Podemos usar la función hstack () para asegurarnos de que este conjunto de datos sea una matriz numérica bidimensional, como esperaba el modelo de aprendizaje automático.



...
# create 2d array from predictions, each set is an input feature
meta_X = hstack(meta_X)
      
      





Ahora podemos entrenar nuestro metamodelo. Puede ser cualquier modelo de aprendizaje automático que nos guste, como la regresión logística para un problema de clasificación.



...
# define blending model
blender = LogisticRegression()
# fit on predictions from base models
blender.fit(meta_X, y_val)
      
      





Puede agruparlo todo en una función llamada fit_ensemble () que entrena el modelo de fusión utilizando el conjunto de datos de validación independiente y de entrenamiento.



# fit the blending ensemble
def fit_ensemble(models, X_train, X_val, y_train, y_val):
# fit all models on the training set and predict on hold out set
meta_X = list()
for name, model in models:
# fit in training set
model.fit(X_train, y_train)
# predict on hold out set
yhat = model.predict(X_val)
# reshape predictions into a matrix with one column
yhat = yhat.reshape(len(yhat), 1)
# store predictions as input for blending
meta_X.append(yhat)
# create 2d array from predictions, each set is an input feature
meta_X = hstack(meta_X)
# define blending model
blender = LogisticRegression()
# fit on predictions from base models
blender.fit(meta_X, y_val)
return blender
      
      





El siguiente paso es usar un conjunto de mezcla para predecir nuevos datos. Este es un proceso de dos pasos. El primer paso es utilizar cada modelo base para la previsión. Luego, las predicciones se juntan y se utilizan como entrada al modelo de mezcla para realizar la predicción final.



Podemos usar el mismo ciclo que al entrenar el modelo. Es decir, recopile las predicciones de cada modelo base en un conjunto de datos de entrenamiento, sume las predicciones y llame a predict () en el modelo de mezcla con este conjunto de datos de metanivel. Predict_ensemble () función a continuación implementa estas acciones. Al entrenar una lista de modelos base, entrenar un mezclador de conjuntos y un conjunto de datos (como un conjunto de datos de prueba o nuevos datos), para el conjunto de datos, devolverá un conjunto de predicciones.



# make a prediction with the blending ensemble
def predict_ensemble(models, blender, X_test):
# make predictions with base models
meta_X = list()
for name, model in models:
# predict with base model
yhat = model.predict(X_test)
# reshape predictions into a matrix with one column
yhat = yhat.reshape(len(yhat), 1)
# store prediction
meta_X.append(yhat)
# create 2d array from predictions, each set is an input feature
meta_X = hstack(meta_X)
# predict
return blender.predict(meta_X)
      
      





Ahora tenemos todos los elementos necesarios para implementar un conjunto mixto para problemas de clasificación o modelos de regresión predictiva.



Conjunto mixto para problemas de clasificación



En esta sección, veremos el uso de la combinación para la tarea de clasificación. Primero, podemos usar la función make_classification () para crear un problema de clasificación binaria sintética con 10,000 ejemplos y 20 características de entrada. El ejemplo completo se muestra a continuación.



# test classification dataset
from sklearn.datasets import make_classification
# define dataset
X, y = make_classification(n_samples=10000, n_features=20, n_informative=15, n_redundant=5, random_state=7)
# summarize the dataset
print(X.shape, y.shape)
      
      





La ejecución del ejemplo crea un conjunto de datos y resume las entradas y salidas.



(10000, 20) (10000,)
      
      





A continuación, primero debemos dividir el conjunto de datos en conjuntos de entrenamiento y de prueba, y luego el conjunto de entrenamiento en un subconjunto utilizado para entrenar los modelos básicos y un subconjunto utilizado para entrenar el metamodelo. En este caso, usaremos una división 50-50 para los conjuntos de entrenamiento y prueba, y luego una división 67-33 para los conjuntos de entrenamiento y validación.



...
# split dataset into train and test sets
X_train_full, X_test, y_train_full, y_test = train_test_split(X, y, test_size=0.5, random_state=1)
# split training set into train and validation sets
X_train, X_val, y_train, y_val = train_test_split(X_train_full, y_train_full, test_size=0.33, random_state=1)
# summarize data split
print('Train: %s, Val: %s, Test: %s' % (X_train.shape, X_val.shape, X_test.shape))
      
      





A continuación, puede utilizar la función get_models () de la sección anterior para crear los modelos de clasificación utilizados en el conjunto. A continuación, se puede llamar a la función fit_ensemble () para entrenar el conjunto mixto en estos conjuntos de datos, y la función predict_ensemble () se puede usar para hacer predicciones en un conjunto de datos independiente.



...
# create the base models
models = get_models()
# train the blending ensemble
blender = fit_ensemble(models, X_train, X_val, y_train, y_val)
# make predictions on test set
yhat = predict_ensemble(models, blender, X_test)
      
      





Finalmente, podemos evaluar el rendimiento del modelo de mezcla informando la precisión de la clasificación en el conjunto de datos de prueba.



...
# evaluate predictions
score = accuracy_score(y_test, yhat)
print('Blending Accuracy: %.3f' % score)
      
      





A continuación se proporciona un ejemplo completo de estimación de un conjunto mixto en un problema de clasificación binaria sintética.



# blending ensemble for classification using hard voting
from numpy import hstack
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.svm import SVC
from sklearn.naive_bayes import GaussianNB

# get the dataset
def get_dataset():
X, y = make_classification(n_samples=10000, n_features=20, n_informative=15, n_redundant=5, random_state=7)
return X, y

# get a list of base models
def get_models():
models = list()
models.append(('lr', LogisticRegression()))
models.append(('knn', KNeighborsClassifier()))
models.append(('cart', DecisionTreeClassifier()))
models.append(('svm', SVC()))
models.append(('bayes', GaussianNB()))
return models

# fit the blending ensemble
def fit_ensemble(models, X_train, X_val, y_train, y_val):
# fit all models on the training set and predict on hold out set
meta_X = list()
for name, model in models:
# fit in training set
model.fit(X_train, y_train)
# predict on hold out set
yhat = model.predict(X_val)
# reshape predictions into a matrix with one column
yhat = yhat.reshape(len(yhat), 1)
# store predictions as input for blending
meta_X.append(yhat)
# create 2d array from predictions, each set is an input feature
meta_X = hstack(meta_X)
# define blending model
blender = LogisticRegression()
# fit on predictions from base models
blender.fit(meta_X, y_val)
return blender

# make a prediction with the blending ensemble
def predict_ensemble(models, blender, X_test):
# make predictions with base models
meta_X = list()
for name, model in models:
# predict with base model
yhat = model.predict(X_test)
# reshape predictions into a matrix with one column
yhat = yhat.reshape(len(yhat), 1)
# store prediction
meta_X.append(yhat)
# create 2d array from predictions, each set is an input feature
meta_X = hstack(meta_X)
# predict
return blender.predict(meta_X)

# define dataset
X, y = get_dataset()
# split dataset into train and test sets
X_train_full, X_test, y_train_full, y_test = train_test_split(X, y, test_size=0.5, random_state=1)
# split training set into train and validation sets
X_train, X_val, y_train, y_val = train_test_split(X_train_full, y_train_full, test_size=0.33, random_state=1)
# summarize data split
print('Train: %s, Val: %s, Test: %s' % (X_train.shape, X_val.shape, X_test.shape))
# create the base models
models = get_models()
# train the blending ensemble
blender = fit_ensemble(models, X_train, X_val, y_train, y_val)
# make predictions on test set
yhat = predict_ensemble(models, blender, X_test)
# evaluate predictions
score = accuracy_score(y_test, yhat)
print('Blending Accuracy: %.3f' % (score*100))
      
      





Al ejecutar el ejemplo, primero se informa un resumen de todos los conjuntos de datos y luego la precisión del conjunto en el conjunto de datos de prueba.



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



Aquí vemos que el conjunto mixto logró una precisión de clasificación de aproximadamente 97.900%.



Train: (3350, 20), Val: (1650, 20), Test: (5000, 20)
Blending Accuracy: 97.900
      
      





En el ejemplo anterior, la predicción de etiquetas de clase claras se combinó mediante un modelo de combinación. Este es un tipo de votación difícil . Una alternativa es un método en el que cada modelo predice las probabilidades de la clase y usa un metamodelo para mezclar las probabilidades. Este es un tipo de voto suave que a veces puede conducir a un mejor desempeño. Primero, tenemos que configurar modelos que devuelvan probabilidades, como el modelo SVM.



# get a list of base models
def get_models():
models = list()
models.append(('lr', LogisticRegression()))
models.append(('knn', KNeighborsClassifier()))
models.append(('cart', DecisionTreeClassifier()))
models.append(('svm', SVC(probability=True)))
models.append(('bayes', GaussianNB()))
return models
      
      





Luego, los modelos subyacentes deben modificarse para predecir probabilidades en lugar de etiquetas de clase claras. Esto se puede lograr llamando a predict_proba () dentro de fit_ensemble () mientras se entrena los modelos subyacentes.



...
# fit all models on the training set and predict on hold out set
meta_X = list()
for name, model in models:
# fit in training set
model.fit(X_train, y_train)
# predict on hold out set
yhat = model.predict_proba(X_val)
# store predictions as input for blending
meta_X.append(yhat)
      
      





Esto significa que el meta-conjunto de datos utilizado para entrenar el meta-modelo tendrá n columnas por clasificador, donde n es el número de clases en el problema de pronóstico, en nuestro caso hay dos clases. También necesitamos cambiar las predicciones hechas por los modelos base cuando usamos el modelo de mezcla para predecir nuevos datos.



...
# make predictions with base models
meta_X = list()
for name, model in models:
# predict with base model
yhat = model.predict_proba(X_test)
# store prediction
meta_X.append(yhat)
      
      





A continuación, se muestra el ejemplo completo de la utilización de la mezcla de probabilidades de clase predichas para un problema de clasificación binaria sintética.




# blending ensemble for classification using soft voting
from numpy import hstack
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.svm import SVC
from sklearn.naive_bayes import GaussianNB

# get the dataset
def get_dataset():
X, y = make_classification(n_samples=10000, n_features=20, n_informative=15, n_redundant=5, random_state=7)
return X, y

# get a list of base models
def get_models():
models = list()
models.append(('lr', LogisticRegression()))
models.append(('knn', KNeighborsClassifier()))
models.append(('cart', DecisionTreeClassifier()))
models.append(('svm', SVC(probability=True)))
models.append(('bayes', GaussianNB()))
return models

# fit the blending ensemble
def fit_ensemble(models, X_train, X_val, y_train, y_val):
# fit all models on the training set and predict on hold out set
meta_X = list()
for name, model in models:
# fit in training set
model.fit(X_train, y_train)
# predict on hold out set
yhat = model.predict_proba(X_val)
# store predictions as input for blending
meta_X.append(yhat)
# create 2d array from predictions, each set is an input feature
meta_X = hstack(meta_X)
# define blending model
blender = LogisticRegression()
# fit on predictions from base models
blender.fit(meta_X, y_val)
return blender

# make a prediction with the blending ensemble
def predict_ensemble(models, blender, X_test):
# make predictions with base models
meta_X = list()
for name, model in models:
# predict with base model
yhat = model.predict_proba(X_test)
# store prediction
meta_X.append(yhat)
# create 2d array from predictions, each set is an input feature
meta_X = hstack(meta_X)
# predict
return blender.predict(meta_X)

# define dataset
X, y = get_dataset()
# split dataset into train and test sets
X_train_full, X_test, y_train_full, y_test = train_test_split(X, y, test_size=0.5, random_state=1)
# split training set into train and validation sets
X_train, X_val, y_train, y_val = train_test_split(X_train_full, y_train_full, test_size=0.33, random_state=1)
# summarize data split
print('Train: %s, Val: %s, Test: %s' % (X_train.shape, X_val.shape, X_test.shape))
# create the base models
models = get_models()
# train the blending ensemble
blender = fit_ensemble(models, X_train, X_val, y_train, y_val)
# make predictions on test set
yhat = predict_ensemble(models, blender, X_test)
# evaluate predictions
score = accuracy_score(y_test, yhat)
print('Blending Accuracy: %.3f' % (score*100))
      
      





Ejecutar el ejemplo primero informa un resumen de todos los conjuntos de datos y luego la precisión del conjunto en el conjunto de prueba.



Nota: Sus resultados pueden variar debido a la naturaleza estocástica del algoritmo o procedimiento de estimación, o diferencias en la precisión numérica. Pruebe el ejemplo varias veces y compare el resultado promedio.



Aquí vemos que la combinación de las probabilidades de clase condujo a un aumento en la precisión de la clasificación hasta aproximadamente el 98,240%.



Train: (3350, 20), Val: (1650, 20), Test: (5000, 20)
Blending Accuracy: 98.240
      
      





Un conjunto mixto solo es efectivo si es capaz de superar a cualquiera de los modelos individuales que lo componen. Podemos confirmar esto evaluando cada uno de los modelos base por separado. Cada modelo de línea de base se puede entrenar en todo el conjunto de datos de entrenamiento (a diferencia del conjunto de mezcla) y evaluar en el conjunto de datos de prueba (al igual que en el conjunto de mezcla). El siguiente ejemplo demuestra esto al evaluar cada modelo de línea de base individualmente.



# evaluate base models on the entire training dataset
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.svm import SVC
from sklearn.naive_bayes import GaussianNB

# get the dataset
def get_dataset():
X, y = make_classification(n_samples=10000, n_features=20, n_informative=15, n_redundant=5, random_state=7)
return X, y

# get a list of base models
def get_models():
models = list()
models.append(('lr', LogisticRegression()))
models.append(('knn', KNeighborsClassifier()))
models.append(('cart', DecisionTreeClassifier()))
models.append(('svm', SVC(probability=True)))
models.append(('bayes', GaussianNB()))
return models

# define dataset
X, y = get_dataset()
# split dataset into train and test sets
X_train_full, X_test, y_train_full, y_test = train_test_split(X, y, test_size=0.5, random_state=1)
# summarize data split
print('Train: %s, Test: %s' % (X_train_full.shape, X_test.shape))
# create the base models
models = get_models()
# evaluate standalone model
for name, model in models:
# fit the model on the training dataset
model.fit(X_train_full, y_train_full)
# make a prediction on the test dataset
yhat = model.predict(X_test)
# evaluate the predictions
score = accuracy_score(y_test, yhat)
# report the score
print('>%s Accuracy: %.3f' % (name, score*100))
      
      







Al ejecutar el ejemplo, primero se informa un resumen de los tres conjuntos de datos y luego la precisión de cada modelo base en el conjunto de prueba.



Nota: Sus resultados pueden diferir debido a la naturaleza estocástica del algoritmo, o al procedimiento de estimación, o diferencias en la precisión numérica. Pruebe el ejemplo varias veces y compare el resultado promedio.



En este caso, vemos que todos los modelos funcionan peor que un conjunto mixto. Lo interesante es que podemos ver que el SVM está muy cerca de lograr un 98.200% de precisión en comparación con el 98.240% de precisión logrado con un conjunto mixto.



Train: (5000, 20), Test: (5000, 20)
>lr Accuracy: 87.800
>knn Accuracy: 97.380
>cart Accuracy: 88.200
>svm Accuracy: 98.200
>bayes Accuracy: 87.300
      
      





Podemos elegir un conjunto mixto como modelo final. Esto incluye entrenar el conjunto en todo el conjunto de datos de entrenamiento y hacer predicciones usando nuevos ejemplos. En particular, todo el conjunto de entrenamiento se divide en conjuntos de entrenamiento y validación para entrenar la base y los metamodelos, respectivamente, y luego el conjunto se puede usar en la previsión. Un ejemplo completo de pronóstico de nuevos datos utilizando un conjunto mixto para la clasificación se ve así:



# example of making a prediction with a blending ensemble for classification
from numpy import hstack
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.svm import SVC
from sklearn.naive_bayes import GaussianNB

# get the dataset
def get_dataset():
X, y = make_classification(n_samples=10000, n_features=20, n_informative=15, n_redundant=5, random_state=7)
return X, y

# get a list of base models
def get_models():
models = list()
models.append(('lr', LogisticRegression()))
models.append(('knn', KNeighborsClassifier()))
models.append(('cart', DecisionTreeClassifier()))
models.append(('svm', SVC(probability=True)))
models.append(('bayes', GaussianNB()))
return models

# fit the blending ensemble
def fit_ensemble(models, X_train, X_val, y_train, y_val):
# fit all models on the training set and predict on hold out set
meta_X = list()
for _, model in models:
# fit in training set
model.fit(X_train, y_train)
# predict on hold out set
yhat = model.predict_proba(X_val)
# store predictions as input for blending
meta_X.append(yhat)
# create 2d array from predictions, each set is an input feature
meta_X = hstack(meta_X)
# define blending model
blender = LogisticRegression()
# fit on predictions from base models
blender.fit(meta_X, y_val)
return blender

# make a prediction with the blending ensemble
def predict_ensemble(models, blender, X_test):
# make predictions with base models
meta_X = list()
for _, model in models:
# predict with base model
yhat = model.predict_proba(X_test)
# store prediction
meta_X.append(yhat)
# create 2d array from predictions, each set is an input feature
meta_X = hstack(meta_X)
# predict
return blender.predict(meta_X)

# define dataset
X, y = get_dataset()
# split dataset set into train and validation sets
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.33, random_state=1)
# summarize data split
print('Train: %s, Val: %s' % (X_train.shape, X_val.shape))
# create the base models
models = get_models()
# train the blending ensemble
blender = fit_ensemble(models, X_train, X_val, y_train, y_val)
# make a prediction on a new row of data
row = [-0.30335011, 2.68066314, 2.07794281, 1.15253537, -2.0583897, -2.51936601, 0.67513028, -3.20651939, -1.60345385, 3.68820714, 0.05370913, 1.35804433, 0.42011397, 1.4732839, 2.89997622, 1.61119399, 7.72630965, -2.84089477, -1.83977415, 1.34381989]
yhat = predict_ensemble(models, blender, [row])
# summarize prediction
print('Predicted Class: %d' % (yhat))
      
      





La ejecución del ejemplo entrena un modelo de conjunto mixto en un conjunto de datos y luego lo usa para predecir una nueva fila de datos, como lo haría si se usara el modelo en una aplicación.



Train: (6700, 20), Val: (3300, 20)
Predicted Class: 1
      
      





Veamos cómo podríamos evaluar el conjunto mixto para la regresión.



Conjunto mixto para problemas de regresión



En esta sección, veremos el uso de lotes para un problema de regresión. Primero, podemos usar la función make_regression () para crear un problema de regresión sintética con 10,000 muestras y 20 características de entrada. El ejemplo completo se muestra a continuación.



# test regression dataset
from sklearn.datasets import make_regression
# define dataset
X, y = make_regression(n_samples=10000, n_features=20, n_informative=10, noise=0.3, random_state=7)
# summarize the dataset
print(X.shape, y.shape)
      
      





La ejecución del ejemplo crea un conjunto de datos y resume los componentes de entrada y salida.



(10000, 20) (10000,)
      
      





A continuación, puede definir una lista de modelos de regresión para usar como línea de base. En este caso, utilizamos modelos de regresión lineal, kNN, árbol de decisión y SVM.



# get a list of base models
def get_models():
models = list()
models.append(('lr', LinearRegression()))
models.append(('knn', KNeighborsRegressor()))
models.append(('cart', DecisionTreeRegressor()))
models.append(('svm', SVR()))
return models
      
      





La función fit_ensemble () usada para entrenar el conjunto no cambia, excepto que el modelo usado para mezclar debe cambiarse a regresión. Aquí utilizamos un modelo de regresión lineal.



...
# define blending model
blender = LinearRegression()
      
      





Dado que se trata de un problema de regresión, evaluaremos el desempeño del modelo utilizando la métrica de error, en este caso el error absoluto promedio, o MAE (abreviado).



...
# evaluate predictions
score = mean_absolute_error(y_test, yhat)
print('Blending MAE: %.3f' % score)
      
      





El ejemplo completo de un conjunto mixto para un problema de modelado predictivo de regresión sintética se muestra a continuación:



# evaluate blending ensemble for regression
from numpy import hstack
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_absolute_error
from sklearn.linear_model import LinearRegression
from sklearn.neighbors import KNeighborsRegressor
from sklearn.tree import DecisionTreeRegressor
from sklearn.svm import SVR

# get the dataset
def get_dataset():
X, y = make_regression(n_samples=10000, n_features=20, n_informative=10, noise=0.3, random_state=7)
return X, y

# get a list of base models
def get_models():
models = list()
models.append(('lr', LinearRegression()))
models.append(('knn', KNeighborsRegressor()))
models.append(('cart', DecisionTreeRegressor()))
models.append(('svm', SVR()))
return models

# fit the blending ensemble
def fit_ensemble(models, X_train, X_val, y_train, y_val):
# fit all models on the training set and predict on hold out set
meta_X = list()
for name, model in models:
# fit in training set
model.fit(X_train, y_train)
# predict on hold out set
yhat = model.predict(X_val)
# reshape predictions into a matrix with one column
yhat = yhat.reshape(len(yhat), 1)
# store predictions as input for blending
meta_X.append(yhat)
# create 2d array from predictions, each set is an input feature
meta_X = hstack(meta_X)
# define blending model
blender = LinearRegression()
# fit on predictions from base models
blender.fit(meta_X, y_val)
return blender

# make a prediction with the blending ensemble
def predict_ensemble(models, blender, X_test):
# make predictions with base models
meta_X = list()
for name, model in models:
# predict with base model
yhat = model.predict(X_test)
# reshape predictions into a matrix with one column
yhat = yhat.reshape(len(yhat), 1)
# store prediction
meta_X.append(yhat)
# create 2d array from predictions, each set is an input feature
meta_X = hstack(meta_X)
# predict
return blender.predict(meta_X)

# define dataset
X, y = get_dataset()
# split dataset into train and test sets
X_train_full, X_test, y_train_full, y_test = train_test_split(X, y, test_size=0.5, random_state=1)
# split training set into train and validation sets
X_train, X_val, y_train, y_val = train_test_split(X_train_full, y_train_full, test_size=0.33, random_state=1)
# summarize data split
print('Train: %s, Val: %s, Test: %s' % (X_train.shape, X_val.shape, X_test.shape))
# create the base models
models = get_models()
# train the blending ensemble
blender = fit_ensemble(models, X_train, X_val, y_train, y_val)
# make predictions on test set
yhat = predict_ensemble(models, blender, X_test)
# evaluate predictions
score = mean_absolute_error(y_test, yhat)
print('Blending MAE: %.3f' % score)
      
      





El ejemplo primero imprime un resumen de los tres conjuntos de datos y luego el MAE en el conjunto de prueba.



Nota: Sus resultados pueden variar debido a la naturaleza estocástica del algoritmo o procedimiento de estimación, o diferencias en la precisión numérica. Pruebe el ejemplo varias veces y compare el resultado promedio.



Aquí vemos que el conjunto alcanzó un MAE de aproximadamente 0,237 en el conjunto de datos de prueba.



Train: (3350, 20), Val: (1650, 20), Test: (5000, 20)
Blending MAE: 0.237
      
      





Al igual que con la clasificación, un conjunto mixto solo es útil si funciona mejor que cualquiera de los modelos de conjunto básico.



Podemos probar esto evaluando cada modelo de línea de base de forma aislada, primero entrenándolo en todo el conjunto de entrenamiento (a diferencia de un conjunto) y haciendo predicciones en el conjunto de datos de prueba (como en un conjunto). En el siguiente ejemplo, cada uno de los modelos de referencia se estima de forma aislada frente a un conjunto de datos de modelos de regresión predictiva sintética.



# evaluate base models in isolation on the regression dataset
from numpy import hstack
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_absolute_error
from sklearn.linear_model import LinearRegression
from sklearn.neighbors import KNeighborsRegressor
from sklearn.tree import DecisionTreeRegressor
from sklearn.svm import SVR

# get the dataset
def get_dataset():
X, y = make_regression(n_samples=10000, n_features=20, n_informative=10, noise=0.3, random_state=7)
return X, y

# get a list of base models
def get_models():
models = list()
models.append(('lr', LinearRegression()))
models.append(('knn', KNeighborsRegressor()))
models.append(('cart', DecisionTreeRegressor()))
models.append(('svm', SVR()))
return models

# define dataset
X, y = get_dataset()
# split dataset into train and test sets
X_train_full, X_test, y_train_full, y_test = train_test_split(X, y, test_size=0.5, random_state=1)
# summarize data split
print('Train: %s, Test: %s' % (X_train_full.shape, X_test.shape))
# create the base models
models = get_models()
# evaluate standalone model
for name, model in models:
# fit the model on the training dataset
model.fit(X_train_full, y_train_full)
# make a prediction on the test dataset
yhat = model.predict(X_test)
# evaluate the predictions
score = mean_absolute_error(y_test, yhat)
# report the score
print('>%s MAE: %.3f' % (name, score))
      
      





Ejecutar el ejemplo primero resume los conjuntos de entrenamiento y prueba y luego el MAE de cada modelo base en el conjunto de datos de prueba.



Nota: Sus resultados pueden variar debido a la naturaleza estocástica del algoritmo o procedimiento de estimación, o diferencias en la precisión numérica. Pruebe el ejemplo varias veces y compare el resultado promedio.



Aquí puede ver que, de hecho, el modelo de regresión lineal se desempeñó ligeramente mejor que el conjunto mixto, alcanzando un MAE de 0.236 versus 0.237. Esto puede tener que ver con cómo se construyó el conjunto de datos sintéticos.



Sin embargo, en este caso, preferiríamos utilizar un modelo de regresión lineal para exactamente esta tarea. Esta situación subraya la importancia de validar el desempeño de los modelos contribuyentes antes de aceptar el modelo de conjunto como final.



Train: (5000, 20), Test: (5000, 20)
>lr MAE: 0.236
>knn MAE: 100.169
>cart MAE: 133.744
>svm MAE: 138.195
      
      





Nuevamente, puede aplicar el conjunto mixto como modelo de regresión final. El enfoque implica dividir el conjunto de datos completo en conjuntos de entrenamiento y prueba para entrenar la línea de base y los metamodelos en ellos, respectivamente, luego el conjunto se puede usar para predecir una nueva fila de datos. A continuación se proporciona un ejemplo completo de predicción de nuevos datos utilizando un conjunto mixto para un problema de regresión.



# example of making a prediction with a blending ensemble for regression
from numpy import hstack
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.neighbors import KNeighborsRegressor
from sklearn.tree import DecisionTreeRegressor
from sklearn.svm import SVR

# get the dataset
def get_dataset():
X, y = make_regression(n_samples=10000, n_features=20, n_informative=10, noise=0.3, random_state=7)
return X, y

# get a list of base models
def get_models():
models = list()
models.append(('lr', LinearRegression()))
models.append(('knn', KNeighborsRegressor()))
models.append(('cart', DecisionTreeRegressor()))
models.append(('svm', SVR()))
return models

# fit the blending ensemble
def fit_ensemble(models, X_train, X_val, y_train, y_val):
# fit all models on the training set and predict on hold out set
meta_X = list()
for _, model in models:
# fit in training set
model.fit(X_train, y_train)
# predict on hold out set
yhat = model.predict(X_val)
# reshape predictions into a matrix with one column
yhat = yhat.reshape(len(yhat), 1)
# store predictions as input for blending
meta_X.append(yhat)
# create 2d array from predictions, each set is an input feature
meta_X = hstack(meta_X)
# define blending model
blender = LinearRegression()
# fit on predictions from base models
blender.fit(meta_X, y_val)
return blender

# make a prediction with the blending ensemble
def predict_ensemble(models, blender, X_test):
# make predictions with base models
meta_X = list()
for _, model in models:
# predict with base model
yhat = model.predict(X_test)
# reshape predictions into a matrix with one column
yhat = yhat.reshape(len(yhat), 1)
# store prediction
meta_X.append(yhat)
# create 2d array from predictions, each set is an input feature
meta_X = hstack(meta_X)
# predict
return blender.predict(meta_X)

# define dataset
X, y = get_dataset()
# split dataset set into train and validation sets
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.33, random_state=1)
# summarize data split
print('Train: %s, Val: %s' % (X_train.shape, X_val.shape))
# create the base models
models = get_models()
# train the blending ensemble
blender = fit_ensemble(models, X_train, X_val, y_train, y_val)
# make a prediction on a new row of data
row = [-0.24038754, 0.55423865, -0.48979221, 1.56074459, -1.16007611, 1.10049103, 1.18385406, -1.57344162, 0.97862519, -0.03166643, 1.77099821, 1.98645499, 0.86780193, 2.01534177, 2.51509494, -1.04609004, -0.19428148, -0.05967386, -2.67168985, 1.07182911]
yhat = predict_ensemble(models, blender, [row])
# summarize prediction
print('Predicted: %.3f' % (yhat[0]))
      
      





La ejecución del ejemplo entrena un modelo de conjunto en un conjunto de datos y luego lo usa para predecir una nueva fila de datos, como lo haría si usara el modelo en una aplicación.



Train: (6700, 20), Val: (3300, 20)
Predicted: 359.986
      
      





Esta sección contiene recursos sobre este tema si desea profundizar en él.














Y no se olvide del código de promoción HABR , que agrega un 10% al descuento del banner.



imagen






Artículos recomendados






All Articles