时间序列预测11:用电量预测 01 数据分析与建模

news/2024/11/19 7:40:41/

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


写在前面

通过之前有关LSTM的8遍基础教程和10篇处理时间序列预测任务的教程介绍,使用简单的序列数据示例,已经把LSTM的原理,数据处理流程,模型架构,Keras实现都讲清楚了。从这篇文章开始,将介绍有关时间序列预测和时间序列分类任务在真实数据集上的应用,你可以以此为模板,针对自己的业务需求进行二次开发。在本系列文章的最后会尝试通过自动调参脚本来辅助优化模型。


代码环境:

  • python 3.7.6
  • tensorflow 2.1.0
  • keras 2.3.1

本文所有代码在 jupyter notebook 中编写。


文章目录

  • 写在前面
  • 1. 家庭用电量预测--数据分析
    • 1.1 数据集介绍
    • 1.2 数据加载与处理
    • 1.3 数据随时间变化规律
    • 1.4 时间序列数据分布
  • 2 建模建议
    • 2.1 业务需求
    • 2.2 数据准备
    • 2.3 建模方法
      • 2.3.1 朴素方法
      • 2.3.2 经典线性方法
      • 2.3.3 机器学习方法
      • 2.3.4 深度学习方法


1. 家庭用电量预测–数据分析

其实家庭用电量预测仅仅是个“引子”,如果有电网数据的话,可以开发适合业务需求的模型,比如通过预测各时段各区域的用电量来协助电网更好地实现电能调度;除此之外,还可以用于发电量预测,比如光伏电站、风力发电站、水电站发电量预测…等等。模型一般不是问题,关键在数据和数据处理。

本文将介绍使用Pandas和Matplotlib对UCI上的家庭用电量数据集进行可视化,针对用电量预测问题,探究不同的网络架构、数据准备方式以及建模方法。
在这里插入图片描述

Gulf of Mexico, United States, photo by NASA

在这里插入图片描述

Lincoln, United States, photo by American Public Power Association

在这里插入图片描述

Niksic, Montenegro, photo by Appolinary Kalashnikova

1.1 数据集介绍

数据集名称为:Individual household electric power consumption Data Set(点击跳转数据集下载页面),该数据集是一个多变量时间序列数据集,采集了法国巴黎一个家庭近四年(2006年12月至2010年11月)的用电量,采样周期为1分钟。数据集的属性信息如下:

  1. date:格式dd/mm/yyyy;
  2. time:格式hh:mm:ss;
  3. global_active_power:每分钟的有功功率(千瓦);
  4. global_reactive_power:每分钟的无功功率(千瓦);
  5. voltage:每分钟的平均电压(伏特);
  6. global_intensity:每分钟的平均电流强度(安培);
  7. sub_metering_1:厨房有功电能(瓦时),主要包含洗碗机,烤箱和微波炉;
  8. sub_metering_2:于洗衣房有功电能(瓦时),包含洗衣机,滚筒式烘干机,冰箱和电灯;
  9. sub_metering_3:电热水器和空调有功电能(瓦时)。

为了避免翻译错误引起歧义,现贴出数据集属性的英文介绍如下文所示:

  1. date: Date in format dd/mm/yyyy
  2. time: time in format hh:mm:ss
  3. global_active_power: household global minute-averaged active power (in kilowatt)
  4. global_reactive_power: household global minute-averaged reactive power (in kilowatt)
  5. voltage: minute-averaged voltage (in volt)
  6. global_intensity: household global minute-averaged current intensity (in ampere)
  7. sub_metering_1: energy sub-metering No. 1 (in watt-hour of active energy). It corresponds to the kitchen, containing mainly a dishwasher, an oven and a microwave (hot plates are not electric but gas powered).
  8. sub_metering_2: energy sub-metering No. 2 (in watt-hour of active energy). It corresponds to the laundry room, containing a washing-machine, a tumble-drier, a refrigerator and a light.
  9. sub_metering_3: energy sub-metering No. 3 (in watt-hour of active energy). It corresponds to an electric water-heater and an air-conditioner.

以上九个属性中,可以作为特征的有七个,去掉的两个是日期和时间,因为序列化数据已经包含先后顺序了,所以不需要时间和日期数据,因此可以使用的数据为一个由七个变量(特征)组成的多元序列。


最后三个属性统计的电能消耗并不是家里所有的电路电能消耗。其它的电能消耗可以通过下式计算:
r e m a i n d e r = g l o b a l _ a c t i v e _ p o w e r × 1000 60 − ( s u b _ m e t e r i n g _ 1 + s u b _ m e t e r i n g _ 2 + s u b _ m e t e r i n g _ 3 ) remainder = \frac {global\_active\_power \times 1000}{60}− (sub\_metering\_1 + sub\_metering\_2 + sub\_metering\_3) remainder=60global_active_power×1000(sub_metering_1+sub_metering_2+sub_metering_3)
这里注意:有功功率单位为 K W KW KW,有功电能的单位为瓦时( w a t t − h o u r watt-hour watthour),以上数据都是间隔一分钟测得的,因此公式的前半部分就是通过有功率乘以时间(1/60小时,也就是一分钟)计算得到总的有功电能消耗,单位是瓦时。减去公式的后半部分(后三个属性的加和),得到了家庭中其他电路的电能消耗。

该数据集已成为评估时间序列预测和多步预测(特别是预测有功功率)的机器学习方法的标准,接下来我们来探究该数据集。


1.2 数据加载与处理

在加载之前,先查看数据详情信息:
在这里插入图片描述
查看是否有异常数据:
在这里插入图片描述
使用Pandas中的 read_csv() 函数加载数据,如果是excel或者csv文件通常不用考虑分隔方式,用默认的配置就可以加载;但是对于 txt 文件则需要考虑,可以看到数据集是用 ; 来分隔数据的,下面加载数据:

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'])

read_csv() 参数说明:

  • seq 参数:指定列之间的分隔符为 ';',字符串格式,默认为 ‘,’
  • header 参数:指定哪一行作为列名,header=0 表示第一行数据作为列名,而不是文件的第一行作为列名;
  • low_memory:在内部对文件进行分块处理,从而在解析时减少了内存使用,但可能是混合类型推断。默认为 True,设置为 False 确保没有混合类型;
  • infer_datetime_format:设置该参数为 Trueparse_dates 参数,pandas会推断列中日期时间字符串的格式,如果可以推断出,则切换到更快方法来解析它们。在某些情况下,这可以使解析速度提高5-10倍;
  • engine:要使用的解析器引擎。C引擎速度更快,而python引擎当前功能更完善;
  • parse_dates{'datetime':[0,1]} 将原数据中的第1、2列作为新的列名为 ‘datatime’ 的列,即将原来的日期列、时间列合并为日期时间一列;
  • index_col:指定’datetime’列为索引列;

更多参数配置,请查看官方文档:👉点开它带走我


1. 查看数据的shape:

dataset.shape

输出:

(2075259, 7)

2. 查看数据前10行:

dataset.head(10)

输出:
在这里插入图片描述
3. 查看缺失值:

dataset.isna().sum()

输出:

Global_active_power          0
Global_reactive_power        0
Voltage                      0
Global_intensity             0
Sub_metering_1               0
Sub_metering_2               0
Sub_metering_3           25979
dtype: int64

4. 查看有默认标记的异常值:

dataset.iloc[dataset.values == '?'].count()

输出:

Global_active_power      155874
Global_reactive_power    155874
Voltage                  155874
Global_intensity         155874
Sub_metering_1           155874
Sub_metering_2           155874
Sub_metering_3                0
dtype: int64

5. 有默认标记的异常值处理
为了提高数据处理效率,将所有标记为’?'的异常值用 np.nan 替换,将数据作为一个浮点值数组来处理。

dataset.replace('?', np.nan, inplace=True)

再查看异常值:

dataset.iloc[dataset.values == '?'].count()

输出:

Global_active_power      0
Global_reactive_power    0
Voltage                  0
Global_intensity         0
Sub_metering_1           0
Sub_metering_2           0
Sub_metering_3           0
dtype: int64

再查看缺失值:

dataset.isna().sum()

输出:

Global_active_power      25979
Global_reactive_power    25979
Voltage                  25979
Global_intensity         25979
Sub_metering_1           25979
Sub_metering_2           25979
Sub_metering_3           25979
dtype: int64

6. 添加新列
使用上一节中计算剩余用电量的计算公式,添加新列作为新的特征序列:

values = dataset.values.astype('float32')
dataset['sub_metering_4'] = (values[:,0] * 1000 / 60) - (values[:,4] + values[:,5] + values[:,6]))

查看新的数据shape:

dataset.shape

输出:

(2075259, 8)

查看数据前十行:

dataset.head(10)

输出:
在这里插入图片描述

7. 保存为新的文件:

dataset.to_csv('household_power_consumption.csv')

1.3 数据随时间变化规律

1. 首先读取新保存的数据:

dataset = pd.read_csv('household_power_consumption.csv', header=0, infer_datetime_format=True, engine='c',parse_dates=['datetime'], index_col=['datetime'])

2.绘制不同特征的子图:
创建一个包含八个子图的图像,每个子图对应一个变量。完整代码如下:

def plot_features(dataset):plt.figure(figsize=(16,12), dpi=200)for i in range(len(dataset.columns)):plt.subplot(len(dataset.columns), 1, i+1)feature_name = dataset.columns[i]plt.plot(dataset[feature_name])plt.title(feature_name, y=0)plt.grid(linestyle='--', alpha=0.5)plt.tight_layout()plt.show()plot_features(dataset)

输出:
在这里插入图片描述


3. 每年的有功功率变化图
为每一年创建一个有功功率图,观察是否有相同的模式。因为2006年只有不到一个月的数据,所以不绘制该年的子图。完整代码如下:

def plot_year_gap(dataset, years_list):plt.figure(figsize=(16,12), dpi=150)for i in range(len(years_list)):ax = plt.subplot(len(years_list), 1, i+1)ax.set_ylabel(r'$KW$')year = years_list[i]year_data = dataset[str(year)]plt.plot(year_data['Global_active_power'])plt.title(str(year), y=0, loc='left')plt.grid(linestyle='--', alpha=0.5)plt.xticks(rotation=0)plt.tight_layout()plt.show()years = ['2007', '2008', '2009', '2010']
plot_year_gap(dataset, years)

输出:
在这里插入图片描述
因为设置了 infer_datetime_format 参数,所以可直接使用年份索引进行截取数据。通过对以上数据进行分析可知,每年2月和8月内的某段时间耗电量有明显下降。我们似乎也看到夏季(6、7、8月)的用电量呈下降趋势,我们还可以在第以、第三和第四个图中有一些缺失的数据。

接下来,进一步查看每个月的用电情况。比如查看2008年每个月的有功功率,可能有助于梳理出几个月的变化规律,如每日和每周用电状况规律。完整代码如下:

def plot_month_gap(dataset, year, months_list):plt.figure(figsize=(16,12), dpi=150)for i in range(len(months_list)):ax = plt.subplot(len(months_list), 1, i+1)ax.set_ylabel(r'$KW$')month = str(year) + '-' + str(months_list[i])month_data = dataset[month]plt.plot(month_data['Global_active_power'])plt.title(month, y=0, loc='left')plt.grid(linestyle='--', alpha=0.5)plt.xticks(rotation=0)plt.tight_layout()plt.show()year = 2008
months = [i for i in range(1, 13)]
plot_month_gap(dataset, year, months)

输出:
在这里插入图片描述

接下来进一步查看每日的用电情况。完整代码如下:

def plot_day_gap(dataset, year, month, days_list):plt.figure(figsize=(20,24), dpi=150)for i in range(len(days_list)):ax = plt.subplot(len(days_list), 1, i+1)ax.set_ylabel(r'$KW$',size=6)day = str(year) + '-0' + str(month) + '-' + str(days_list[i])day_data = dataset[day]gcp_data = day_data['Global_active_power']plt.plot(gcp_data)plt.title(day, y=0, loc='left', size=6)plt.grid(linestyle='--', alpha=0.5)plt.xticks(rotation=0)plt.show()year = 2008
month = 8
days = [i for i in range(1, 32)]
plot_day_gap(dataset, year, month, days)

输出:
在这里插入图片描述


1.4 时间序列数据分布

另一个需要考虑的重要方面是变量的分布。例如,了解观测值的分布是高斯分布还是其他分布。可以通过为每个特征创建一个直方图来研究数据分布。完整代码如下:

def dataset_distribution(dataset):plt.figure(figsize=(16,12), dpi=150)for i in range(len(dataset.columns)):ax = plt.subplot(len(dataset.columns), 1, i+1)ax.set_ylabel(r'$numbers$',size=10)feature_name = dataset.columns[i]dataset[feature_name].hist(bins=100)plt.title(feature_name, y=0, loc='right', size=20)plt.grid(linestyle='--', alpha=0.5)plt.xticks(rotation=0)plt.tight_layout()plt.show()dataset_distribution(dataset)

输出:
在这里插入图片描述
可以看到有功和无功功率、强度以及分表功率都是向瓦时或千瓦倾斜的分布,电压数据呈高斯分布。有功功率的分布似乎是双峰的,这意味着它看起来有两组观测值。可以通过查看四年来的数据的有功功率分布来验证,完整代码如下:

def plot_year_dist(dataset, years_list):plt.figure(figsize=(16,12), dpi=150)for i in range(len(years_list)):ax = plt.subplot(len(years_list), 1, i+1)ax.set_ylabel(r'$numbers$')ax.set_xlim(0, 5) # 设置x轴显示限制,保证每个子图x刻度相同year = years_list[i]year_data = dataset[str(year)]year_data['Global_active_power'].hist(bins=100, histtype='bar')plt.title(str(year), y=0, loc='right', size=10)plt.grid(linestyle='--', alpha=0.5)plt.xticks(rotation=0)plt.tight_layout()plt.show()years = ['2007', '2008', '2009', '2010']
plot_year_dist(dataset, years)

输出:
在这里插入图片描述

可以看到,有功功率分布看起来非常相似。这种分布确实是双峰的,一个峰值约为0.3kw,另一个峰值约为1.3kw。随着有功功率(x轴)的增加,高功率用电时间点的数量越来越少。


所确定的群体可能在一年中的不同季节有所不同。可以通过查看一年中每个月的有功功率分布来对此进行调查。完整代码如下:

def plot_month_dist(dataset, year, months_list):plt.figure(figsize=(16,12), dpi=150)for i in range(len(months_list)):ax = plt.subplot(len(months_list), 1, i+1)ax.set_ylabel(r'$KW$')ax.set_xlim(0, 5)month = str(year) + '-' + str(months_list[i])month_data = dataset[month]month_data['Global_active_power'].hist(bins=100, histtype='bar')plt.title(month, y=0, loc='right', size=10)plt.grid(linestyle='--', alpha=0.5)plt.xticks(rotation=0)plt.tight_layout()plt.show()year = 2008
months = [i for i in range(1, 13)]
plot_month_dist(dataset, year, months)

输出:
在这里插入图片描述
可以看到,在北半球较暖的月份(法国巴黎),有功功率比较大的点少,而在较冷的月份,有功功率比较大的点多。在12月到3月的较冷月份,可以看到有更大的千瓦值(大约 3.7 − 4 K W 3.7-4KW 3.74KW)。


2 建模建议

2.1 业务需求

对于我们使用的家庭用电量数据集来说,可以提出很多建模问题,比如:

  • 预测一天内每小时的耗电量;
  • 预测一周内每天的耗电量;
  • 预测一月内每天的耗电量;
  • 预测一年内每天的耗电量。

以上四类预测问题称为多步预测。利用所有特征进行预测的模型称为多变量多步预测模型。每个模型都不局限于日期的大小,还可以根据需求对更细粒度的问题进行建模,比如一天内某各时段每分钟的耗电量预测问题。这有助于电力公司进行电能调度,是一个广泛研究的重要问题。


2.2 数据准备

在为建模准备这些数据时有很大的灵活性。具体的数据准备方法及其效益实际上取决于问题的框架选择和建模方法。然而,以下是可能有用的一般数据准备方法的列表:

  • 每日差异可能有用,以调整数据中的每日周期。
  • 年度差异可能有助于调整数据中的任何年度周期。
  • 标准化可能有助于将不同单位的变量减少到相同的比例

有许多简单的人为因素可能有助于从数据中提取工程特征,从而使特定日期更易于预测。一些例子包括:

  • 表示一天中的时间,以说明人们是否有可能在家。
  • 指示一天是工作日还是周末。
  • 表示一天是否为北美公共假日。这些因素对预测月度数据的重要性可能会大大降低,在一定程度上对周数据的重要性可能也会降低。
  • 更一般的特征可能包括:表示季节,这可能导致使用的环境控制系统的类型或数量。

2.3 建模方法

对于这个问题,可能有四类方法值得探讨:

  1. 朴素方法;
  2. 经典线性方法;
  3. 机器学习方法;
  4. 深度学习方法;

2.3.1 朴素方法

朴素的方法包括一些非常简单但通常非常有效的假设。例如:

  • 明天和今天一样;
  • 明天和去年的今天一样;
  • 明天是过去几天的平均值;

2.3.2 经典线性方法

经典的线性方法适用于单变量时间序列预测问题。常用的方法有:

  • SARIMA(季节自回归综合移动平均)
  • ETS(三重指数平滑)

2.3.3 机器学习方法

机器学习方法要求将问题构造为有监督学习问题。这将要求将序列的滞后观测值作为输入特征,丢弃数据中的时间关系。常用的非线性和集成方法有:

  • k近邻算法
  • SVM
  • 决策树
  • 随机森林
  • GBM(Gradient Boosting Machines)

为了确保模型拟合和评估,要保留数据中的时间结构,需要做大量的特征工程,来增加特征,专业程度较高。当有多个特征时,可能变得对业务需求不适用。


2.3.4 深度学习方法

一般来说,神经网络在自回归型问题上并没有被证明是非常有效的。然而,卷积神经网络等技术能够从原始数据(包括一维信号数据)中自动学习复杂特征。而递归神经网络,例如LSTM,能够直接在多个输入数据的并行序列中学习。此外,这些方法的组合如CNN-LSTM和ConvLSTM等方法,在时间序列分类任务中被证明是有效的。这些方法可以处理大量数据和多个输入变量(特征)任务。


之后文章会介绍以上提到的的建模方法。


参考:
https://matplotlib.org/index.html
https://matplotlib.org/api/_as_gen/matplotlib.pyplot.tight_layout.html#matplotlib.pyplot.tight_layout
https://matplotlib.org/api/_as_gen/matplotlib.pyplot.subplot.html?highlight=subplot#matplotlib.pyplot.subplot
http://www.imooc.com/wenda/detail/574859
https://machinelearningmastery.com/how-to-load-and-explore-household-electricity-usage-data/


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

相关文章

python用支持向量机回归(SVR)模型分析用电量预测电力消费

最近我们被客户要求撰写关于支持向量机回归的研究报告,包括一些图形和统计输出。 本文描述了训练支持向量回归模型的过程,该模型用于预测基于几个天气变量、一天中的某个小时、以及这一天是周末/假日/在家工作日还是普通工作日的用电量。 【视频】支持向…

算力网络:十大技术发展方向

摘自:https://mp.weixin.qq.com/s/yykVHtdUVGL7G9E1jtMIxg 在社会算力并网场景下,将联合超算、智算等社会算力开展算力并网验证;在云边端协同场景下,打造算网融合创新技术方案,探索算网大脑雏形,深入车联网…

全国281个地级市工业用电量数据(2003-2016)

数据集名称:全国281个地级市工业用电量数据 时间范围:2003-2016年 数据来源:EPS数据库 相关说明:工业用电大多使用三相电压,如三相380VAC,三相660VAC等。 工业用电与居民用电的区别:工业用电…

时间序列预测:用电量预测 05 BP神经网络

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

用电量专题-全国、煤炭行业、地级市工业用电量等多指标(部份内容已更新至2021)

一、全国历年逐月累计用电量 1、数据来源:国际电力网电力统计每月统计的数据 2、时间跨度:2004-2021年9月 3、区域范围:全国 4、指标说明: 全社会用电量 第一产业用电量 第二产业用电量 第三产业用电量 城乡居民生活用电量…

时序数据-LSTM模型-实现用电量预测

作者: 明天依旧可好 QQ交流群: 807041986 原文链接: https://mtyjkh.blog.csdn.net/article/details/115612319 深度学习系列:深度学习 我的环境: win10、jupyter notebook、tensorflow2 0.导入相关包设置相关参数 i…

电网大屏报表的制作--全国用电量分析

2018 年已经过半,各省又开始比考试成绩了,考试科目就叫 GDP,排在前面的自然扬眉吐气,排在后面的,就灰头土脸了,同样都是大省份,同样都是直辖市,为啥你排名靠前,我却垫了底…

冷库用电量计算机方式,冷库耗电量计算方法(附计算公式)

单位产品耗电量是将冷库内制冷用电和冷库风机有电分配于各种冷冻品和冷藏品中,其中制冷用电包括压缩机和其他用电(如氨泵. 水泵用电等),冻结间风机耗电由冷冻品负担,冷却物冷藏间风机耗电由冷却冷产品负担。雅俗家耗电按单位冷量耗电计算&…