大家好,时间序列数据是许多现实世界问题的核心,例如预测能源消耗、气象预报、库存管理。传统上,使用专门的时间序列模型如Prophet来对此类数据进行建模和预测。然而,通过将时间序列数据转换为表格格式,可以利用更广泛的机器学习算法和技术,从而发现新的见解和改进预测性能。
本文将介绍使用开源库将日常能源消耗的时间序列数据集转换为表格形式,探索多种机器学习模型,包括梯度提升决策树和自动机器学习(AutoML),将其与Prophet模型的性能进行对比。可以发现,使用梯度提升决策树对表格数据进行多类别分类,可将样本外预测误差降低67%,与梯度提升相比,AutoML进一步将预测误差降低42%。
这些分析说明,通过适当的特征工程和机器学习技术,我们能够从时间序列数据中挖掘出更多有价值的信息,显著提高预测准确性。
1.检查数据
该数据表示PJM每小时的能源消耗量(以兆瓦为单位)。PJM Interconnection LLC(PJM)是美国的一个区域输电组织(RTO),是东部互联电网的一部分,为多州提供电力传输服务。
数据集包括日期列和兆瓦级能耗列,目标是训练时间序列预测模型,预测明天的日能耗水平分为 4 个等级:low
、below average
、above average
和high
。这些等级根据整体日能耗分布的四分位数确定。
首先演示如何应用时间序列预测方法(如Prophet),但这些方法仅适用于时间序列数据的某些类型的 ML 模型。接下来,将问题重构为一个标准的多类分类问题,可以应用任何机器学习模型,并通过使用监督式ML获得出色的预测结果。
首先,我们将数据转换为日均能耗,并将列重命名为先知预测模型期望的格式。实际值的日能耗水平转换成四分位数,即预测的值,训练数据及每个日能耗水平对应的四分位数如下所示,四分位数是使用训练数据计算的,以防止数据泄露。
下面是用来拟合预测模型的训练数据:
下面是测试数据,我们将根据这些数据来评估我们的预测结果。
2.训练和评估Prophet预测模型
根据上图显示,使用 2015-04-09
作为训练数据范围的结束日期,并从 2015-04-10
开始进行测试数据。仅使用训练数据计算每日能耗的四分位阈值,以避免数据泄漏。
接下来,预测测试数据期间 PJME 的日能耗水平(以兆瓦为单位),并将预测值表示为离散变量。该变量表示每日能源消耗水平的四分位数,可分为 1("低")、2("低于平均水平")、3("高于平均水平")或 4("高")。在评估方面,使用 scikit-learn
中的 accuracy_score
函数来评估模型的性能。由于我们是以这种方式提出问题的,因此能够使用分类准确率来评估模型的次日预测,并与未来的模型进行比较。
import numpy as np
from prophet import Prophet
from sklearn.metrics import accuracy_score# 初始化模型并在训练数据上进行训练
model = Prophet()
model.fit(train_df)# 创建覆盖测试期的未来预测数据框
future = model.make_future_dataframe(periods=len(test_df), freq='D')
预测 = model.predict(future)# 根据阈值将预测的每日值分为四等分
forecast['quartile'] = pd.cut(forecast['yhat'], bins = [-np.inf] + list(quartiles) + [np.inf], labels=[1, 2, 3, 4])# 提取测试期的预测四分位数
forecasted_quartiles = forecast.iloc[-len(test_df):]['quartile'].astype(int)# 将测试集中的实际日值归类为四分位数
test_df['quartile'] = pd.cut(test_df['y'], bins=[-np.inf] + list(quartiles) + [np.inf], labels=[1, 2, 3, 4])
actual_test_quartiles = test_df['quartile'].astype(int)# 计算评估指标
accuracy = accuracy_score(actual_test_quartiles, forecasted_quartiles)# 打印评估指标
print(f'Accuracy: {accuracy:.4f}')
>>> 0.4249
样本外准确率只有43%,建立时间序列模型时,只能使用时间序列预测模型(可能的ML模型的有限子集)。接下来通过适当的特征化将时间序列转换为标准表格数据集,更灵活地对这些数据进行建模,转换为标准表格数据后,就可以使用任何有监督的ML模型来预测这些日能耗数据。
3.通过特征化将时间序列数据转换为表格数据
将时间序列数据转换为表格格式,使用开源库 sktime
、tsfresh
和 tsfel
对数据进行特征化处理。这些库可以提取大量的特征,包括统计特征、时间特征和可能的频谱特征,以捕捉时间序列数据的潜在模式和特征。通过将时间序列分解为单个特征,可以更容易地了解数据的不同方面是如何影响目标变量的。
TSFreshFeatureExtractor
是sktime
库中的一个特征提取工具,利用tsfresh
的功能从时间序列数据中提取相关特征。tsfresh
设计用于自动计算大量时间序列特征,对理解复杂的时间动态非常有益。在本实例中,使用TSFreshFeatureExtractor
中最小的基本特征集来对数据进行特征化。
tsfel
即 "时间序列特征提取库",提供了一整套从时间序列数据中提取特征的工具。利用预定义配置,从能源消耗时间序列数据中构建了丰富的特征集(如统计、时间、频谱),捕捉了可能与分类任务相关的各种特征。
import tsfel
from sktime.transformations.panel.tsfresh import TSFreshFeatureExtractor# 定义 tsfresh 特征提取器
tsfresh_trafo = TSFreshFeatureExtractor(default_fc_parameters="minimal")# 使用特征提取器转换训练数据
X_train_transformed = tsfresh_trafo.fit_transform(X_train)# 使用相同的特征提取器转换测试数据
X_test_transformed = tsfresh_trafo.transform(X_test)# 检索预定义的特征配置文件,提取所有可用特征
cfg = tsfel.get_features_by_domain()# 每天计算 tsfel 特征的函数
def compute_features(group):# TSFEL expects a DataFrame with the data in columns, so we transpose the input groupfeatures = tsfel.time_series_features_extractor(cfg, group, fs=1, verbose=0)return features# 按指数的 "日 "级分组,并进行特征计算
train_features_per_day = X_train.groupby(level='Date').apply(compute_features).reset_index(drop=True)
test_features_per_day = X_test.groupby(level='Date').apply(compute_features).reset_index(drop=True)# 将每个特征组合成一组组合特征,用于训练/测试数据
train_combined_df = pd.concat([X_train_transformed, train_features_per_day], axis=1)
test_combined_df = pd.concat([X_test_transformed, test_features_per_day], axis=1)
针对输入特征进行了精心的特征选择,首先剔除那些与目标变量"日均能耗水平"的相关性过高(相关系数绝对值超过0.8)的特征。这些高度相关的特征可能会导致模型过度拟合,即在训练数据上表现良好,但在新的未见数据上泛化能力差。
同时移除那些与目标变量完全不相关(相关系数为0)的特征,毫无相关性的特征对预测目标没有任何贡献,保留它们不仅增加了模型复杂度,也可能引入无关的噪声信息,影响模型性能。
通过这一步筛选,保留那些与目标变量有一定相关性、但又不至于过度相关的特征子集,为后续的机器学习建模打下基础。合理的特征工程有助于提升模型的估计质量和泛化能力。
# 滤出与目标变量高度相关的特征
column_of_interest = "PJME_MW__mean"
train_corr_matrix = train_combined_df.corr()
train_corr_with_interest = train_corr_matrix[column_of_interest]
null_corrs = pd.Series(train_corr_with_interest.isnull())
false_features = null_corrs[null_corrs].index.tolist()columns_to_exclude = list(set(train_corr_with_interest[abs(train_corr_with_interest) > 0.8].index.tolist() + false_features))
columns_to_exclude.remove(column_of_interest)# 过滤后的数据帧排除了与所关注列高度相关的列
X_train_transformed = train_combined_df.drop(columns=columns_to_exclude)
X_test_transformed = test_combined_df.drop(columns=columns_to_exclude)
现在有 73 个特征,这些特征是从使用的时间序列特征库中添加的,根据这些特征,要预测的标签是第二天的能耗水平。
最佳的做法是在训练数据和测试数据上分别应用特征化过程,以避免数据泄漏,测试使用最近的观测数据。此外,使用以下代码计算离散四分位值,并获取训练/测试能量标签,也就是 y_labels
。
# 定义一个函数,将每个值划分为四分位数
def classify_into_quartile(value):if value < quartiles[0]:return 1 elif value < quartiles[1]:return 2 elif value < quartiles[2]:return 3 else:return 4 y_train = X_train_transformed["PJME_MW__mean"].rename("daily_energy_level")
X_train_transformed.drop("PJME_MW__mean", inplace=True, axis=1)y_test = X_test_transformed["PJME_MW__mean"].rename("daily_energy_level")
X_test_transformed.drop("PJME_MW__mean", inplace=True, axis=1)energy_levels_train = y_train.apply(classify_into_quartile)
energy_levels_test = y_test.apply(classify_into_quartile)
4.在特征化表格数据上训练和评估GBC模型
使用特征化表格数据集,可以应用任何有监督的 ML 模型来预测未来的能耗水平。这里使用梯度提升分类器(GBC)模型,它是大多数数据科学家处理表格数据的首选武器。
我们的GBC模型由 sklearn.ensemble
模块实例化,并配置了特定的超参数,以优化其性能并避免过度拟合。
from sklearn.ensemble import GradientBoostingClassifiergbc = GradientBoostingClassifier(n_estimators=150,learning_rate=0.1,max_depth=4,min_samples_leaf=20,max_features='sqrt',subsample=0.8,random_state=42
)gbc.fit(X_train_transformed, energy_levels_train)y_pred_gbc = gbc.predict(X_test_transformed)
gbc_accuracy = accuracy_score(energy_levels_test, y_pred_gbc)
print(f'Accuracy: {gbc_accuracy:.4f}')
>>> 0.8075
81% 的样本外准确率大大高于我们之前的prophet模型结果。
5.使用AutoML简化工作
了解如何特征化时间序列问题,以及应用梯度提升等强大ML模型的好处后,应用ML模型简化工作流程。我们可以尝试多种模型,调整超参数,然后将其集合在一起,也可以让AutoML处理所有这些问题。
使用 [Cleanlab Studio: https://cleanlab.ai/] 提供的AutoML解决方案,无需任何配置。只需提供表格数据集,平台将自动训练多种有监督ML模型(包括梯度提升等),并调整超参数,确定最适合组合成一个预测器的模型。以下是训练和部署AutoML监督分类器所需的全部代码:
from cleanlab_studio import Studiostudio = Studio()
studio.create_project(dataset_id=energy_forecasting_dataset,project_name="ENERGY-LEVEL-FORECASTING",modality="tabular",task_type="multi-class",model_type="regular",label_column="daily_energy_level",
)model = studio.get_model(energy_forecasting_model)
y_pred_automl = model.predict(test_data, return_pred_proba=True)
自动机器学习(AutoML)平台中展示了模型评估估计值,展示了所有不同类型的机器学习(ML)模型(包括多个梯度提升模型),以及通过优化组合这些模型的预测结果而构建的集合预测器。
不同类型模型的AutoML结果
在测试数据上运行推理以获得第二天的能耗水平预测结果后,得到的测试准确率为 89%,与之前的梯度提升方法相比,原始准确率提高了 8%。
在日常能耗水平数据上测试AutoML的准确率
6.总结
此方法可应用于预测PJM地区的日常能源消耗数据。首先使用专门的时间序列模型 Prophet 对原始数据进行建模作为基准,然后将数据转换为表格格式,提取出更多有用的特征,再使用通用的机器学习分类算法进行建模和预测。
结果显示,与基准的 Prophet 模型相比,表格数据加梯度提升树的方法可将预测误差降低67%(准确率提高38%)。使用自动机器学习(AutoML)技术,对表格数据自动选择并调优最佳的分类算法。AutoML模型不仅比梯度提升树表现更好,降低了42%的预测误差(准确率提高8%),而且比 Prophet 基准模型的表现出色,降低了高达81%的预测误差(准确率提高46%)。
这些分析说明,通过将时间序列数据转化为更标准的表格形式,并结合适当的特征工程和机器学习算法,能够超越传统时间序列模型的性能,在能源消耗等许多现实预测问题上获得更准确的结果。总的来说,这种基于表格数据的通用建模方法,为时间序列预测问题提供了一种值得探索的新思路。