为什么 LightGBM Python-package 给出错误的预测用于回归任务?

Why LightGBM Python-package gives bad prediction using for regression task?

我有一个样本时间序列 dataset (23, 208), which is a pivot table count for 24hrs count for some users; I was experimenting with different regressors from sklearn which work fine (except for SGDRegressor()), but this LightGBM Python-package 给我非常线性的预测如下:

我试过的代码:

import pandas as pd
dff = pd.read_csv('ex_data2.csv',sep=',')
dff.set_index("timestamp",inplace=True)
print(dff.shape)


from sklearn.model_selection import train_test_split
trainingSetf, testSetf = train_test_split(dff,
                                        #target_attribute, 
                                        test_size=0.2,
                                        random_state=42,
                                        #stratify=y,
                                        shuffle=False)


import lightgbm as lgb
from sklearn.multioutput import MultiOutputRegressor

username = 'MMC_HEC_LVP' # select one column for plotting & check regression performance
user_list = []

for column in dff.columns:
  user_list.append(column)


index = user_list.index(username)

X_trainf = trainingSetf.iloc[:,:].values
y_trainf = trainingSetf.iloc[:,:].values

X_testf = testSetf.iloc[:,:].values
y_testf = testSetf.iloc[:,:].values
test_set_copy = y_testf.copy()

model_LGBMRegressor = MultiOutputRegressor(lgb.LGBMRegressor()).fit(X_trainf, y_trainf)
pred_LGBMRegressor = model_LGBMRegressor.predict(X_testf)

test_set_copy[:,[index]] = pred_LGBMRegressor[:,[index]]

#plot the results for selected user/column 
import matplotlib.pyplot as plt
plt.style.use("fivethirtyeight")

plt.figure(figsize=(12, 10))

plt.xlabel("Date")
plt.ylabel("Values")
plt.title(f"{username} Plot")

plt.plot(trainingSetf.iloc[:,[index]],label='trainingSet')
plt.plot(testSetf.iloc[:,[index]],"--",label='testSet')
plt.plot(test_set_copy[:,[index]],'b--',label='RF_predict')
plt.legend()

所以我缺少的是如果我使用默认(超)参数?

简答

您的数据集的行数非常少,LightGBM 的参数设置了默认值以在 medium-sized 数据集上提供良好的性能。

设置以下参数以强制 LightGBM 适应提供的数据。

长答案

在训练之前,LightGBM 对输入数据做了一些pre-processing。

例如:

  • 捆绑稀疏特征
  • 将连续特征合并到直方图中
  • 删除保证没有信息的特征(例如,不变的特征)

该预处理的结果是一个 LightGBM Dataset 对象,运行 该预处理称为 Dataset“构造”。 LightGBM 对此 Dataset 对象执行提升,而不是像 numpy 数组或 pandas 数据帧这样的原始数据。

为了加快构建速度并防止训练过程中的过度拟合,LightGBM 提供了防止创建太小的直方图箱 (min_data_in_bin) 或产生与太少记录匹配的叶节点的拆分 (min_data_in_leaf).

在小型数据集上进行训练可能需要将这些参数设置为非常低的值。

我创建了以下 minimal, reproducible example,使用 Python 3.8.12、lightgbm==3.3.2numpy==1.22.2scikit-learn==1.0.2 演示了此行为。

from lightgbm import LGBMRegressor
from sklearn.metrics import r2_score
from sklearn.datasets import make_regression

# 20-row input data
X, y = make_regression(
    n_samples=20,
    n_informative=5,
    n_features=5,
    random_state=708
)

# training produces 0 trees, and predicts mean(y)
reg = LGBMRegressor(
    num_boost_round=20,
    verbosity=0
)
reg.fit(X, y)
print(f"r2 (defaults): {r2_score(y, reg.predict(X))}")
# 0.000

# training fits and predicts well
reg = LGBMRegressor(
    min_data_in_bin=1,
    min_data_in_leaf=1,
    num_boost_round=20,
    verbosity=0
)
reg.fit(X, y)
print(f"r2 (small min_data): {r2_score(y, reg.predict(X))}")
# 0.985

如果您在原始 post 的代码中使用 LGBMRegressor(min_data_in_bin=1, min_data_in_leaf=1),您将看到更适合所提供数据的预测。