在循环中拟合 Ensemble Regressor 会生成重复值

Fitting Ensemble Regressor within a loop generates repeat values

我正在尝试使用集成回归器根据几个 material 测量值来预测产量。我的数据是年度数据,可以追溯到 1965 年。(一些细节被删除并使用了随机数据,因为这是一个使用敏感数据的工作项目。)

我已将我的代码精简到最低限度,但我仍然看到问题:

import pandas as pd
import numpy as np

from sklearn.ensemble import GradientBoostingRegressor, RandomForestRegressor
from xgboost.sklearn import XGBRegressor

X_past = pd.DataFrame(index = range(1965, 2020), data = dict(
    A = np.random.randint(4170, 19091, size = 55),
    B = np.random.randint(74, 337, size = 55)
))

X_future = pd.DataFrame(index = range(2020, 2023), data = dict(
    A = np.random.randint(4170, 19091, size = 3),
    B = np.random.randint(74, 337, size = 3)
))

y_past = pd.DataFrame(index = range(1965, 2020), data = dict(
    C = np.random.randint(12163, 42580, size = 55)
))

predictions = None
predictions = pd.DataFrame()

i = 0

while i < 10:
    i += 1
    
    reg = None
    y_pred = None
    
    X = X_past.values
    y = y_past.values.ravel()

    #reg = RandomForestRegressor(n_estimators = 300)
    reg = GradientBoostingRegressor(n_estimators = 300)
    #reg = XGBRegressor(n_estimators = 640, silent = True)

    reg.fit(X, y)

    y_pred = reg.predict(np.array(X_future))
    predictions = predictions.append(pd.Series(y_pred), ignore_index = True,)
    

predictions.columns = [2020, 2021, 2022]
predictions['Row-wise Duplicates'] = (predictions[2021] == predictions[2022])

predictions

产生的结果如下:

2020 2021 2022 Row-wise Duplicates
13211.008045 29624.483861 34110.523735 False
13211.008045 29624.483861 33462.196606 False
13211.008045 29624.483861 33867.781932 False
13211.008045 29624.483861 33999.203849 False
13211.008045 29624.483861 33947.950436 False
13211.008045 29624.483861 33550.338744 False
13211.008045 29624.483861 34079.297200 False
13211.008045 29624.483861 33924.349324 False
13211.008045 29624.483861 33195.847833 False
13211.008045 29624.483861 33922.391200 False

如您所见,尽管每次迭代都重新拟合,但我看到了很多重复值。

我有时也会看到这些年来重复的值(通常是 2021 年与 2022 年匹配,这就是我计算“按行重复”列的原因):

2020 2021 2022 Row-wise Duplicates
40819.929316 40819.929316 40819.929316 True
41516.312213 41516.312213 41516.312213 True
41516.312213 41516.312213 41516.312213 True
40901.743937 40901.743937 40901.743937 True
41191.025907 41191.025907 41191.025907 True
41109.211286 41109.211286 41109.211286 True
40910.834451 40910.834451 40910.834451 True
41799.581630 41799.581630 41799.581630 True
42512.531092 42512.531092 42512.531092 True
41018.306151 41018.306151 41018.306151 True

我做错了什么?为什么我会看到这样的重复项?我该如何解决?

您使用的算法和您使用的参数没有随机的内部元素。因此,给它相同的训练集和相同的测试集(就像您在代码中所做的那样)将产生相同的结果。

您可以使用值小于 1subsample 参数,使其使用不同的随机子样本来训练每个基础学习器(参见文档 https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.GradientBoostingRegressor.html

所以,如果你用这行替换你的行:

reg = GradientBoostingRegressor(n_estimators = 300, subsample = 0.9)

该算法将使用您数据的 90% 的随机子集来训练每个学习器,您将在每次调用中得到不同的结果。如果将它与 random_state 参数结合使用,您仍然可以使结果可重现。