• 第82步 时间序列建模实战:LightGBM回归建模


    基于WIN10的64位系统演示

    一、写在前面

    这一期,我们介绍LightGBM回归

    同样,这里使用这个数据:

    《PLoS One》2015年一篇题目为《Comparison of Two Hybrid Models for Forecasting the Incidence of Hemorrhagic Fever with Renal Syndrome in Jiangsu Province, China》文章的公开数据做演示。数据为江苏省2004年1月至2012年12月肾综合症出血热月发病率。运用2004年1月至2011年12月的数据预测2012年12个月的发病率数据。

    二、LightGMB回归

    (1)参数解读

    LightGBM 可以处理分类和回归任务,大多数参数在这两种任务之间是通用的,但也有一些参数是特定于任务类型的。下面是这两种任务在参数设置方面的异同:

    (a)相同之处:

    核心参数:如 boosting_type、num_boost_round、learning_rate 等。

    学习控制参数:这些控制决策树的结构和拟合方式。例如,max_depth, num_leaves, min_data_in_leaf, feature_fraction, bagging_fraction, lambda_l1, lambda_l2 等。

    IO 参数:控制输入输出的参数,如 max_bin 和 min_data_in_bin。

    其他参数:如 verbosity, boost_from_average 等。

    (b)不同之处:

    目标函数 (objective 或 application 参数):

    分类:可以选择 binary(二分类)或者 multiclass(多分类)。对于多分类还有一个参数 num_class 来指定类别数。

    回归:通常选择 regression。还有其他的回归目标如 regression_l1,huber,fair,等。

    (c)度量指标 (metric 参数):

    分类:例如 binary_logloss, binary_error, multi_logloss, multi_error 等。

    回归:例如 l2 (MSE), l1 (MAE), mape 等。

    (d)类别权重 (class_weight 参数):

    分类:当数据集的类别不均衡时,可以使用这个参数为各个类别设置不同的权重。

    回归:这个参数通常不适用。

    (e)其他特定参数:

    分类:例如,scale_pos_weight 可以用于处理非常不平衡的二分类问题。

    回归:通常不需要这些特定的参数。

    综上所述,尽管分类和回归任务在 LightGBM 的参数上有很多相似之处,但它们的目标函数和评价标准是不同的,需要根据具体任务来进行调整。

    (2)单步滚动预测

    1. import pandas as pd
    2. import numpy as np
    3. from sklearn.metrics import mean_absolute_error, mean_squared_error
    4. from lightgbm import LGBMRegressor
    5. from sklearn.model_selection import GridSearchCV
    6. # 读取数据
    7. data = pd.read_csv('data.csv')
    8. # 将时间列转换为日期格式
    9. data['time'] = pd.to_datetime(data['time'], format='%b-%y')
    10. # 创建滞后期特征
    11. lag_period = 6
    12. for i in range(lag_period, 0, -1):
    13. data[f'lag_{i}'] = data['incidence'].shift(lag_period - i + 1)
    14. # 删除包含 NaN 的行
    15. data = data.dropna().reset_index(drop=True)
    16. # 划分训练集和验证集
    17. train_data = data[(data['time'] >= '2004-01-01') & (data['time'] <= '2011-12-31')]
    18. validation_data = data[(data['time'] >= '2012-01-01') & (data['time'] <= '2012-12-31')]
    19. # 定义特征和目标变量
    20. X_train = train_data[['lag_1', 'lag_2', 'lag_3', 'lag_4', 'lag_5', 'lag_6']]
    21. y_train = train_data['incidence']
    22. X_validation = validation_data[['lag_1', 'lag_2', 'lag_3', 'lag_4', 'lag_5', 'lag_6']]
    23. y_validation = validation_data['incidence']
    24. # 初始化 LGBMRegressor 模型
    25. lgbm_model = LGBMRegressor()
    26. # 定义参数网格
    27. param_grid = {
    28. 'n_estimators': [50, 100, 150],
    29. 'learning_rate': [0.01, 0.05, 0.1, 0.5, 1],
    30. 'num_leaves': [31, 50, 75],
    31. 'boosting_type': ['gbdt', 'dart', 'goss']
    32. }
    33. # 初始化网格搜索
    34. grid_search = GridSearchCV(lgbm_model, param_grid, cv=5, scoring='neg_mean_squared_error')
    35. # 进行网格搜索
    36. grid_search.fit(X_train, y_train)
    37. # 获取最佳参数
    38. best_params = grid_search.best_params_
    39. # 使用最佳参数初始化 LGBMRegressor 模型
    40. best_lgbm_model = LGBMRegressor(**best_params)
    41. # 在训练集上训练模型
    42. best_lgbm_model.fit(X_train, y_train)
    43. # 对于验证集,我们需要迭代地预测每一个数据点
    44. y_validation_pred = []
    45. for i in range(len(X_validation)):
    46. if i == 0:
    47. pred = best_lgbm_model.predict([X_validation.iloc[0]])
    48. else:
    49. new_features = list(X_validation.iloc[i, 1:]) + [pred[0]]
    50. pred = best_lgbm_model.predict([new_features])
    51. y_validation_pred.append(pred[0])
    52. y_validation_pred = np.array(y_validation_pred)
    53. # 计算验证集上的MAE, MAPE, MSE 和 RMSE
    54. mae_validation = mean_absolute_error(y_validation, y_validation_pred)
    55. mape_validation = np.mean(np.abs((y_validation - y_validation_pred) / y_validation))
    56. mse_validation = mean_squared_error(y_validation, y_validation_pred)
    57. rmse_validation = np.sqrt(mse_validation)
    58. # 计算训练集上的MAE, MAPE, MSE 和 RMSE
    59. y_train_pred = best_lgbm_model.predict(X_train)
    60. mae_train = mean_absolute_error(y_train, y_train_pred)
    61. mape_train = np.mean(np.abs((y_train - y_train_pred) / y_train))
    62. mse_train = mean_squared_error(y_train, y_train_pred)
    63. rmse_train = np.sqrt(mse_train)
    64. print("Train Metrics:", mae_train, mape_train, mse_train, rmse_train)
    65. print("Validation Metrics:", mae_validation, mape_validation, mse_validation, rmse_validation)

    看结果:

    (3)多步滚动预测-vol. 1

    对于LGBMRegressor,目标变量y_train不能是多列的DataFrame,所以你们懂的。

    (4)多步滚动预测-vol. 2

    同上。

    (5)多步滚动预测-vol. 3

    1. import pandas as pd
    2. import numpy as np
    3. from lightgbm import LGBMRegressor # 导入LGBMRegressor
    4. from sklearn.model_selection import GridSearchCV
    5. from sklearn.metrics import mean_absolute_error, mean_squared_error
    6. # 数据读取和预处理
    7. data = pd.read_csv('data.csv')
    8. data_y = pd.read_csv('data.csv')
    9. data['time'] = pd.to_datetime(data['time'], format='%b-%y')
    10. data_y['time'] = pd.to_datetime(data_y['time'], format='%b-%y')
    11. n = 6
    12. for i in range(n, 0, -1):
    13. data[f'lag_{i}'] = data['incidence'].shift(n - i + 1)
    14. data = data.dropna().reset_index(drop=True)
    15. train_data = data[(data['time'] >= '2004-01-01') & (data['time'] <= '2011-12-31')]
    16. X_train = train_data[[f'lag_{i}' for i in range(1, n+1)]]
    17. m = 3
    18. X_train_list = []
    19. y_train_list = []
    20. for i in range(m):
    21. X_temp = X_train
    22. y_temp = data_y['incidence'].iloc[n + i:len(data_y) - m + 1 + i]
    23. X_train_list.append(X_temp)
    24. y_train_list.append(y_temp)
    25. for i in range(m):
    26. X_train_list[i] = X_train_list[i].iloc[:-(m-1)]
    27. y_train_list[i] = y_train_list[i].iloc[:len(X_train_list[i])]
    28. # 模型训练
    29. param_grid = {
    30. 'n_estimators': [50, 100, 150],
    31. 'learning_rate': [0.01, 0.05, 0.1, 0.5, 1],
    32. 'boosting_type': ['gbdt', 'dart', 'goss'],
    33. 'num_leaves': [31, 63, 127]
    34. }
    35. best_lgbm_models = []
    36. for i in range(m):
    37. grid_search = GridSearchCV(LGBMRegressor(), param_grid, cv=5, scoring='neg_mean_squared_error') # 使用LGBMRegressor
    38. grid_search.fit(X_train_list[i], y_train_list[i])
    39. best_lgbm_model = LGBMRegressor(**grid_search.best_params_)
    40. best_lgbm_model.fit(X_train_list[i], y_train_list[i])
    41. best_lgbm_models.append(best_lgbm_model)
    42. validation_start_time = train_data['time'].iloc[-1] + pd.DateOffset(months=1)
    43. validation_data = data[data['time'] >= validation_start_time]
    44. X_validation = validation_data[[f'lag_{i}' for i in range(1, n+1)]]
    45. y_validation_pred_list = [model.predict(X_validation) for model in best_lgbm_models]
    46. y_train_pred_list = [model.predict(X_train_list[i]) for i, model in enumerate(best_lgbm_models)]
    47. def concatenate_predictions(pred_list):
    48. concatenated = []
    49. for j in range(len(pred_list[0])):
    50. for i in range(m):
    51. concatenated.append(pred_list[i][j])
    52. return concatenated
    53. y_validation_pred = np.array(concatenate_predictions(y_validation_pred_list))[:len(validation_data['incidence'])]
    54. y_train_pred = np.array(concatenate_predictions(y_train_pred_list))[:len(train_data['incidence']) - m + 1]
    55. mae_validation = mean_absolute_error(validation_data['incidence'], y_validation_pred)
    56. mape_validation = np.mean(np.abs((validation_data['incidence'] - y_validation_pred) / validation_data['incidence']))
    57. mse_validation = mean_squared_error(validation_data['incidence'], y_validation_pred)
    58. rmse_validation = np.sqrt(mse_validation)
    59. print("验证集:", mae_validation, mape_validation, mse_validation, rmse_validation)
    60. mae_train = mean_absolute_error(train_data['incidence'][:-(m-1)], y_train_pred)
    61. mape_train = np.mean(np.abs((train_data['incidence'][:-(m-1)] - y_train_pred) / train_data['incidence'][:-(m-1)]))
    62. mse_train = mean_squared_error(train_data['incidence'][:-(m-1)], y_train_pred)
    63. rmse_train = np.sqrt(mse_train)
    64. print("训练集:", mae_train, mape_train, mse_train, rmse_train)

    结果:

    三、数据

    链接:https://pan.baidu.com/s/1EFaWfHoG14h15KCEhn1STg?pwd=q41n

    提取码:q41n

  • 相关阅读:
    不能显式拦截ajax请求的302响应?
    Java 8 stream的详细用法
    2024年5月系统架构设计师综合知识真题
    【计算机辅助蛋白质结构分析、分子对接、片段药物设计技术与应用】
    [C/C++] 数据结构 LeetCode:用队列实现栈
    【前端】Js
    2023最新SSM计算机毕业设计选题大全(附源码+LW)之java网上私厨到家服务平台dp28s
    PettingZoo:多智能体游戏环境库入门
    linux安装切换图形化界面?
    stm32cubemx hal学习记录:TIMER输入捕获
  • 原文地址:https://blog.csdn.net/qq_30452897/article/details/133544582