Aprendizado de máquina: mixando conjunto em Python

Blending é um algoritmo de aprendizado de máquina de conjunto. Este é um nome coloquial para generalização empilhada [doravante usaremos o termo "empilhamento" em vez do termo "empilhamento" aceito em trabalhos científicos] ou o conjunto de embalagens, onde ao invés de treinar o metamodelo em previsões fora dos grupos feitos pelo modelo base, o modelo é treinado previsões feitas em um conjunto de dados independente.



A combinação foi usada para descrever modelos de lote que reuniram muitas centenas de modelos na competição de aprendizado de máquina da Netflix de US $ 1.000.000 e, como tal, a mistura continua sendo um método e nome popular para lote em concursos de aprendizado de máquina como Kaggle ... Especialmente para o início do novo thread do curso de Aprendizado de Máquina, estamos compartilhando um tutorial a partir do qual você aprenderá como desenvolver e avaliar um conjunto misto em python. Depois de concluir este tutorial, você saberá:



  • Conjuntos mistos são um tipo de empacotamento de modelo no qual o metamodelo é treinado usando previsões em um conjunto de dados de validação de teste independente em vez de previsões durante a validação cruzada k-fold.
  • Como desenvolver um conjunto misto, incluindo treinamento de modelo e funções de previsão com base em novos dados.
  • Como avaliar conjuntos mistos para problemas de modelagem de regressão preditiva e classificação.









Visão geral do tutorial



Este tutorial é dividido em quatro partes. Aqui estão eles:



  • Conjunto misto.
  • Criação de um conjunto misto.
  • Conjunto misto em um problema de classificação.
  • Conjunto misto em um problema de regressão.


Conjunto misto



Blending é uma técnica de aprendizado de máquina de conjunto que usa um modelo de aprendizado de máquina para descobrir a melhor forma de combinar previsões de vários modelos de membro de conjunto.



Portanto, misturar é o mesmo que generalização de empilhamento conhecida como empilhamento. A combinação e o lote são frequentemente usados ​​de forma intercambiável no mesmo artigo ou descrição do modelo.



Muitos profissionais de aprendizado de máquina obtiveram sucesso usando lotes e técnicas relacionadas para melhorar a precisão da previsão em qualquer um dos modelos individuais. Em alguns contextos, o lote também é chamado de mistura. Também trocaremos os termos aqui.

Empilhamento linear ponderado por recurso , 2009.


Uma arquitetura de modelo em lote contém dois ou mais modelos de linha de base, muitas vezes chamados de modelos de nível zero, e um metamodelo que combina as previsões do modelo de linha de base como um modelo de nível um. O metamodelo é treinado com base nas previsões feitas pelos modelos de base em dados fora da amostra.



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


No entanto, a mixagem tem certas conotações para a construção de um modelo de conjunto empacotado. A combinação pode oferecer o desenvolvimento de um conjunto de pilha, onde os modelos básicos são qualquer tipo de modelo de aprendizado de máquina, e o metamodelo é um modelo linear que "combina" as previsões dos modelos básicos. Por exemplo, um modelo de regressão linear ao prever um valor numérico, ou um modelo de regressão logística ao prever um rótulo de classe, calcula a soma ponderada das previsões feitas pelos modelos de base e será tratado como uma combinação de previsões.



  • Conjunto misto : use um modelo linear, como regressão linear ou regressão logística, como um metamodelo em um conjunto de modelos em lote.


Mistura foi um termo comumente usado para um conjunto de pacotes durante a competição de 2009 da Netflix. A competição envolveu equipes em busca de modelos preditivos com desempenho melhor do que o algoritmo nativo da Netflix, com um prêmio de US $ 1.000.000 concedido à equipe que alcançou uma melhoria de 10 por cento no desempenho.



Nossa solução com RMSE = 0,8643 ^ 2 é uma mistura linear de mais de 100 resultados. [...] Ao longo da descrição dos métodos, destacamos os preditores específicos que participaram da solução mista final.

A solução BellKor 2008 para o prêmio Netflix de 2008.


Assim, a mistura é o termo coloquial para aprendizagem de conjunto com uma arquitetura de modelo, como lote. Raramente, ou nunca, é usado em livros ou trabalhos acadêmicos, exceto aqueles relacionados ao aprendizado de máquina em competição. Mais comumente, o termo combinação é usado para descrever uma aplicação específica de envio em lote onde um metamodelo é treinado em previsões feitas por modelos de base com um conjunto de dados de validação independente. Nesse contexto, o empacotamento é reservado para o metamodelo treinado em previsões durante o procedimento de validação cruzada.



  • Combinação : um conjunto de tipo de lote em que o metamodelo é treinado em previsões feitas em um conjunto de dados independente.
  • Batching : Um conjunto do tipo batch onde o metamodelo é treinado nas previsões feitas durante a validação cruzada k-fold.


Essa distinção é comum na comunidade de competição de aprendizado de máquina Kaggle.



Mixagem é a palavra cunhada pelos vencedores da Netflix. Está muito próximo da generalização, mas um pouco mais simples e o risco de vazamento de informações é menor. [...] Ao misturar, em vez de gerar previsões durante a validação cruzada para o conjunto de treinamento, você cria um pequeno conjunto independente de, digamos, 10% do conjunto de treinamento. O modelo de lote é então treinado apenas neste pequeno conjunto.

Guia Kaggle Ensemble , MLWave, 2015.


Usamos a última definição de mistura. Vamos ver como isso é implementado.



Desenvolvimento de conjunto misto



A biblioteca scikit-learn não suportava mixagem pronta no momento em que este livro foi escrito. Mas podemos implementá-lo por conta própria usando modelos do scikit-learn. Primeiro, você precisa criar um conjunto de modelos básicos. Pode ser qualquer modelo que quisermos para um problema de regressão ou classificação. Podemos definir uma função get_models () que retorna uma lista de modelos, onde cada modelo é definido como uma tupla com um nome e um classificador personalizado ou objeto de regressão. Por exemplo, para um problema de classificação, poderíamos usar regressão logística, kNN, árvore de decisão, SVM e modelo Bayesiano ingênuo.



# 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
      
      





Em seguida, precisamos treinar o modelo de mixagem. Lembre-se de que os modelos básicos são treinados no conjunto de dados de treinamento. O metamodelo é treinado nas previsões feitas por cada modelo base em um conjunto de dados independente.



Primeiro, podemos percorrer os modelos em uma lista e treinar cada um por vez no conjunto de dados de treinamento. Além disso, neste ciclo, podemos usar um modelo treinado para fazer uma previsão em um conjunto de dados independente (validação) e armazenar previsões para o 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)
      
      





Agora temos um "meta_X *" representando a entrada que pode ser usada para treinar o metamodelo. Cada coluna ou objeto representa a saída de um modelo básico. Cada linha representa uma amostra de um conjunto de dados independente. Podemos usar a função hstack () para garantir que esse conjunto de dados seja uma matriz numpy bidimensional, conforme esperado pelo modelo de aprendizado de máquina.



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





Agora podemos treinar nosso metamodelo. Pode ser qualquer modelo de aprendizado de máquina que quisermos, como regressão logística para um problema de classificação.



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





Você pode agrupar tudo em uma função chamada fit_ensemble () que treina o modelo de combinação usando um conjunto de dados de treinamento e validação independente.



# 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
      
      





A próxima etapa é usar um conjunto de mixagem para prever novos dados. Este é um processo de duas etapas. A primeira etapa é usar cada modelo básico para previsões. As previsões são então colocadas juntas e usadas como entrada para o modelo de mixagem para fazer a previsão final.



Podemos usar o mesmo ciclo de treinamento do modelo. Ou seja, colete as previsões de cada modelo de base em um conjunto de dados de treinamento, adicione as previsões juntas e chame Predict () no modelo de mistura com esse conjunto de dados de nível de metal. Predict_ensemble () função abaixo implementa essas ações. Dado o treinamento de uma lista de modelos de base, o treinamento de um misturador de conjunto e um conjunto de dados (como um conjunto de dados de teste ou novos dados), para o conjunto de dados, ele retornará um conjunto de previsões.



# 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)
      
      





Agora temos todos os elementos necessários para implementar um conjunto misto para classificação ou problemas de modelagem de regressão preditiva.



Conjunto misto para problema de classificação



Nesta seção, veremos o uso de combinação para a tarefa de classificação. Primeiro, podemos usar a função make_classification () para criar um problema de classificação binária sintética com 10.000 exemplos e 20 recursos de entrada. O exemplo completo é mostrado abaixo.



# 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)
      
      





Executar o exemplo cria um conjunto de dados e resume as entradas e saídas.



(10000, 20) (10000,)
      
      





Em seguida, precisamos dividir o conjunto de dados em conjuntos de treinamento e teste primeiro e, em seguida, o conjunto de treinamento em um subconjunto usado para treinar os modelos básicos e um subconjunto usado para treinar o metamodelo. Nesse caso, usaremos uma divisão 50-50 para os conjuntos de treinamento e teste e, em seguida, uma divisão 67-33 para os conjuntos de treinamento e validação.



...
# 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))
      
      





Você pode então usar a função get_models () da seção anterior para criar os modelos de classificação usados ​​no conjunto. A função fit_ensemble () pode então ser chamada para treinar o conjunto misto nesses conjuntos de dados, e a função predict_ensemble () pode ser usada para fazer previsões em um conjunto de dados independente.



...
# 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 medir o desempenho do modelo de mistura relatando a precisão da classificação no conjunto de dados de teste.



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





Um exemplo completo de estimativa de um conjunto misto em um problema de classificação binária sintética é fornecido abaixo.



# 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))
      
      





Executar o exemplo primeiro relata um resumo de todos os conjuntos de dados e, em seguida, a precisão do conjunto no conjunto de dados de teste.



Nota: Seus resultados podem variar devido à natureza estocástica do algoritmo ou procedimento de estimativa, ou diferenças na precisão numérica. Considere executar o exemplo várias vezes e comparar a média.



Aqui vemos que o conjunto misto atingiu uma precisão de classificação de cerca de 97,900%.



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





No exemplo anterior, a previsão de rótulos de classe claros foi combinada usando um modelo de combinação. Este é um tipo de votação difícil . Uma alternativa é um método onde cada modelo prevê as probabilidades da classe e usa um metamodelo para misturar as probabilidades. Este é um tipo de voto suave que às vezes pode levar a um melhor desempenho. Primeiro, temos que configurar modelos que retornam probabilidades, como o 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
      
      





Em seguida, os modelos subjacentes precisam ser modificados para prever probabilidades em vez de rótulos de classe claros. Isso pode ser alcançado chamando predict_proba () dentro de fit_ensemble () enquanto treina os modelos subjacentes.



...
# 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)
      
      





Isso significa que o meta-conjunto de dados usado para treinar o metamodelo terá n colunas por classificador, onde n é o número de classes no problema de previsão, no nosso caso existem duas classes. Também precisamos alterar as previsões feitas pelos modelos de base ao usar o modelo de mistura para prever novos dados.



...
# 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)
      
      





Todo o exemplo de uso da combinação de probabilidades de classe previstas para um problema de classificação binária sintética é fornecido abaixo.




# 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))
      
      





Executar o exemplo primeiro relata um resumo de todos os conjuntos de dados e, em seguida, a precisão do conjunto no conjunto de teste.



Nota: Seus resultados podem variar devido à natureza estocástica do algoritmo ou procedimento de estimativa, ou diferenças na precisão numérica. Experimente o exemplo várias vezes e compare o resultado médio.



Aqui vemos que a mistura das probabilidades de classe levou a um aumento na precisão da classificação em cerca de 98,240%.



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





Um conjunto misto só é eficaz se for capaz de superar qualquer um dos modelos individuais nele. Podemos confirmar isso avaliando cada um dos modelos básicos separadamente. Cada modelo de linha de base pode ser treinado em todo o conjunto de dados de treinamento (em oposição ao conjunto de mixagem) e avaliado no conjunto de dados de teste (assim como no conjunto de mixagem). O exemplo abaixo demonstra isso avaliando cada modelo de linha 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))
      
      







Executar o exemplo primeiro relata um resumo de todos os três conjuntos de dados e, em seguida, a precisão de cada modelo base no conjunto de teste.



Nota: Seus resultados podem ser diferentes devido à natureza estocástica do algoritmo, ou ao procedimento de estimativa, ou diferenças na precisão numérica. Experimente o exemplo várias vezes e compare o resultado médio.



Neste caso, vemos que todos os modelos têm desempenho pior do que o conjunto misto. O interessante é que podemos ver que o SVM está muito perto de atingir 98.200% de precisão, em comparação com 98.240% de precisão alcançada com o conjunto misto.



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 escolher um conjunto misto como nosso modelo final. Isso inclui treinar o conjunto em todo o conjunto de dados de treinamento e fazer previsões usando novos exemplos. Em particular, todo o conjunto de treinamento é dividido em conjuntos de treinamento e validação para treinar a base e os metamodelos, respectivamente, e então o conjunto pode ser usado na previsão. Um exemplo completo de previsão de novos dados usando um conjunto misto para classificação se parece com este:



# 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))
      
      





A execução do exemplo treina um modelo de conjunto misto em um conjunto de dados e, em seguida, o usa para prever uma nova linha de dados, como faria se estivesse usando o modelo em um aplicativo.



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





Vamos ver como podemos avaliar o conjunto misto para regressão.



Conjunto misto para problema de regressão



Nesta seção, veremos o uso de lotes para um problema de regressão. Primeiro, podemos usar a função make_regression () para criar um problema de regressão sintética com 10.000 amostras e 20 recursos de entrada. O exemplo completo é mostrado abaixo.



# 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)
      
      





Executar o exemplo cria um conjunto de dados e resume os componentes de entrada e saída.



(10000, 20) (10000,)
      
      





Em seguida, você pode definir uma lista de modelos de regressão para usar como linha de base. Nesse caso, usamos modelos de regressão linear, kNN, árvore de decisão e 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
      
      





A função fit_ensemble () usada para treinar o conjunto não muda, exceto que o modelo usado para mixagem deve ser alterado para regressão. Aqui usamos um modelo de regressão linear.



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





Por se tratar de um problema de regressão, avaliaremos o desempenho do modelo utilizando a métrica do erro, neste caso o erro médio absoluto, ou (abreviado) MAE.



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





Todo o exemplo de um conjunto misto para um problema de modelagem preditiva de regressão sintética é dado abaixo:



# 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)
      
      





O exemplo primeiro imprime um resumo dos três conjuntos de dados e, em seguida, o MAE no conjunto de teste.



Nota: Seus resultados podem variar devido à natureza estocástica do algoritmo ou procedimento de estimativa, ou diferenças na precisão numérica. Experimente o exemplo várias vezes e compare o resultado médio.



Aqui vemos que o conjunto atingiu um MAE de cerca de 0,237 no conjunto de dados de teste.



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





Tal como acontece com a classificação, um conjunto misto só é útil se tiver um desempenho melhor do que qualquer um dos modelos de conjunto básico.



Podemos testar isso avaliando cada modelo de linha de base isoladamente, primeiro treinando-o em todo o conjunto de treinamento (em oposição a um conjunto) e fazendo previsões no conjunto de dados de teste (como em um conjunto). No exemplo abaixo, cada um dos modelos de linha de base é estimado isoladamente em relação a um conjunto de dados de modelagem de regressão preditiva 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))
      
      





Executar o exemplo primeiro resume os conjuntos de treinamento e teste e, em seguida, o MAE de cada modelo base no conjunto de dados de teste.



Nota: Seus resultados podem variar devido à natureza estocástica do algoritmo ou procedimento de estimativa, ou diferenças na precisão numérica. Experimente o exemplo várias vezes e compare o resultado médio.



Aqui você pode ver que, de fato, o modelo de regressão linear teve um desempenho ligeiramente melhor do que o conjunto misto, atingindo um MAE de 0,236 em comparação com 0,237. Isso pode ter a ver com a forma como o conjunto de dados sintético foi construído.



No entanto, neste caso, preferiríamos usar um modelo de regressão linear exatamente para essa tarefa. Essa situação ressalta a importância de validar o desempenho dos modelos contribuintes antes de aceitar o 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
      
      





Novamente, você pode aplicar o conjunto misto como o modelo de regressão final. A abordagem envolve a divisão de todo o conjunto de dados em conjuntos de treinamento e teste para treinar a linha de base e os metamodelos neles, respectivamente, e então o conjunto pode ser usado para prever uma nova linha de dados. Um exemplo completo de previsão de novos dados usando um conjunto misto para um problema de regressão é fornecido abaixo.



# 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]))
      
      





A execução do exemplo treina um modelo de conjunto em um conjunto de dados e, em seguida, o usa para prever uma nova linha de dados, como faria se estivesse usando o modelo em um aplicativo.



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





Esta seção contém recursos sobre este tópico se você quiser se aprofundar nele.


  • Stacking Ensemble Machine Learning With Python
  • How to Implement Stacked Generalization (Stacking) From Scratch With Python




  • Feature-Weighted Linear Stacking, 2009.
  • The BellKor 2008 Solution to the Netflix Prize, 2008.
  • Kaggle Ensemble Guide, MLWave, 2015.




  • Netflix, Wikipedia.




E não se esqueça do código promocional HABR , que acrescenta 10% ao desconto no banner.



imagem


  • Curso de Aprendizado de Máquina
  • Curso avançado "Machine Learning Pro + Deep Learning"
  • Curso "Matemática e Aprendizado de Máquina para Ciência de Dados"


Mais cursos
  • Data Science
  • Data Analyst
  • «Python -»
  • Unity
  • JavaScript
  • -
  • Java-
  • C++
  • DevOps
  • iOS-
  • Android-




Artigos recomendados






All Articles