梯度提升的提前停止

梯度提升是一种集成技术,将几个弱学习者(回归树)组合在一起,以迭代的方式生成一个强大的单一模型。

梯度提升中的早期停止支持使我们能够找到最小的迭代次数,这足以建立一个可以很好地推广到未知数据的模型。

早期停止的概念很简单。我们指定了一个 validation_fraction ,它表示整个数据集的一小部分,该数据集将保留在训练之外,以评估模型的验证损失。梯度提升模型使用训练集进行训练,并使用验证集进行评估。当每个增加阶段增加上回归树时,将使用验证集对模型进行评分。这个过程将持续到在最后的 n_iter_no_change 阶段模型的评分没有提高至少 tol为止。在此之后,该模型被认为已经收敛,进一步增加的阶段是“提前停止”。

最终模型的提升数可在属性n_estimators_中获得。

这个例子说明了早期停止如何在sklearn.ensemble.GradientBoostingClassifier模型中被使用,与使用没有早期停止的估计器建立的模型相比,达到几乎相同的精度。这可以显著减少训练时间,内存使用和预测延迟。

# Authors: Vighnesh Birodkar <vighneshbirodkar@nyu.edu>
#          Raghav RV <rvraghav93@gmail.com>
# License: BSD 3 clause

import time

import numpy as np
import matplotlib.pyplot as plt

from sklearn import ensemble
from sklearn import datasets
from sklearn.model_selection import train_test_split

print(__doc__)

data_list = [datasets.load_iris(), datasets.load_digits()]
data_list = [(d.data, d.target) for d in data_list]
data_list += [datasets.make_hastie_10_2()]
names = ['Iris Data''Digits Data''Hastie Data']

n_gb = []
score_gb = []
time_gb = []
n_gbes = []
score_gbes = []
time_gbes = []

n_estimators = 500

for X, y in data_list:
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2,
                                                        random_state=0)

    # We specify that if the scores don't improve by atleast 0.01 for the last
    # 10 stages, stop fitting additional stages
    gbes = ensemble.GradientBoostingClassifier(n_estimators=n_estimators,
                                               validation_fraction=0.2,
                                               n_iter_no_change=5, tol=0.01,
                                               random_state=0)
    gb = ensemble.GradientBoostingClassifier(n_estimators=n_estimators,
                                             random_state=0)
    start = time.time()
    gb.fit(X_train, y_train)
    time_gb.append(time.time() - start)

    start = time.time()
    gbes.fit(X_train, y_train)
    time_gbes.append(time.time() - start)

    score_gb.append(gb.score(X_test, y_test))
    score_gbes.append(gbes.score(X_test, y_test))

    n_gb.append(gb.n_estimators_)
    n_gbes.append(gbes.n_estimators_)

bar_width = 0.2
n = len(data_list)
index = np.arange(0, n * bar_width, bar_width) * 2.5
index = index[0:n]

比较有无早期停止的得分

plt.figure(figsize=(95))

bar1 = plt.bar(index, score_gb, bar_width, label='Without early stopping',
               color='crimson')
bar2 = plt.bar(index + bar_width, score_gbes, bar_width,
               label='With early stopping', color='coral')

plt.xticks(index + bar_width, names)
plt.yticks(np.arange(01.30.1))


def autolabel(rects, n_estimators):
    """
    Attach a text label above each bar displaying n_estimators of each model
    """

    for i, rect in enumerate(rects):
        plt.text(rect.get_x() + rect.get_width() / 2.,
                 1.05 * rect.get_height(), 'n_est=%d' % n_estimators[i],
                 ha='center', va='bottom')


autolabel(bar1, n_gb)
autolabel(bar2, n_gbes)

plt.ylim([01.3])
plt.legend(loc='best')
plt.grid(True)

plt.xlabel('Datasets')
plt.ylabel('Test score')

plt.show()

比较有无早期停止的拟合时间

plt.figure(figsize=(95))

bar1 = plt.bar(index, time_gb, bar_width, label='Without early stopping',
               color='crimson')
bar2 = plt.bar(index + bar_width, time_gbes, bar_width,
               label='With early stopping', color='coral')

max_y = np.amax(np.maximum(time_gb, time_gbes))

plt.xticks(index + bar_width, names)
plt.yticks(np.linspace(01.3 * max_y, 13))

autolabel(bar1, n_gb)
autolabel(bar2, n_gbes)

plt.ylim([01.3 * max_y])
plt.legend(loc='best')
plt.grid(True)

plt.xlabel('Datasets')
plt.ylabel('Fit Time')

plt.show()

脚本的总运行时间:(1分10.353秒)

Download Python source code:plot_gradient_boosting_early_stopping.py

Download Jupyter notebook:plot_gradient_boosting_early_stopping.ipynb