推薦 :利用Python的混合集成機器學習(附鏈接)

作者: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)

運行該示例將創建數據集並總結輸入和輸出的維度。


(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.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充滿好奇。期待着在科研道路上,人工智能與機械工程、計算物理碰撞出別樣的火花。希望結交朋友分享更多數據科學的故事,用數據科學的思維看待世界。

END

版權聲明:本號內容部分來自互聯網,轉載請註明原文鏈接和作者,如有侵權或出處有誤請和我們聯繫。


合作請加QQ:365242293  

數據分析(ID : ecshujufenxi )互聯網科技與數據圈自己的微信,也是WeMedia自媒體聯盟成員之一,WeMedia聯盟覆蓋5000萬人羣。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章