之前我们已经在配水管网中使用了不同的用水系数乘子,本次我们想使用LSTM算法来预测节点用水量,压力的时间序列。
按照特征工程与实际的专业知识,我们使用滑动窗口的平移输入,以7天为一个周期,输入7天的节点流量,预测第八天的相同节点流量。代码如下
1.首先我们要生成2个月的节点用水数据,按照15min的间隔生成:详情参考用水波动真实性一文https://blog.csdn.net/wenxiaoshuai001/article/details/117390651?spm=1001.2014.3001.5501
2.间断模拟产生数据,参考上一文https://blog.csdn.net/wenxiaoshuai001/article/details/117425098?spm=1001.2014.3001.5501
import wntr
import pandas as pd
import numpy as np
inp_file = 'c:/Users/wen EX/Desktop/WNTR-master/examples/networks/STUDY1.inp'
wn = wntr.network.WaterNetworkModel(inp_file)
#首先调整一下我们的设置参数,主要是pattern_timestep设置成15min,因为我们的传感器是15min的,设置压力驱动,水力计算时间和报告时间步长
wn.options.hydraulic.demand_model = 'PDD'
wn.options.time.hydraulic_timestep = 15*60
wn.options.time.pattern_timestep = 15*60
wn.options.time.report_timestep = 15*60
#调整一下初始的水量,不然有时候乘子太大会导致需水量过高出现负压
for junction_names, junction in wn.junctions():
junction.demand_timeseries_list[0].base_value =junction.demand_timeseries_list[0].base_value*0.5
#创建一个字典,到时候键是天数,值是模拟的结果
result = {}
#传入数据,一共是365天的
data = pd.read_csv('../patdata.csv',index_col=0)
#因为要使用动态变量名,这里使用的是命名空间的方法
names = locals()
for i in range(1,4):
#添加用水模式,命名备用
wn.add_pattern('day'+str(i)+'pat',data.loc[i,:].to_list())
#循环迭代所有的junction,这里的junction.demand_timeseries_list不能直接改,我们添加另一个用水模式然后把原先的模式删除了
for junction_names, junction in wn.junctions():
junction.add_demand(base=junction.demand_timeseries_list[0].base_value, pattern_name='day'+str(i)+'pat')
#删除第一个 保留第二个,第二个的用水模式就是我们创建的乘子
del junction.demand_timeseries_list[0]
#使用wntr的模拟器,可以通过实践不同来断点模拟,我们每天都断点一次
wn.options.time.duration = i * 24 * 3600
sim = wntr.sim.WNTRSimulator(wn)
names['day'+str(i)+'result']=sim.run_sim()
#传入字典
result[i] = names['day'+str(i)+'result']
#打印字典各个元素
# demand = result[2].node['demand']
# print(len(demand.loc[:,'3']))
# print(result)
#输出各个结点的我们关心的特征,参考专业知识,我们一般在结点关注结点的压力特征
for i in range(1,4):
result[i].node['pressure'].to_csv(r'../wntr-data/day'+str(i)+'pressure data.csv')
3.此时我们生成了每一天为一个excel表格,每一个表格的colum是node的编号,每一个index是时间:
如图所示,该表格是第二天的各个结点pressure值。
此时我们的任务是查看某一个特定的结点,把所有的时间串联起来,成为一个时间的序列,每一天有96个值(15min的间隔采样24小时:244),我们暂时确定用一周的时间来作为输入(7乘96),得到第八天的244的预测值(估计比较困难,lstm对长时间的预测感觉精度比较低):
start = result[1].node['pressure']
for i in range(2,4):
data_day = result[i].node['pressure']
start =pd.concat([start,data_day])
start.to_csv(r'../wntr-data/pressure data.csv')
直接用该方式就可以拼接全部的压力数据,接下来我们就可以读取特定点的数据进行预测了