时间序列特征构造:以电力负荷预测为例讲解(python语言)

article/2025/10/31 0:33:33

个人电气博文目录传送门
学好电气全靠它,个人电气博文目录(持续更新中…)

时间序列特征构造

时间序列问题,首先不管是回归问题,还是分类问题。

一个模型的好坏,决定因素由数据集的大小,特征值的选取和处理,算法。
其中最重要的是特征值的选取和处理。
今天余总来讲解下时间序列的特征构造问题。
该特征构造部分可以用于其他数值数据。

时间序列特征构造分类为 :时间特征,时间历史特征,时间交叉特征

时间特征

连续时间
持续时间,间隔时间

离散时间
年,季度,季节,月,星期,日,等
节假日,节假日第几天
上午,早上,中午,晚上
年初,年末,月初,月末,周内,周末
是否高峰时段,是否上班

时间历史特征

统计值
四分位数,中位数,平均值,偏度,峰度,离散系数

同期值:
如今天的8点和昨天的8点,
这周一和上周一

时间交叉特征

类别特征与类别特征:笛卡尔积

连续特征与类别特征:离散笛卡尔积,聚合特征(聚合指聚类后的类别特征)

连续特征与连续特征:一阶差分,二阶差分(即把数据和前后做差值,差值作为特征,一次差值为一阶差分)

时间特征构造代码
使用的包 pandas
个人pandas教程总结
pandas常用函数,个人常用的

时间模块讲解链接
python 日期和时间处理(time,datetime模块讲解)

时间特征构造
原始数据total_df.csv

给出的数据只有时间和负荷,
我们要从时间里提取出年,月,日,节假日,工作日等时间特征。

首先把文档里的时间数据格式由字符串转换到时间

total_df.loc[:, 'record_date'] = pd.to_datetime(total_df['record_date'],format='%Y-%m-%dT%H:%M:%S')

利用python里的time 函数模块,构造强时间指代特征:星期几(dow)、几号(dom)、几月(month)、哪一年(year)。代码如下:


# 几时# 星期几,其中dow为构造的新列
total_df.loc[:, 'dow'] = total_df['record_date'].apply(lambda x: x.dayofweek)# 几号,dom为构造的新列
total_df.loc[:, 'dom'] = total_df['record_date'].apply(lambda x: x.day)# 几月,month为构造的新列
total_df.loc[:, 'month'] = total_df['record_date'].apply(lambda x: x.month)# 几年,year为构造的新列
total_df.loc[:, 'year'] = total_df['record_date'].apply(lambda x: x.year)

利用time函数模块添加周末特征:通过0,1化添加周末特征,周末的特征为1,将文字数值化传入模型,具体代码如下:


#weekend,weekend_sat,weekend_sun 为构造的新列
total_df.loc[:,'weekend'] = 0
total_df.loc[:,'weekend_sat'] = 0
total_df.loc[:,'weekend_sun'] = 0
total_df.loc[(total_df['dow']>4), 'weekend'] = 1
total_df.loc[(total_df['dow']==5), 'weekend_sat'] = 1
total_df.loc[(total_df['dow']==6), 'weekend_sun'] = 1

添加特征:添加上下中旬,其特征分别表示为1/2/3,代码如下:

def period_of_month(day):if day in range(1, 11):return 1if day in range(11, 21):return 2else:return 3
#period_of_month为构造的新列total_df.loc[:, 'period_of_month'] = total_df['dom'].apply(lambda x: period_of_month(x))

添加上半月、下半月时间特征,其特征分别表示为1/2,代码如下:

def period2_of_month(day):if day in range(1, 16):return 1else:return 2
#period2_of_month为构造的新列total_df.loc[:, 'period2_of_month'] = total_df['dom'].apply(lambda x: period2_of_month(x))  

利用python 里的time函数模块再自定义函数,添加国庆节假日特征,如果满足月份为10,日期小于8,则为国庆节。代码如下:

total_df.loc[:, 'festival'] = 0total_df.loc[(total_df.month == 10) & (total_df.dom < 8), 'festival'] = 1  

天气特征构造
天气啥的一般是文字,(如晴,多云…)文字程序无法直接输入,需要先One-hot化。
one-hot方法有很多,介绍下pandas 包的吧
介绍pd.get_dummies
示例

import pandas as pd
df = pd.DataFrame([['green' , 'A'],['red'   , 'B'],['blue'  , 'A']])df.columns = ['color',  'class']
print('处理前')
print(df)
df1=pd.get_dummies(df)
print('处理后')
print(df1)

一阶差分,二阶差分啥的,pandas shift,diff就能搞定

data['use1']=data['use'].shift(1)#向下平移1
data['use2']=data['use'].shift(2)#向下平移2
data['use3']=data['use'].shift(3)##向下平移3
data['use1差值']=data['use'].diff(1)#前后 t和t-1差值
data['use2差值']=data['use'].diff(2)##t和t-2差值
data= data.dropna()#去空值

统计特征啥的,pandas 有函数了调,不讲解,如果这都不会,自己拿豆腐撞墙吧。

聚合特征:首先把各个样本聚类,然后把类别信息作为特征之一,传入到输入中,作为输入的一部分。

例子:负荷预测

处理好后的数据样子截图

数据已经对天气,节假日进行了处理。

误差函数


#statistic.py
import numpy as np
import math
import scipy.stats as stats#计算预测值真实值的均方误差
#actual 实际值
def meanSquareError(actual,pred):if (not len(actual) == len(pred) or len(actual) == 0):return -1.0total = 0.0for x in range(len(actual)):total += math.pow(actual[x]-pred[x],2)return total/len(actual)
# actual values实际值
#计算mse误差
def mse(actual,pred):if (not len(actual) == len(pred) or len(actual) == 0):return -1.0total = 0.0for x in range(len(actual)):total += math.pow(actual[x]-pred[x],2)return total/(len(actual)*1000000)# 计算预测值与实际值之间的归一化均方根误差(NRMSE)
#
def normRmse(actual,pred):if (not len(actual) == len(pred) or len(actual) == 0):return -1.0sumSquares = 0.0maxY = actual[0]minY = actual[0]for x in range(len(actual)):sumSquares += math.pow(pred[x]-actual[x],2.0)maxY = max(maxY,actual[x])minY = min(minY,actual[x])return math.sqrt(sumSquares/len(actual))/(maxY-minY)# 根据实际值计算预测值的均方根误差(RMSE)def Rmse(actual,pred):if (not len(actual) == len(pred) or len(actual) == 0):return -1.0sumSquares = 0.0for x in range(len(actual)):sumSquares += math.pow(pred[x]-actual[x],2.0)return math.sqrt(sumSquares/len(actual))#计算相对于实际值的预测值的绝对百分误差(MAPE)
def mape(actual,pred):if (not len(actual) == len(pred) or len(actual) == 0):return -1.0total = 0.0for x in range(len(actual)):total += abs((actual[x]-pred[x])/actual[x])return total/len(actual)#计算相对于实际值的预测值的绝对百分误差(MAPE)
def mae(actual,pred):if (not len(actual) == len(pred) or len(actual) == 0):return -1.0total = 0.0for x in range(len(actual)):total += abs(actual[x]-pred[x])return total/len(actual)

预测代码

import math
from tools import statistics#引入误差函数
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm
from pandas import read_csv
from pandas import DataFrame
from pandas import concat
# 将时间序列转换为监督学习问题
#n_in=24时即为将24小时的所有数据去预测24小时后的数据。
def series_to_supervised(data, n_in=1, n_out=1, dropnan=True):n_vars = 1 if type(data) is list else data.shape[1]df = DataFrame(data)cols, names = list(), list()# input sequence (t-n, ... t-1)for i in range(n_in, 0, -1):cols.append(df.shift(i))#当names += [('var%d(t-%d)' % (j+1, i)) for j in range(n_vars)]# forecast sequence (t, t+1, ... t+n)for i in range(0, n_out):cols.append(df.shift(-i))#向上平移即将下一天当前时间的actual功率平移当当前天,作为输出标签if i == 0:names += [('var%d(t)' % (j+1)) for j in range(n_vars)]else:names += [('var%d(t+%d)' % (j+1, i)) for j in range(n_vars)]# put it all togetheragg = concat(cols, axis=1)agg.columns = names# drop rows with NaN valuesif dropnan:agg.dropna(inplace=True)return agg
# 加载数据
dataset = read_csv('load.csv', header=0, index_col=0)
values = dataset.values
# 整数编码
# encoder = LabelEncoder()
# values[:,4] = encoder.fit_transform(values[:,4])
# ensure all data is float
values = values.astype('float32')
# normalize features 归一化特征
# scaler = MinMaxScaler(feature_range=(0, 1))
# scaled = scaler.fit_transform(values)
matrix_load = np.array(values)
matrix_load[:,0] = matrix_load[:,0]/1000#daily load 加载日负载数据,并将第一列功率每一个数除以1000# 异常值处理
k = 0
for j in range(0, matrix_load.shape[0]):
##如何一个数与前一个相差2(即2000)和与后一个相差2(2000)if(abs(matrix_load[j,0]-matrix_load[j-1,0])>2 and abs(matrix_load[j,0]-matrix_load[j+1,0])>2):k = k + 1##则这个数=(前一个+后一个)/2+(前一天的前一个+前一天的后一个)/2matrix_load[j,0] = (matrix_load[j - 1,0] + matrix_load[j + 1,0]) / 2 + matrix_load[j - 24,0] - matrix_load[j - 24 - 1,0] / 2sum = 0num = 0for t in range(1,8):if(j - 24*t >= 0):num = num + 1sum = sum + matrix_load[j - 24*t,0]#前一周以内每日同时数据之和(如星期一的4点,星期二的4点...)if((j + 24*t) < matrix_load.shape[0]):num = num + 1sum = sum + matrix_load[j + 24*t,0]#前一周的+后一周每日同时数据之和sum = sum / num#前后一周每日同时数据平均值# #如果当前数据与平均值相差超过3,则当前数据=平均值加或减3if(abs(matrix_load[j,0] - sum)>3):k = k + 1if(matrix_load[j,0] > sum): matrix_load[j,0] = sum + 3else: matrix_load[j,0] = sum - 3
print(k)
# print(matrix_load[1,0])
# shift all data by mean 去均值
shifted_value = matrix_load[:,0].mean()
matrix_load[:,0] -= shifted_value
for i in range(1, 9):matrix_load[:, i] = matrix_load[:, i] / 10shifted_valuei = matrix_load[:,i].mean()matrix_load[:,i] -= shifted_valuei
print(matrix_load.shape)
# frame as supervised learning
before = 24
end = 1
reframed = series_to_supervised(matrix_load, before, end)
print(reframed.shape)
# drop columns we don't want to predict
for i in range(76):reframed.drop(reframed.columns[[-1]], axis=1, inplace=True)
print(reframed.shape)
print(reframed.head())
# 划分训练集测试集
values = reframed.values
n_train_hours = values.shape[0] - 166*24
train = values[:n_train_hours, :]
test = values[n_train_hours:, :]
print('train:',n_train_hours,'test:',166*24)
# 划分输入和输出
train_X, train_y = train[:, :-end], train[:, -end]
print(train_X.shape, train_y.shape)
test_X, test_y = test[:, :-end], test[:, -end]
#改变数据形状 3D [samples, timesteps, features]
train_X = train_X.reshape((train_X.shape[0], before*77))
test_X = test_X.reshape((test_X.shape[0], before*77))
print(train_X.shape, train_y.shape, test_X.shape, test_y.shape)
# svr
# kernel='linear'时,为线性核,C越大分类效果越好,但有可能会过拟合(defaul C=1)
# kernel='rbf'时(default),为高斯核radial basis function,gamma值越小,分类界面越连续;gamma值越大,分类界面越“散”,分类效果越好,但有可能会过拟合
kernelList = ["rbf"]
names = ["true","radial basis"]
preds = []
preds.append(test_y)
for i in range(len(kernelList)):clf = svm.SVR(C=2.0, kernel=kernelList[i])clf.fit(train_X, train_y)predicted_values = clf.predict(test_X)mape = statistics.mape((test_y + shifted_value) * 1000, (predicted_values + shifted_value) * 1000)print('MAPE is ', mape)mae = statistics.mae((test_y + shifted_value) * 1000, (predicted_values + shifted_value) * 1000)print('MAE is ', mae)mse = statistics.meanSquareError((test_y + shifted_value) * 1000, (predicted_values + shifted_value) * 1000)print('MSE is ', mse)rmse = math.sqrt(mse)print('RMSE is ', rmse)nrmse = statistics.normRmse((test_y + shifted_value) * 1000, (predicted_values + shifted_value) * 1000)print('NRMSE is ', nrmse)preds.append(predicted_values)
# 结果
fig = plt.figure()
colors = ["g","r","b","c","m","y","k","w"]
legendVars = []
for j in range(len(preds)):print(j)x, = plt.plot(preds[j]+shifted_value, color=colors[j])legendVars.append(x)
plt.title("Svm (rbf) Multi")
plt.xlabel('Time(hour)')
plt.ylabel('Electricity load (*1e3 kW)')
plt.legend(legendVars, names)
plt.show()
fig.savefig('svr_mul_result.jpg', bbox_inches='tight')

说明:
本负荷预测:在特征方面有

1.天气,节假日,周末,工作日
2.将前面24小时的负荷日期气温等因素 来预测第25小时的负荷。有一定的同期日特征,可以考虑其他同期日,如上一周的同日同时等,这个看自己取舍。

当然你也可以考虑其他特征,特征并不是越多越好。

时间特征不仅仅可以用在回归上,分类啥的也可以。

区间负荷预测算例链接:电气论文:负荷区间预测(机器学习简单实现)

电气专业的计算机萌新 :余登武。写博文不容易,如果你觉得本文对你有用,请点个赞支持下,谢谢。

在这里插入图片描述
在这里插入图片描述


http://chatgpt.dhexx.cn/article/6iSF2Uww.shtml

相关文章

[负荷预测]基于灰色GM(1,1)模型的中长期电力负荷预测

目 录 一、灰色模型GM&#xff08;1,1&#xff09;原理 二、模型构建前检验 三、预测精度的检验 3.1 残差检验 3.2 后验差检验 四、灰色模型GM(1,1)算法 五、Matlab编程实现 5.1 程序代码 5.2 输出结果 5.3 结果检验 5.4 预测泛化 六、Python编程实现 6.1 程序…

基于注意力机制的 CNN-BiGRU 短期电力负荷预测方法

提出了一种基于 Attention 机制的CNN -BiGRU&#xff08;卷积神经网络双向GRU注意力机制&#xff09;短期电力负荷预测方法&#xff0c;该方法将历史负荷数据作为输入&#xff0c;搭建由一维卷 积层和池化层等组成的 CNN 架构&#xff0c;提取反映负荷复杂动态变化的高维特征…

电力负荷预测任务(基于GRU模型)

数据&#xff1a;2000-2002三年每小时的电力负载 程序以及数据链接&#xff08;如果受益&#xff0c;请给个关注和star&#xff09;&#xff1a;https://github.com/xzdLYL/electrical_load_prediction 任务目标&#xff1a;以2000&#xff0c;2001年数据训练模型&#xff0c…

机器学习练手---负荷数据预测

纸上得来终觉浅&#xff0c;得知此事要躬行 文章目录 前言一、数据清洗查看特征与label的关联程度查看特征自身的差异性。特征筛选 二、引入模型1.选择多元线性回归模型2.尝试预测 总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 简单记录一下机器…

电力负荷短期预测模型(基于ARIMA)

电力负荷预测 电力分析与预测一.导入数据二.数据的预处理三.基本描述性统计四.构建特征&#xff0c;模型准备①系统聚类法②K-means聚类 五.构建特征&#xff0c;建立预测模型①预测未来一天&#xff0c;各时段的电力负荷②预测未来几天总体电力负荷 电力分析与预测 根据提供的…

深度学习方法在负荷预测中的应用综述(论文阅读)

前言   本篇论文主要介绍了当下用于智能电网电力负荷预测的多种DL方法&#xff0c;并对它们的效果进行了比较。对于RMSE的降低效果上&#xff0c;集成DBN和SVM的方法RMSE降低显著&#xff0c;达到了21.2%。此外&#xff0c;PDRNN方法与ARIMA方法相比有很大的降低&#xff0c;…

电气论文:负荷区间预测(机器学习简单实现)

个人电气博文目录链接: 学好电气全靠它,个人电气博文目录(持续更新中…) 代码图 效果图 论文解锁,是解锁这个专栏。可以看这个专栏的所有文章。 讲解 本文:简单写的模型(未对数据进行降噪,降噪可以看我的小波分解博客。未对区间预测效果进行度量。自己写个公式就可以…

【负荷预测】长短期负荷预测(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️❤️&#x1f4a5;&#x1f4a5;&#x1f4a5; &#x1f389;作者研究&#xff1a;&#x1f3c5;&#x1f3c5;&#x1f3c5;主要研究方向是电力系统和智能算法、机器学…

基于BiGRU短期电力负荷预测方法

前言 大家好,我是阿光。 本专栏整理了《PyTorch深度学习项目实战100例》,内包含了各种不同的深度学习项目,包含项目原理以及源码,每一个项目实例都附带有完整的代码+数据集。 正在更新中~ ✨ 🚨 我的项目环境: 平台:Windows10语言环境:python3.7编译器:PyCharmPy…

[负荷预测]基于线性回归模型的中长期电力负荷预测

目录 一、中长期电力负荷预测 二、国家电网电力数据集 三、 Matlab编程实现 3.1 程序代码 3.2 多元线性回归模型 3.3 对2020年数据预测 一、中长期电力负荷预测 电力负荷预测是电力系统规划的重要组成部分&#xff0c;也是电力系统经济运行的基础&#xff0c;其对电力系…

【负荷预测】基于神经网络的负荷预测和价格预测(Matlab代码实现)

目录 1 概述 2 基于神经网络的负荷预测&#xff08;Matlab实现&#xff09; 2.1 代码 2.2 结果 2.3 回归树模型的进一步改进 3 基于神经网络的价格预测&#xff08;Matlab代码实现&#xff09; 4 阅读全文&#xff08;Matlab代码&#xff09; 1 概述 这个例子演示了…

LSTM-多变量-单时间步-pytorch-负荷预测(多时间步采用滚动预测)

问题描述 使用LSTM做负荷预测问题&#xff0c;数据共计456行&#xff0c;每一行3个特征&#xff0c;用过去N个时间段特征&#xff0c;预测未来第N1个时间点的特征&#xff0c;数据格式如下&#xff0c;用00:00:00-04:00:00的[feature1&#xff0c;feature2&#xff0c;feature…

【负荷预测、电价预测】基于神经网络的负荷预测和价格预测(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

Charles抓包web、手机、小程序配置

一、下载地址 二、web抓包 Charles Web抓包&#xff0c;启动Charles会自动与浏览器设置成代理&#xff0c;不需要进行过多的设置。接下来就是通过浏览器发送网络请求&#xff0c;Charles就会直接抓取到这些信息和响应信息。 1、抓取HTTPS协议 Charles配置 点击顶部菜单栏【He…

Charles抓包使用及常用问题

简介 Charles其实是一款代理服务器&#xff0c;通过成为电脑或者浏览器的代理&#xff0c;然后截取请求和请求结果达到分析抓包的目的。该软件是用Java写的&#xff0c;能够在Windows&#xff0c;Mac&#xff0c;Linux上使用&#xff0c;安装Charles的时候要先装好Java环境。 …

Charles抓包显示<unknown>解决方案

上篇 &#xff1a;Charles抓包微信小程序数据 charles抓包会出现&#xff0c;请求前都加了锁&#xff0c;具体地址为<unknown>的情况。 解决<unknown>问题 首先电脑上需要安装charles&#xff0c;然后需要设置手机上的WiFi设置&#xff0c;修改配置中的代理设置&a…

charles抓包配置具体操作步骤

Charles主要功能 截取Http和Https网络封包 支持重发网络请求&#xff0c;方便后端调试 支持修改网络请求参数 支持网络请求的截获并动态修改 支持模拟慢速网络 Charles下载安装 charles下载地址&#xff1a;https://www.charlesproxy.com/download/ 注&#xff1a; 浏览…

Charles抓包https接口指南

Charles抓包https接口 作为一名iOS攻城狮&#xff0c;如果你没有听说过青花瓷这款软件&#xff0c;我只能说你还是回家洗洗睡吧。 最近在写一个需求&#xff0c;服务端不知道怎么设计接口。我只好找来了一个又类似功能的app&#xff0c;想要一睹芳容。于是主角Charles软件开始…

Charles抓包 - 手机

目的&#xff1a;抓IOS、Android端接口数据&#xff0c;保证IOS、Android和电脑在同一网络下&#xff1a; 1、首先需要将 Charles 的代理功能打开&#xff0c;在 Charles 的菜单栏上选择 “Proxy”–>“Proxy Settings”&#xff0c;填入代理端口 8888&#xff0c;并且勾上…

抓包工具-Charles

目录 1.环境搭建 2.Charles的界面&功能介绍 2.1提供两种封包视图&#xff1a;Structure和Sequence 2.2模拟网速 2.3重复发送请求 2.4修改服务器返回内容 2.4.1断点功能Breakpoints 2.4.2重写功能Rewrite 2.4.3重定向MAP&#xff08;后面在介绍&#xff09; 2.5修改…