时间序列预测12:用电量预测 02 朴素模型多步预测建模

news/2024/11/19 5:53:05/

【时间序列预测/分类】 全系列60篇由浅入深的博文汇总:传送门


接上文,本文使用朴素模型来对家庭用电数据集进行单变量多步预测。主要内容如下:

  • 如何为模型准备数据集;
  • 如何开发指标、划分数据集、评估预测模型;
  • 如何开发和评估和比较朴素模型的性能;

文章目录

  • 如何开发用于多时间步家庭用电量预测的朴素模型
  • 1. 数据处理
    • 1.1 异常值处理
    • 1.2 缺失值处理
  • 2. 模型评估
    • 2.1 问题建模
    • 2.2 评价指标
    • 2.3 训练集和测试集划分
    • 2.4 前向验证
    • 2.5 朴素预测模型(简单模型)
      • 2.5.1 每日持久性预测
      • 2.5.2 每周持久性预测
      • 2.5.3 一年前每周的持久性预测
  • 3. 完整代码


如何开发用于多时间步家庭用电量预测的朴素模型

1. 数据处理

1.1 异常值处理

从上一篇文章中得知,数据集中有大量标记为 的异常值,这就需要把这些异常值处理为np.nan的浮点类型,提高数据处理速度。代码如下:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt# 函数的参数在上篇文章中已经介绍,此处不再赘述。
dataset = pd.read_csv('household_power_consumption.txt', sep=';', header=0, low_memory=False, infer_datetime_format=True, engine='c',parse_dates={'datetime':[0,1]}, index_col=['datetime'])dataset.replace('?', np.nan, inplace=True) # 替换异常值
values = dataset.values.astype('float32') # 统一数据类型为float类型,提高精度和速度

1.2 缺失值处理

刚才我们把异常值替换成了缺失值(nan),这一步我们填充这些缺失的值。一个非常简单的方法是复制前一天同一时刻的采样值。使用自定义的 fill_missing() 函数来实现:

def fill_missing(values):'''该函数实现缺失值填充思路:将前一天同一时刻的采样值用来填充缺失值'''one_day = 60 * 24for row in range(values.shape[0]):# 行循环for col in range(values.shape[1]): # 列循环if np.isnan(values[row, col]):values[row, col] = values[row - one_day, col]fill_missing(dataset.values) # 填充缺失值

处理完成后,添加新列并将处理完成的数据保存,计算公式已经在前一篇文章中解释过,此处不赘述。代码如下:

# 添加剩余用电量的列
values = dataset.values
dataset['sub_metering_4'] = (values[:,0] * 1000 / 60) - (values[:,4] + values[:,5] + values[:,6])
dataset.to_csv('household_power_consumption.csv')

至此,数据处理完成。


2. 模型评估

本节介绍如何开发和评估家庭用电量数据集的预测模型。本节主要包括以下四部分内容:

  • 问题建模
  • 评价指标
  • 训练集测试集划分
  • 前向验证

2.1 问题建模

有许多方法探索家庭用电量数据集。本文使用这些数据来探索一个具体的问题:用最近一段时间的数据来预测未来一周的用电量是多少。这需要建立一个预测模型预测未来七天每天的总有功功率。这类问题被称为多步时间序列预测问题。利用多个输入变量的模型可称为多变量(特征)多步时间序列预测模型。

要达到这样的目的,为了便于处理,先把原数据每分钟的耗电量采样数据重新采样成每日总耗电量。这不是必需的,但是有意义,因为我们关心的是每天的总功率。可以使用 Pandas中的 resample() 函数实现,设置参数 “D” 调用此函数,以允许按日期-时间索引加载数据并按天将数据重新采样分组。然后,可以通过计算每天所有采样值的总和,为这8个变量(特征)创建新的日耗电量数据集。

查看重新采样的结果:

daily_groups = dataset.resample('D')
daily_groups.sum()

在这里插入图片描述
新采样包含的原采样点个数统计:

daily_groups.count()

在这里插入图片描述
重采样:

daily_data = daily_groups.sum()

可以从以上输出信息得知重新采样之后,数据的shape为 (1442, 8)

保存为新的csv文件:

daily_data.to_csv('household_power_consumption_days.csv'

2.2 评价指标

预测输出为七个值组成的向量,每个值代表预测的未来一周中每一天的耗电量。多步预测问题通常是对每一个预测时间步分别进行评价。有如下建议:

  • 每隔一定周期(例如预测1天、预测3天的模型)对技能进行评价;
  • 根据预测日期长短的不同对比模型(例如,擅长预测1天的模型与擅长预测5天的模型);

总功率的单位是千瓦,应该使用具有统一单位的误差度量方法。**均方根误差(RMSE)绝对平均误差(MAE)**都符合这个单位统一的要求,本文采用更常用的 RMSE。与MAE不同,RMSE对预测错误的惩罚更大。此问题的性能指标是从第1天到第7天的每天的的RMSE。用分数来评估模型的表现以帮助模型的选择,是便捷有效的方法。一个可用的评估分数是所有单日的 RMSE。自定义的 evaluate forecast() 函数可以实现这个功能。


2.3 训练集和测试集划分

使用前三年的数据训练预测模型,最后一年的数据评估模型。将数据按照标准周(星期天开始到星期六结束)进行划分。这对模型的选定是一种有效的方法,可以预测未来一周的耗电量。也有助于建模,模型可用于预测特定的一天(如周三)或整个序列。

以周为单位对数据进行处理,先截取测试数据,剩下的为训练数据。数据的最后一年是2010年,2010年的第一个星期天是1月3日,数据在2010年11月26日结束,最近的最后一个星期六是11月20日。一共46周的测试数据。下面提供测试数据集的第一行和最后一行每日数据以供确认。
在这里插入图片描述
由之前的统计可知(上文中的图),每日耗电量数据从2006年12月16日开始。数据集中的第一个周日是12月17日,这是第二行数据。将数据组织成标准周,可提供159个完整的标准周用于训练预测模型。
在这里插入图片描述
自定义的 split_dataset() 函数将每天的数据分成训练集和测试集,并将它们组织成标准周。特定的行偏移量用于使用数据集的知识拆分数据。然后使用NumPy的 split() 函数将分割的数据集组织为每周数据。此处注意 split() 函数的功能是等间距划分,如果数据能整除会报错。


2.4 前向验证

模型使用前向验证进行评估。流程为:先提供给模型一周的数据,预测第二周;接着给第二周的实际数据,用前两周的数据,预测第三周;然后给第三周的实际数据,使用前三周的数据,预测第四周,以此类推…在下面用输入数据和输出/预测数据来演示:

Input,  Predict
[Week1]  Week2
[Week1 + Week2]  Week3
[Week1 + Week2 + Week3]  Week4
...

在此数据集上评估预测模型的前向验证方法通过自定义的 evaluate_model() 函数实现。model_func 参数为函数名。提供的这个函数用来定义模型,拟合模型,并预测一周的用电量。然后,evaluate_model() 函数根据测试数据集对模型所做的预测进行求值。


2.5 朴素预测模型(简单模型)

在任何新的预测问题上,测试朴素预测模型是很重要的。朴素模型的预测结果定量地显示了预测问题的难度,并提供了一个标准性能(baseline),通过它可以评估更复杂的预测方法。本节比较三种针对家庭功率预测问题的简单预测方法:

  • 每日持久性预测;
  • 每周持久性预测;
  • 一年前每周的持久性预测;

2.5.1 每日持久性预测

该模型取预测期前最后一天(如周六)的有功功率,作为预测期内(周日至周六)每天的有功功率值。daily_persistence() 函数实现了该策略。

2.5.2 每周持久性预测

该模型预测取前一周的整个时间作为下一周的预测。这是基于下周将与本周非常相似的想法。weekly_persistence() 函数实现了该策略。

2.5.3 一年前每周的持久性预测

类似于利用上周预测下周的想法,即根据下周将与一年前的同一周相似的想法,使用52周前的观察周作为预测。year_persistence() 函数实现了该策略。


3. 完整代码

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import math
import sklearn.metrics as skm# 设置中文显示
plt.rcParams['font.sans-serif'] = ['Microsoft JhengHei']
plt.rcParams['axes.unicode_minus'] = Falsedef split_dataset(data):'''该函数实现以周为单位切分训练数据和测试数据'''# data为按天的耗电量统计数据,shape为(1442, 8)# 测试集取最后一年的46周(322天)数据,剩下的159周(1113天)数据为训练集,以下的切片实现此功能。train, test = data[1:-328], data[-328:-6]train = np.array(np.split(train, len(train)/7)) # 将数据划分为按周为单位的数据test = np.array(np.split(test, len(test)/7))return train, testdef evaluate_forecasts(actual, predicted):'''该函数实现根据预期值评估一个或多个周预测损失思路:统计所有单日预测的 RMSE'''scores = list()for i in range(actual.shape[1]):mse = skm.mean_squared_error(actual[:, i], predicted[:, i])rmse = math.sqrt(mse)scores.append(rmse)s = 0 # 计算总的 RMSEfor row in range(actual.shape[0]):for col in range(actual.shape[1]):s += (actual[row, col] - predicted[row, col]) ** 2score = math.sqrt(s / (actual.shape[0] * actual.shape[1]))print('actual.shape[0]:{}, actual.shape[1]:{}'.format(actual.shape[0], actual.shape[1]))return score, scoresdef summarize_scores(name, score, scores):s_scores = ', '.join(['%.1f' % s for s in scores])print('%s: [%.3f] %s\n' % (name, score, s_scores))def evaluate_model(model_func, train, test):'''该函数实现评估单个模型'''history = [x for x in train] # # 以周为单位的数据列表predictions = [] # 每周的前项预测值for i in range(len(test)):yhat_sequence = model_func(history) # 预测每周的耗电量predictions.append(yhat_sequence)history.append(test[i, :]) # 将测试数据中的采样值添加到history列表,以便预测下周的用电量predictions = np.array(predictions)score, scores = evaluate_forecasts(test[:, :, 0], predictions) # 评估一周中每天的预测损失return score, scoresdef daily_persistence(history):last_week = history[-1] # 获取之前一周七天的总有功功率value = last_week[-1, 0] # 获取前一周最后一天的总有功功率forecast = [value for _ in range(7)] # 准备7天预测return forecastdef weekly_persistence(history):last_week = history[-1] # 将之前一周的数据作为预测数据return last_week[:, 0]def week_one_year_ago_persistence(history):last_week = history[-52] # 将去年同一周的数据预测数据return last_week[:, 0]def model_predict_plot(dataset, days):train, test = split_dataset(dataset.values)#定义要评估的模型的名称和函数models = dict()models['daily'] = daily_persistencemodels['weekly'] = weekly_persistencemodels['week-oya'] = week_one_year_ago_persistenceplt.figure(figsize=(8,6), dpi=150)for name, func in models.items():score, scores = evaluate_model(func, train, test)summarize_scores(name, score, scores)plt.plot(days, scores, marker='o', label=name)plt.grid(linestyle='--', alpha=0.5)plt.ylabel(r'$RMSE$', size=15)plt.title('三种模型预测结果比较', color='blue', size=20)plt.legend()plt.show()if __name__ == '__main__':dataset = pd.read_csv('household_power_consumption_days.csv', header=0, infer_datetime_format=True, engine='c',parse_dates=['datetime'], index_col=['datetime'])days = ['sun', 'mon', 'tue', 'wed', 'thr', 'fri', 'sat']model_predict_plot(dataset, days)

运行该示例首先打印每个模型的总分数和每日分数。我们可以看到,周策略的表现优于日策略,一年前的一周数据预测当前周的策略表现最好。我们可以在每个模型的总体RMSE得分和每个预测日的得分中看到这一点。一个例外是第一天(星期天)的预测错误,在这一天,每日持久性模型的性能似乎优于两周策略。我们可以使用一年前的一周数据预测当前周的策略,以465.294千瓦的总RMSE作为性能基线,来评估其它复杂模型在该数据集上的表现。

actual.shape[0]:46, actual.shape[1]:7
daily: [511.886] 452.9, 596.4, 532.1, 490.5, 534.3, 481.5, 482.0actual.shape[0]:46, actual.shape[1]:7
weekly: [469.389] 567.6, 500.3, 411.2, 466.1, 471.9, 358.3, 482.0actual.shape[0]:46, actual.shape[1]:7
week-oya: [465.294] 550.0, 446.7, 398.6, 487.0, 459.3, 313.5, 555.1

在这里插入图片描述


下一篇文章介绍ARIMA模型实现用电量多步预测。
在这里插入图片描述


参考:
https://machinelearningmastery.com/naive-methods-for-forecasting-household-electricity-consumption/
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.resample.html?highlight=resample#pandas.DataFrame.resample
https://www.statsmodels.org/stable/generated/statsmodels.graphics.tsaplots.plot_acf.html?highlight=plot_acf
https://matplotlib.org/index.html


http://www.ppmy.cn/news/651084.html

相关文章

时间序列预测18:ConvLSTM 实现用电量/发电量预测

【时间序列预测/分类】 全系列60篇由浅入深的博文汇总:传送门 接上文,本文介绍了ConvLSTM模型实现用电量/发电量预测。 LSTM 处理用电量/发电量预测任务的文章: 【Part1】Encoder-Decoder LSTM 模型 实现用电量/发电量预测 【Part2】CNN-LST…

DeepAR代码详析(pytorch版)实现用电量预测

DeepAR代码详析(pytorch版)实现用电量预测 – 潘登同学的RNN学习笔记 文章目录 DeepAR代码详析(pytorch版)实现用电量预测 -- 潘登同学的RNN学习笔记 数据集说明数据预处理代码 构造模型Loss函数评估指标相关 utils工具类训练模型…

时间序列预测17:CNN-LSTM 实现用电量/发电量预测

【时间序列预测/分类】 全系列60篇由浅入深的博文汇总:传送门 接上文,本文介绍了CNN-LSTM模型实现单、多变量多时间步预测的家庭用电量预测任务。 文章目录 1. CNN-LSTM1.1 CNN 模型1.2 完整代码 1. CNN-LSTM 1.1 CNN 模型 卷积神经网络(CN…

时间序列预测14:CNN 实现用电量/发电量预测

【时间序列预测/分类】 全系列60篇由浅入深的博文汇总:传送门 文章目录 前言适用于多时间步预测的CNN模型1 单变量多步预测 CNN 模型1.1 业务需求1.2 1D CNN 模型1.3 完整代码 前言 与其他机器学习算法不同,卷积神经网络能够从序列数据中自动学习特征&a…

实训1:拉格朗日法插补用户用电量数据缺失值

实训1:拉格朗日法插补用户用电量数据缺失值 实训任务: 读取missing_data.csv表查询缺失值位置 3.使用SciPy库中的interpolate模块下的lagrange对数据进行拉格朗日插值使用数据查看是否存在缺失值,不存在则说明插值成功 查询缺失值位置 is…

大工业用电计费及其相关知识

电费计算方法主要分为大工业用电和一般工商业用电、农业生产用电用电、居民生活用电。 1、概念 大工业用电指受电变压器(含不通过受电变压器的高压电动机)容量在315千伏安及以上的下列用电: (1)以电为原动力&#xf…

时间序列预测:用电量预测 02 KNN(K邻近算法)

🌮开发平台:jupyter lab 🍖运行环境:python3、TensorFlow2.x ----------------------------------------------- 2022.9.16 测验成功 ---------------------------------------------------------------- 1. 时间序列预测&#x…

线性回归入门案例 家庭用电量预测

本博客是线性回归的入门案例,仅用到一阶线性回归 代码中用到的数据集下载地址 [link] https://pan.baidu.com/s/12wSIOVMQ3zS3jK0FcwkTSw[ python3版本代码段 导包 #导包 import numpy as np import matplotlib.pyplot as plt import pandas as pd import time…