XGBoost和LightGBM时间序列预测对比

news2024/11/16 5:37:41

XGBoost和LightGBM都是目前非常流行的基于决策树的机器学习模型,它们都有着高效的性能表现,但是在某些情况下,它们也有着不同的特点。

XGBoost和LightGBM简单对比

训练速度

LightGBM相较于xgboost在训练速度方面有明显的优势。这是因为LightGBM使用了一些高效的算法和数据结构,比如直方图算法和基于梯度单边采样算法(GOSS),这些算法使得LightGBM在训练大规模数据集时速度更快。

内存消耗

由于LightGBM使用了一些高效的算法和数据结构,因此其内存消耗相对较小。而xgboost在处理大规模数据集时可能会需要较大的内存。

鲁棒性

xgboost在处理一些不规则数据时更加鲁棒,比如一些缺失值和异常值。而LightGBM在这方面相对较弱。

精度

在相同的数据集和参数设置下,两个模型的精度大致相当。不过在某些情况下,xgboost可能表现得更好,比如在特征数较少的情况下,或者是需要更加平滑的决策树时。

参数设置

xgboost的参数比较多,需要根据实际情况进行调整。而LightGBM的参数相对较少,大多数情况下使用默认参数即可。

XGBoost和 LightGBM 算法对比

XGBoost和 LightGBM 都是基于决策树的梯度提升框架,它们的核心思想都是通过组合多个弱学习器来提升模型的预测能力。它们在实现上有很多相似之处,但在算法方面有一些明显的不同:

分裂点选择方法

在构建决策树时,xgboost 采用的是一种贪心算法,称为 Exact Greedy Algorithm,它会枚举每一个特征的每一个取值作为分裂点,然后计算对应的增益值,选取最大增益的分裂点作为最终的分裂点。

而 LightGBM 使用的是一种基于梯度单边采样(Gradient-based One-Side Sampling,GOSS)和直方图算法的分裂点选择方法,它会先对数据进行预排序,然后将数据划分成若干个直方图,每个直方图包含多个数据点。在寻找最优分裂点时,LightGBM 只会在直方图中选取一个代表点(即直方图中的最大梯度值)进行计算,这样大大降低了计算量。

特征并行处理

xgboost 将数据按特征进行划分,然后将每个特征分配到不同的节点上进行计算。这种方法可以有效提高训练速度,但需要额外的通信和同步开销。

LightGBM 将数据按进行划分,然后将每个分块分配到不同的节点上进行计算。这种方法避免了通信和同步开销,但需要额外的内存空间。

处理缺失值

xgboost 会自动将缺失值分配到左右子树中概率更高的那一边。这种方法可能会引入一些偏差,但对于处理缺失值较多的数据集比较有效。

LightGBM 则采用的方法称为 Zero As Missing(ZAM),它将所有的缺失值都视为一个特殊的取值,并将其归入其中一个子节点中。这种方法可以避免偏差,但需要更多的内存空间。

训练速度

LightGBM 在训练速度方面具有显著优势,这是因为它使用了 GOSS 和直方图算法,减少了计算量和内存消耗。而 xgboost 的计算速度相对较慢,但是在处理较小的数据集时表现良好。

电力能源消耗预测

在当今世界,能源是主要的讨论点之一,能够准确预测能源消费需求是任何电力公司的关键,所以我们这里以能源预测为例,对这两个目前最好的表格类数据的模型做一个对比。

我们使用的是伦敦能源数据集,其中包含2011年11月至2014年2月期间英国伦敦市5567个随机选择的家庭的能源消耗。我们将这个集与伦敦天气数据集结合起来,作为辅助数据来提高模型的性能。

1、预处理

在每个项目中,我们要做的第一件事就是很好地理解数据,并在需要时对其进行预处理:

 import pandas as pd
 import matplotlib.pyplot as plt
 
 df = pd.read_csv("london_energy.csv")
 print(df.isna().sum())
 df.head()

“LCLid”是标识每个家庭的唯一字符串,“Date”就是我们的时间索引,“KWH”是在该日期花费的总千瓦时数,没有任何缺失值。由于我们想要以一般方式而不是以家庭为单位来预测耗电量,所以我们需要将结果按日期分组并平均千瓦时。

 df_avg_consumption = df.groupby("Date")["KWH"].mean()
 df_avg_consumption = pd.DataFrame({"date": df_avg_consumption.index.tolist(), "consumption": df_avg_consumption.values.tolist()})
 df_avg_consumption["date"] = pd.to_datetime(df_avg_consumption["date"])
 print(f"From: {df_avg_consumption['date'].min()}")
 print(f"To: {df_avg_consumption['date'].max()}")

我们来做一个折线图:

 df_avg_consumption.plot(x="date", y="consumption")

季节性特征非常明显。冬季能源需求很高,而夏季的消耗是最低的。这种行为在数据集中每年都会重复,具有不同的高值和低值。可视化一年内的波动:

 df_avg_consumption.query("date > '2012-01-01' & date < '2013-01-01'").plot(x="date", y="consumption")

训练像XGBoost和LightGB这样的模型,我们需要自己创建特征。因为目前我们只有一个特征:日期。所欲需要根据完整的日期提取不同的特征,例如星期几、一年中的哪一天、月份和其他日期:

 df_avg_consumption["day_of_week"] = df_avg_consumption["date"].dt.dayofweek
 df_avg_consumption["day_of_year"] = df_avg_consumption["date"].dt.dayofyear
 df_avg_consumption["month"] = df_avg_consumption["date"].dt.month
 df_avg_consumption["quarter"] = df_avg_consumption["date"].dt.quarter
 df_avg_consumption["year"] = df_avg_consumption["date"].dt.year
 
 df_avg_consumption.head()

’ date '特征就变得多余了。但是在删除它之前,我们将使用它将数据集分割为训练集和测试集。与传统的训练相反,在时间序列中,我们不能只是以随机的方式分割集合,因为数据的顺序非常重要,所以对于测试集,将只使用最近6个月的数据。如果训练集更大,可以用去年全年的数据作为测试集。

 training_mask = df_avg_consumption["date"] < "2013-07-28"
 training_data = df_avg_consumption.loc[training_mask]
 print(training_data.shape)
 
 testing_mask = df_avg_consumption["date"] >= "2013-07-28"
 testing_data = df_avg_consumption.loc[testing_mask]
 print(testing_data.shape)

可视化训练集和测试集之间的分割:

 figure, ax = plt.subplots(figsize=(20, 5))
 training_data.plot(ax=ax, label="Training", x="date", y="consumption")
 testing_data.plot(ax=ax, label="Testing", x="date", y="consumption")
 plt.show()

现在我们可以删除’ date '并创建训练和测试集:

 # Dropping unnecessary `date` column
 training_data = training_data.drop(columns=["date"])
 testing_dates = testing_data["date"]
 testing_data = testing_data.drop(columns=["date"])
 
 X_train = training_data[["day_of_week", "day_of_year", "month", "quarter", "year"]]
 y_train = training_data["consumption"]
 
 X_test = testing_data[["day_of_week", "day_of_year", "month", "quarter", "year"]]
 y_test = testing_data["consumption"]

2、训练模型

我们这里的超参数优化将通过网格搜索完成。因为是时间序列,所以不能只使用普通的k-fold交叉验证。Scikit learn提供了TimeSeriesSplit方法,这里可以直接使用。

 from xgboost import XGBRegressor
 import lightgbm as lgb
 from sklearn.model_selection import TimeSeriesSplit, GridSearchCV
 
 # XGBoost
 cv_split = TimeSeriesSplit(n_splits=4, test_size=100)
 model = XGBRegressor()
 parameters = {
     "max_depth": [3, 4, 6, 5, 10],
     "learning_rate": [0.01, 0.05, 0.1, 0.2, 0.3],
     "n_estimators": [100, 300, 500, 700, 900, 1000],
     "colsample_bytree": [0.3, 0.5, 0.7]
 }
 
 
 grid_search = GridSearchCV(estimator=model, cv=cv_split, param_grid=parameters)
 grid_search.fit(X_train, y_train)

对于LightGB,代码是这样的:

 # LGBM
 cv_split = TimeSeriesSplit(n_splits=4, test_size=100)
 model = lgb.LGBMRegressor()
 parameters = {
     "max_depth": [3, 4, 6, 5, 10],
     "num_leaves": [10, 20, 30, 40, 100, 120],
     "learning_rate": [0.01, 0.05, 0.1, 0.2, 0.3],
     "n_estimators": [50, 100, 300, 500, 700, 900, 1000],
     "colsample_bytree": [0.3, 0.5, 0.7, 1]
 }
 
 
 grid_search = GridSearchCV(estimator=model, cv=cv_split, param_grid=parameters)
 grid_search.fit(X_train, y_train)

3、评估

为了评估测试集上的最佳估计量,我们将计算:平均绝对误差(MAE)、均方误差(MSE)和平均绝对百分比误差(MAPE)。因为每个指标都提供了训练模型实际性能的不同视角。我们还将绘制一个折线图,以更好地可视化模型的性能。

 from sklearn.metrics import mean_absolute_error, mean_absolute_percentage_error,\
   mean_squared_error
 
 def evaluate_model(y_test, prediction):
   print(f"MAE: {mean_absolute_error(y_test, prediction)}")
   print(f"MSE: {mean_squared_error(y_test, prediction)}")
   print(f"MAPE: {mean_absolute_percentage_error(y_test, prediction)}")
 
 def plot_predictions(testing_dates, y_test, prediction):
   df_test = pd.DataFrame({"date": testing_dates, "actual": y_test, "prediction": prediction })
   figure, ax = plt.subplots(figsize=(10, 5))
   df_test.plot(ax=ax, label="Actual", x="date", y="actual")
   df_test.plot(ax=ax, label="Prediction", x="date", y="prediction")
   plt.legend(["Actual", "Prediction"])
   plt.show()

然后我们运行下面代码进行验证:

 # Evaluating GridSearch results
 prediction = grid_search.predict(X_test)
 plot_predictions(testing_dates, y_test, prediction)
 evaluate_model(y_test, prediction)

XGB:

LightGBM:

从图上可以看到,XGBoost可以更准确地预测冬季的能源消耗,但为了量化和比较性能,我们计算误差指标。通过查看下面的表,可以很明显地看出XGBoost在所有情况下都优于LightGBM。

使用外部辅助天气数据

该模型表现还不错,我们看看还能不能提高呢?为了达到更好的效果,可以采用许多不同的技巧和技巧。其中之一是使用与能源消耗直接或间接相关的辅助特征。例如,在预测能源需求时,天气数据可以发挥决定性作用。这就是为什么我们选择使用伦敦天气数据集的天气数据的原因。

首先让我们来看看数据的结构:

 df_weather = pd.read_csv("london_weather.csv")
 print(df_weather.isna().sum())
 df_weather.head()

这个数据集中有各种缺失的数据需要填充。填充缺失的数据也不是一件简单的事情,因为每种不同的情况填充方法是不同的。我们这里的天气数据,每天都取决于前几天和下一天,所以可以通过插值来填充这些值。另外还需要将’ date ‘列转换为’ datetime ',然后合并两个DF,以获得一个增强的完整数据集。

 # Parsing dates
 df_weather["date"] = pd.to_datetime(df_weather["date"], format="%Y%m%d")
 
 # Filling missing values through interpolation
 df_weather = df_weather.interpolate(method="ffill")
 
 # Enhancing consumption dataset with weather information
 df_avg_consumption = df_avg_consumption.merge(df_weather, how="inner", on="date")
 df_avg_consumption.head()

在生成增强集之后,必须重新运行拆分过程获得新的’ training_data ‘和’ testing_data '。

 # Dropping unnecessary `date` column
 training_data = training_data.drop(columns=["date"])
 testing_dates = testing_data["date"]
 testing_data = testing_data.drop(columns=["date"])
 
 X_train = training_data[["day_of_week", "day_of_year", "month", "quarter", "year",\
                          "cloud_cover", "sunshine", "global_radiation", "max_temp",\
                          "mean_temp", "min_temp", "precipitation", "pressure",\
                          "snow_depth"]]
 y_train = training_data["consumption"]
 
 
 X_test = testing_data[["day_of_week", "day_of_year", "month", "quarter", "year",\
                          "cloud_cover", "sunshine", "global_radiation", "max_temp",\
                          "mean_temp", "min_temp", "precipitation", "pressure",\
                          "snow_depth"]]
 y_test = testing_data["consumption"]

训练步骤不需要做更改。在新数据集上训练模型后,我们得到以下结果:

XGBoost

LightGBM

整合上面的表格:

我们看到:天气数据大大提高了两个模型的性能。特别是在XGBoost场景中,MAE减少了近44%,而MAPE从19%减少到16%。对于LightGBM, MAE下降了42%,MAPE从19.8%下降到16.7%。

总结

xgboost 和 LightGBM 都是优秀的梯度提升框架,它们各自具有一些独特的优点和缺点,选择哪一种算法应该根据实际应用场景和数据集的特征来决定。如果数据集中缺失值较多,可以选择 xgboost。如果需要处理大规模数据集并追求更快的训练速度,可以选择 LightGBM。如果需要解释模型的特征重要性,xgboost 提供了更好的特征重要性评估方法,并且如果需要更加鲁棒的模型,可以优先选择xgboost。

在本文中我们还介绍了一种提高模型的方法,就是使用附加数据,通过附加我们认为相关的辅助数据,也可以大大提高模型的性能。

除此以外,我们还可以结合滞后特征或尝试不同的超参数优化技术(如随机搜索或贝叶斯优化),来作为提高性能的尝试,如果你有任何新的结果,欢迎留言。

以下是2个数据集的链接:

https://avoid.overfit.cn/post/bfcd5ca1cd7741acac137fade88bd747

作者:George Kamtziridis

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/382213.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

发票自动OCR识别并录入模板 3分钟免费配置

要问整个公司里和数据打交道最多的职能&#xff0c;非财务莫属了吧。除了每天要处理大量财务数据外&#xff0c;还有发票录入的工作让财务陷入“易燃易爆炸”的工作状态。发票报销看似简单&#xff0c;但发票的类型有很多种&#xff0c;每种发票需要录入的信息也有差别。再加上…

SimpleITK 获取CT spacing 底层原理

SimpleITK 获取CT spacing 底层原理 一、层厚、层间距概念 层厚&#xff1a; CT扫描机扫描出来的断层的层的厚度&#xff0c; 通常用Slice thickness表示&#xff0c; 比如 5mm 层间隔&#xff1a;一般用 Slice interval 或 Slice increment来表示&#xff0c;比如 5mm。在 …

最新!蔚来2022年第四季度被理想汽车超越,或将在2023年全面落后

3月1日&#xff0c;蔚来汽车&#xff08;NYSE: NIO; HKEX: 9866; SGX: NIO&#xff0c;下称“蔚来”&#xff09;发布了截至2022年12月31日的第四季度及全年财报。财报显示&#xff0c;蔚来2022年第四季度实现营收160.64亿元&#xff08;约23.29亿美元&#xff09;&#xff0c;…

SpringBoot实现静态资源映射,登录功能以及访问拦截验证——以黑马瑞吉外卖为例

目录 一、项目简介 二、设置静态资源访问路径 三、实现登录功能 四、拦截访问请求 本篇文章以黑马瑞吉外卖为例 一、项目简介 瑞吉外卖项目分为后台和前台系统&#xff0c;后台提供给管理人员使用&#xff0c;前台则是用户订餐使用 资源我们放在resources下 二、设置静态…

Postman的下载和安装

文章目录一 下载二 安装一 下载 官网下载地址&#xff1a;https://www.postman.com/ 进入官网页面&#xff0c;选择对应的操作系统和版本&#xff0c;然后进入Postman下载页面&#xff0c;然后点击 Windows 64-bit 即可下载&#xff0c;如下 二 安装 Postman的安装很简单&am…

Python每日一练(20230302)

目录 1. 字符串统计 2. 合并两个有序链表 3. 下一个排列 附录 Python字典内置方法 增 删 改 查 其它 1. 字符串统计 从键盘输入一个包含有英文字母、数字、空格和其它字符的字符串&#xff0c;并分别实现下面的功能&#xff1a;统计字符串中出现2次的英文字母&#…

C++---最长上升子序列模型---友好城市(每日一道算法2023.3.2)

注意事项&#xff1a; 本题为"线性dp—最长上升子序列的长度"的扩展题&#xff0c;所以dp思路这里就不再赘述。 题目&#xff1a; Palmia国有一条横贯东西的大河&#xff0c;河有笔直的南北两岸&#xff0c;岸上各有位置各不相同的N个城市。 北岸的每个城市有且仅有…

python自学之《21天学通Python》(18)——第21章 案例2 Python搞定大数据

“大数据&#xff08;Big Data&#xff09;”这个术语最早期的引用可追溯到apache org的开源项目Nutch。当时&#xff0c;大数据用来描述为更新网络搜索索引需要同时进行批量处理或分析的大量数据集。随着谷歌MapReduce和GoogleFileSystem &#xff08;GFS&#xff09;的发布&a…

第十三节 继承

什么是继承&#xff1f; java中提供一个关键字extends&#xff0c;用这个关键字&#xff0c;我们可以让一个类和另一个类建立父子关系。 public class Student extends People{} student为子类&#xff08;派生类&#xff09;&#xff0c;people为父类&#xff08;基类或者超类…

激光雷达迈向规模量产期:如何看待3类玩家的竞争格局?

激光雷达正进入规模量产周期。 高工智能汽车研究院监测数据显示&#xff0c;2022年中国市场&#xff08;不含进出口&#xff09;乘用车前装标配激光雷达交付12.99万颗&#xff0c;配套新车11.18万辆&#xff0c;同比分别增长1544.30%和2626.82%&#xff1b;预计2023年标配交付将…

第四回:文字图例尽眉目

import matplotlib import matplotlib.pyplot as plt import numpy as np import matplotlib.dates as mdates import datetime一、Figure和Axes上的文本 Matplotlib具有广泛的文本支持&#xff0c;包括对数学表达式的支持、对栅格和矢量输出的TrueType支持、具有任意旋转的换…

Python进阶-----面向对象2.0(特有属性和方法与私有属性和方法)

目录 前言&#xff1a; 1.添加特有属性/方法 示例1&#xff1a;添加特有属性 示例2&#xff1a;添加特有方法 2.私有属性/方法 &#xff08;1&#xff09;私有化示例 &#xff08;2&#xff09; 私有化属性/方法可以在类的内部使用 &#xff08;3&#xff09;强制访问私…

一:BT、BLE版本说明及对比

蓝牙版本说明1.常见名词说明2.BT&BLE特性对比3.BT各版本对比4.BLE各版对比1.常见名词说明 名称说明BR(Basic Rate)基本码率EDR(Enhanced Data Rate)增强码率BLE(Bluetooth Low Energy)低功耗蓝牙HS(High Speed)高速蓝牙BT(BlueTooth)蓝牙技术LE(Low Energy)低能耗AFH(Adap…

态路小课堂丨光模块使用可能遇到的4大问题以及注意事项!

光模块作为光通信系统的核心器件&#xff0c;其内部集成了精密的光学元件和电路元件。在日常使用过程中如果不按规定操作&#xff0c;很容易导致光模块损坏。本文态路通信为您介绍光模块在使用时可能遇到的问题&#xff0c;以及我们应该注意的事项。以此来减少光模块使用寿命&a…

Spring 事务(编程式事务、声明式事务@Transactional、事务隔离级别、事务传播机制)

文章目录1. 事务的定义2. Spring 中事务的实现2.1 MySQL 中使用事务2.2 Spring 中编程式事务的实现2.3 Spring 中声明式事务2.3.1 声明式事务的实现 Transactional2.3.2 Transactional 作用域2.3.3Transactional 参数设置2.3.4 Transactional 异常情况2.3.5 Transactional 工作…

桑基图绘制

绘制桑基图 但是关于数据流上的数据标签可能还得用ps… 注意 1、节点&#xff08;nodes&#xff09;要包括各层的&#xff0c;且不能重复&#xff0c;需要自己在后边append几个数据 2、数据流的数据要是整数&#xff0c;不能时numpy 3、注意表格加入时要再由array转为list&a…

大数据技术之Maxwell入门案例学习

大数据技术之Maxwell入门案例学习 文章目录大数据技术之Maxwell入门案例学习1、写在前面2. Maxwell 使用2.1 Maxwell 安装部署2.2 Maxwell 入门案例2.2.1 监控 Mysql 数据并在控制台打印2.2.2 监控 Mysql 数据输出到 kafka2.2.3 监控 Mysql 指定表数据输出控制台2.2.4 监控 Mys…

分布式监控系统——Zabbix(4)可视化、模板和用户参数

文章目录分布式监控系统——Zabbix&#xff08;4&#xff09;可视化、模板和用户参数一、zabbix可视化1.简介2.自定义图形&#xff08;Graphs&#xff09;3.聚合图形&#xff08;Screens&#xff09;4.幻灯片演示&#xff08;Slide shows&#xff09;5.定义拓扑图&#xff08;M…

企业电销如何获得高质量精准流量,大数据获客直击精准客流

随时社会的发展&#xff0c;时代的进步&#xff0c;各行各业都在崛起&#xff0c;竞争力愈演愈烈&#xff0c;那么为了使自己的品牌得到更多人的关注&#xff0c;自己的产品可以更好的销售&#xff0c;无数的老板在想各种缤纷的办法让自己赚钱&#xff0c;百度竞价&#xff0c;…

图像处理│一张自拍即可实现变老变年轻,带你感受时光流逝之美

✨ 目录&#x1f388; 项目效果&#x1f388; 环境搭建&#x1f388; 下载PaddleGAN&#x1f388; 安装飞浆&#x1f388; 生成图片潜码&#x1f388; 老龄化处理&#x1f388; 年轻化处理&#x1f388; 项目效果 飞浆是一个由百度推出的深度学习开发平台&#xff0c;为开发者…