作者:Jason Brownlee
翻译:王可汗
校对:wwl
本文约7000字,建议阅读16分钟
本文为大家展示了如何在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)
运行该示例将创建数据集并总结输入和输出的维度。
|
接下来,我们需要将数据集分解,首先分解为训练集和测试集,然后将训练集分解为用于训练基本模型的子集和用于训练元模型的子集。
在本例中,我们将对训练和测试集使用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.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))
运行示例会在数据集上训练混合集成模型,然后用于对新数据行进行预测,就像我们在应用程序中使用该模型时所做的那样。
-
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中开发和评估混合集成。
具体来说,你学会了:
混合集成是一种叠加,在这种叠加中,元模型是通过对一个未完成的验证数据集的预测而不是过时的预测来拟合的。
如何开发一个混合集成,包括训练模型和对新数据进行预测的功能。
如何评价混合集成为分类和回归预测建模问题。
原文标题:
Blending Ensemble Machine Learning With Python
原文链接:
https://machinelearningmastery.com/blending-ensemble-machine-learning-with-python/
编辑:王菁
校对:汪雨晴
译者简介
王可汗,清华大学机械工程系直博生在读。曾经有着物理专业的知识背景,研究生期间对数据科学产生浓厚兴趣,对机器学习AI充满好奇。期待着在科研道路上,人工智能与机械工程、计算物理碰撞出别样的火花。希望结交朋友分享更多数据科学的故事,用数据科学的思维看待世界。
翻译组招募信息
工作内容:需要一颗细致的心,将选取好的外文文章翻译成流畅的中文。如果你是数据科学/统计学/计算机类的留学生,或在海外从事相关工作,或对自己外语水平有信心的朋友欢迎加入翻译小组。
你能得到:定期的翻译培训提高志愿者的翻译水平,提高对于数据科学前沿的认知,海外的朋友可以和国内技术应用发展保持联系,THU数据派产学研的背景为志愿者带来好的发展机遇。
其他福利:来自于名企的数据科学工作者,北大清华以及海外等名校学生他们都将成为你在翻译小组的伙伴。
点击文末“阅读原文”加入数据派团队~
转载须知
如需转载,请在开篇显著位置注明作者和出处(转自:数据派ID:DatapiTHU),并在文章结尾放置数据派醒目二维码。有原创标识文章,请发送【文章名称-待授权公众号名称及ID】至联系邮箱,申请白名单授权并按要求编辑。
发布后请将链接反馈至联系邮箱(见下方)。未经许可的转载以及改编者,我们将依法追究其法律责任。
点击“阅读原文”拥抱组织
转载:https://blog.csdn.net/tMb8Z9Vdm66wH68VX1/article/details/112790958