查看原文
其他

利用 Python 的混合集成机器学习

Jason Brownlee 大数据与机器学习文摘 2021-08-08

(点击上方公众号,可快速关注)

转自:数据派THU

本文为大家展示了如何在python中开发和评估混合集成学习,以及如何用于分类和回归问题当中。

混合是一种基于集成学习的机器学习算法。

它是堆叠或堆叠集成的口语化名称,在这种情况下,元模型不是根据基本模型做出的对折外数据的预测来拟合,而是根据对保留的样本数据集做出的预测来拟合。

在价值100万美元的Netflix机器学习竞赛中,“混合”被用来描述由竞争对手将数百个预测模型组合在一起的堆叠模型并且在竞争激烈的机器学习圈,比如Kaggle社区,仍然是一种流行的技术和名称。

在本教程中,您将了解如何在python中开发和评估混合集成学习。

完成本教程后,您将知道:

  • 混合集成是一种叠加,在这种叠加中,元模型是通过对一个保留验证数据集的预测而不是折外数据集的预测来拟合的。

  • 如何开发一个混合集成,包括训练模型和对新数据进行预测的功能。

  • 如何评价用于分类和回归预测建模问题的混合集成。

让我们开始吧。

教程概述

本教程分为四个部分,它们是:

  • 混合集成

  • 开发混合集成

  • 用于分类的混合集成

  • 用于回归的混合集成

混合集成

混合是一种集成机器学习技术,它使用一个机器学习模型来学习如何最好地结合来自多个成员模型的预测。

广义来说,就其本身而言,混合和堆叠泛化(即叠加)是一样的。在同一篇论文或模型描述中,混合和叠加通常是交替使用的。

“许多机器学习实践者已经成功地使用叠加和相关技术来提高预测精度,超过任何单个模型所获得的水平。在某些情况下,堆叠也被称为混合,在这里我们将交替使用这两个术语。”

特征加权线性叠加,2009年。

堆叠模型的体系结构包括两个或多个基本模型(通常称为0级模型)和一个元模型(它结合了基本模型的预测,称为1级模型)。元模型是根据基本模型对样本外数据的预测来训练的。

  • 0级模型(基础模型):基于训练数据训练模型用来进行预测。

  • 1级模型(元模型):学习如何最好地结合基本模型的预测的模型。

然而,混合对于如何构建堆叠集成模型具有特定的内涵。

混合可能建议开发一个堆叠的集成学习模型,其中基础模型是任何类型的机器学习模型,元模型是一个“混合”基础模型的线性模型。

例如,预测数值时的线性回归模型或预测类标签时的逻辑回归模型将计算基本模型所作预测的加权和,并将被认为是预测的混合。

  • 混合集成:使用线性模型,如线性回归或逻辑回归,作为叠加集成中的元模型。

在2009年的Netflix奖金比赛中“混合”是描述堆叠集成的术语。该奖项包括寻求比Netflix原生算法更好的电影推荐预测的团队,性能提高10%的团队将获得100万美元的奖金。

“我们的RMSE=0.8643^2解是100多个结果的线性混合.……在对方法的描述中,我们强调了参与最终混合解决方案的特定预测器。”

- 2008年Netflix大奖的BellKor解决方案

因此,混合是一个通俗的术语,指的是带有堆栈类型架构模型的集成学习。除了与竞争机器学习相关的内容外,很少在教科书或学术论文中使用它。

最常见的是,混合(blending)被用来描述堆叠的特定应用,在这种情况下,元模型是根据一个固定的验证数据集上的基础模型所做出的预测来训练的。堆叠(stacking)则被保留给元模型,在交叉验证过程中根据折外预测进行训练的场景。

  • 混合(blending):堆叠类型的集成,其中元模型是根据对保留的验证数据集的预测进行训练的。

  • 堆叠(stacking):堆叠式集成,在k-fold交叉验证过程中,元模型根据折外预测进行训练。

这种区别在Kaggle竞争机器学习社区中很常见。

“Blend(混合)这个词是由Netflix的获胜者们提出的。它非常接近堆叠泛化,但更简单,信息泄漏的风险更小。…使用混合,而不是为训练集创建折外数据集预测,您创建一个小的保留数据集,比如10%的训练集。然后堆叠模型只在这个保留集合上运行。”

-《Kaggle Ensemble Guide》,MLWave, 2015。

我们将使用后一个混合的定义。

接下来,让我们看看如何实现混合。

开发混合集成

在编写时,scikit-learn库并不天生支持混合。但,我们可以使用scikit-lern模型自己实现它。

首先,我们需要创建一些基本模型。对于回归或分类问题,这些模型可以是我们喜欢的任何模型。我们可以定义一个函数get_models(),它返回一个模型列表,其中每个模型被定义为一个具有名称和配置的分类器或回归器的元组。

例如,对于一个分类问题,我们可以使用逻辑回归、kNN、决策树、支持向量机和朴素贝叶斯模型。

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

我们现在有了表示可用于训练元模型的输入数据的“meta_X”。每一列或特性代表一个基本模型的输出。

每一行表示来自保留数据集的一个示例。我们可以使用hstack()函数来确保这个数据集像机器学习模型所期望的那样是一个2D numpy数组。

...

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

我们可以将所有这些整合接到一个名为fit_ensemble()的函数中,该函数使用一个训练数据集和一个验证数据集训练混合模型。

下一步是使用混合集成对新数据进行预测。这是一个两步的过程。第一步是使用每个基础模型进行预测。然后将这些预测收集在一起,作为混合模型的输入来做出最终的预测。我们可以使用与训练模型时相同的循环结构。也就是说,我们可以将每个基本模型的预测收集到训练数据集中,将预测堆叠在一起,并使用这个元级别数据集在blender模型上调用predict()。下面的predict_ensemble()函数实现了这一点。

# 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

给定训练的基础模型列表、训练的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)

现在,我们已经拥有了实现分类或回归预测建模问题的混合集成所需的所有元素。

用于分类的混合集成

在本节中,我们将研究如何使用混合来解决分类问题。

首先,我们可以使用make_classification()函数创建一个包含10,000个示例和20个输入特性的二进制分类问题。

下面列出了完整的示例。

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

运行该示例将创建数据集并总结输入和输出的维度。


(10000, 20) (10000,)

接下来,我们需要将数据集分解,首先分解为训练集和测试集,然后将训练集分解为用于训练基本模型的子集和用于训练元模型的子集。

在本例中,我们将对训练和测试集使用50-50分割,然后对训练和验证集使用67-33分割

...

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

然后,我们可以使用上一节中的get_models()函数来创建集成中使用的分类模型。

然后可以调用fit_ensemble()函数来在训练和验证数据集上训练混合集成,而predict_ensemble()函数可以用于对保留数据集进行预测。

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

将这些整合在一起,下面列出了在二分类问题上评估混合集成的完整例子。



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

运行示例首先报告训练、验证和测试数据集的尺寸,然后是测试数据集上集成的MAE。

注:由于算法或计算过程的随机性,或数值精度的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。

在这种情况下,我们可以看到将分类准确率提升到了98.240%。

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

在前面的例子中,crisp类标签的预测使用混合模型进行组合。这是一种硬投票。

另一种方法是让每个模型预测类概率,然后使用元模型混合概率。这是一种软投票,在某些情况下可以获得更好的性能。

首先,我们必须配置模型来返回概率,比如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

接下来,我们必须改变基础模型来预测概率,而不是清晰的类标签。

这可以通过在拟合基本模型时调用fit_ensemble()函数中的predict_proba()函数来实现。

...

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

这意味着用于训练元模型的元数据集每个分类器将有n列,其中n是预测问题中类的数量,在我们的例子中是两个。

在使用混合模型对新数据进行预测时,还需要改变基础模型的预测。

...

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

将这些结合在一起,下面列出了在二分类问题中对预测类概率使用混合的完整例子。



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

运行示例首先报告训练、验证和测试数据集的形状,然后报告测试数据集上集成的准确性。

注:由于算法或计算过程的随机性,或数值精度的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。

在这种情况下,我们可以看到混合类概率将分类准确率提升到了98.240%。

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

混合集成只有在其性能优于任何单一贡献模型时才是有效的。

我们可以通过单独评估每个基本模型来确认这一点。每个基本模型都可以适合整个训练数据集(与混合集成不同),并在测试数据集上进行评估(就像混合集成一样)。

下面的示例演示了这一点,分别评估每个基本模型。

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

运行示例首先报告完整的训练和测试数据集的形状,然后报告测试数据集上每个基本模型的准确性。

注:由于算法或计算过程的随机性,或数值精度的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。

在这种情况下,我们可以看到所有模型的表现都比混合集成差。

有趣的是,我们可以看到SVM的准确率接近于98.200%,而混合集成的准确率为98.240 %。

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

我们可以选择使用混合集合作为我们的最终模型。

这包括将集合与整个训练数据集相匹配,并对新的例子进行预测。具体来说,将整个训练数据集分割成训练集和验证集,分别训练基模型和元模型,然后使用集成进行预测。

下面是用混合集成对新数据进行分类预测的完整例子。

# 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.303350112.680663142.077942811.15253537-2.0583897-2.519366010.67513028-3.20651939-1.603453853.688207140.053709131.358044330.420113971.47328392.899976221.611193997.72630965-2.84089477-1.839774151.34381989]
yhat = predict_ensemble(models, blender, [row])
# summarize prediction
print('Predicted Class: %d' % (yhat))

运行示例会在数据集上训练混合集成模型,然后用于对新数据行进行预测,就像我们在应用程序中使用该模型时所做的那样。

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

接下来,让我们探讨如何评估用于回归的混合集成。

用于回归的混合集成

在这一节中,我们将研究如何使用堆叠来处理一个回归问题。

首先,我们可以使用make_regression()函数来创建一个包含10,000个示例和20个输入特性的综合回归问题。

下面列出了完整的示例。

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

运行该示例将创建数据集并总结输入和输出的形状。

接下来,我们可以定义作为基础模型的回归模型列表。在本例中,我们将使用线性回归、kNN、决策树和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

用于训练混合集成的fit_ensemble()函数与分类无关,只是用于混合的模型必须改为回归模型。

在这个例子中,我们将使用线性回归模型。

...

# define blending model
blender = LinearRegression()

基于这是一个回归问题,我们将使用一个误差度量来评估模型的性能,在这种情况下,平均绝对误差,或简称MAE。

...

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

把这些结合在一起,下面列出了用于合成回归预测建模问题的混合集成的完整示例。



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

运行示例首先报告训练、验证和测试数据集的形状,然后是测试数据集上集成的MAE。

注:由于算法或计算过程的随机性,或数值精度的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。

在这种情况下,我们可以看到混合集成在测试数据集上获得了约0.237的MAE。

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

与分类一样,混合集成只有在其性能优于任何有助于集成的基础模型时才有用。

我们可以通过单独评估每个基础模型来检查这一点,首先在整个训练数据集上拟合它(不像混合集成),然后在测试数据集上做出预测(和混合集成一样)。

下面的示例对合成回归预测建模数据集上的每个基本模型进行单独评估。



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

运行示例首先报告完整的训练和测试数据集的形状,然后报告每个基本模型在测试数据集上的MAE。注:由于算法或计算过程的随机性,或数值精度的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。在这种情况下,我们可以看到线性回归模型确实比混合集成略好一些,相对于集成的0.237,MAE达到了0.236。这可能与构建合成数据集的方式有关。但是,在这种情况下,我们会选择直接使用线性回归模型来解决这个问题。这突出了在采用集成模型作为最终模型之前检查贡献模型的表现的重要性。

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

同样,我们可以选择使用混合集成作为回归的最终模型。

这涉及到拟合将整个数据集分解为训练集和验证集,分别适合基础模型和元模型,然后集成可以用于对新数据行进行预测。

下面列出了使用混合集成进行回归对新数据进行预测的完整示例。

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

运行示例会在数据集上训练混合集成模型,然后用于对新数据行进行预测,就像我们在应用程序中使用该模型时所做的那样。

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

延伸阅读

如果您想深入了解这个主题,本节提供了更多相关资源。

相关教程

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 Prize, Wikipedia.

总结

在本教程中,您了解了如何在python中开发和评估混合集成。

具体来说,你学会了:

混合集成是一种叠加,在这种叠加中,元模型是通过对一个未完成的验证数据集的预测而不是过时的预测来拟合的。

如何开发一个混合集成,包括训练模型和对新数据进行预测的功能。

如何评价混合集成为分类和回归预测建模问题。



- EOF -


推荐阅读  点击标题可跳转

1、Python 正则表达式大全

2、22 个常用的 Python 工具包

3、Python 和 R 哪个更适合机器学习?两者结合,双倍快乐


看完本文有收获?请转发分享给更多人

关注「大数据与机器学习文摘」,成为Top 1%

点赞和在看就是最大的支持❤️

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存