负荷预测是一个长久的研究课题
本文提供一个负荷预测的代码仅供参考
导入包
import datetime
from darts import TimeSeries
from darts.datasets import AirPassengersDataset
from darts.models import NBEATSModel
from darts.dataprocessing.transformers import Scaler
# 解决中文显示问题
import matplotlib.pyplot as plt
# todo:每天将新数据再次用于训练后,并预测
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# path_url = '你的文件路径'
N_list = [5] # 使用前N天的数据作为输入,预测第8天数据
Train_Month = 2 # 使用前Train_Month个月的数据作为训练集
读取数据
def read_data(path_url):
df_15min = pd.read_csv(path_url)
res1 = pd.to_datetime(df_15min['stat_time'])
df_15min_after = df_15min.set_index(res1)
mp_7932_series1 = df_15min_after['mp_7932']
conv_h_d = df_15min_after[['h_d', 'd_w']]
return mp_7932_series1, conv_h_d
划分验证与测试集合
def split_train_test(mp_7932_series1, conv_h_d, N,i):
train_length = int((Train_Month * 30+20+i) * 96) # 前8个月的数据点数
labels = mp_7932_series1.index[train_length:]
val_data = mp_7932_series1[train_length - N * 96:]
sales_ts = TimeSeries.from_series(mp_7932_series1)
conv_ts = TimeSeries.from_series(conv_h_d)
# 划分训练集和验证集,这里假设前8个月的数据用于训练,其余用于预测
train_series = sales_ts[:train_length]
val_series = sales_ts[train_length:]
conv_h_d_train = conv_ts[:train_length] # 用于训练的conv
conv_h_d_val = conv_ts[train_length - N * 96:] # 用于验证的conv
val_ts = sales_ts[train_length - N * 96:] # 验证集
scaler_train = Scaler()
scaler_val = Scaler()
val_ts_sca = Scaler()
train_scaled = scaler_train.fit_transform(train_series) # 归一化数据
val_scaled = scaler_val.fit_transform(val_series)
val_ts_scaled = val_ts_sca.fit_transform(val_ts)
return train_scaled, val_ts, val_ts_scaled, val_ts_sca, conv_h_d_train, conv_h_d_val, val_series
写评价指标代码
def get_MAPE(real_data, predict_data):
new_real = []
new_pred = []
for i in range(len(real_data)):
if real_data[i] != 0:
new_real.append(real_data[i])
new_pred.append(predict_data[i])
new_real, new_pred = np.array(new_real), np.array(new_pred)
# MAPE1 = np.mean(np.abs(real_data - predict_data) / np.mean(real_data))
MAPE = np.mean(np.abs(new_real - new_pred) / np.abs(new_real))
return 1 - abs(MAPE)
加载模型
def load_model(N, train_flag, num_blocks, num_layers, layers_widths,model_url):
if train_flag:
nbeats_model = NBEATSModel(input_chunk_length=96 * N, output_chunk_length=96, n_epochs=1, num_blocks=num_blocks,
num_layers=num_layers, layer_widths=layers_widths)
else:
nbeats_model = NBEATSModel.load(model_url)
return nbeats_model
计算误差
def caculatemape(model, val_ts_scaled, val_series, conv_h_d_val, val_ts_sca, N, num_blocks, num_layers, layers_widths):
res_mape = []
for n in range(1):
index_7days = val_ts_scaled[n * 96:96 * (n + N)]
past_conv = conv_h_d_val[n * 96:96 * (n + N)]
pred1 = model.predict(series=index_7days, n=96, past_covariates=past_conv)
pred1 = val_ts_sca.inverse_transform(pred1)
real_data = val_series[96 * (n):96 * (n + 1)]
pred1.plot(label='pred')
real_data.plot(label='true')
real_data = real_data.values()
pred1_re_scaled = pred1.values()
mape = get_MAPE(real_data, pred1_re_scaled)
day = datetime.datetime.now().strftime('%y-%m-%d')
fig_floder = ('./T_test_Nbeats' + day + 'N_' + str(N)
+ 'num_blocks_' + str(num_blocks)
+ 'num_layers_' + str(num_layers)
+ 'layers_widths_' + str(layers_widths)
+ 'result_fig')
fig_save = fig_floder + '/mape_' + str(mape) + '.jpg'
if not os.path.exists(fig_floder):
os.mkdir(fig_floder)
plt.savefig(fig_save)
plt.close()
res_mape.append(mape)
return res_mape
模型训练代码
def train_model(model, train_scaled, conv_h_d_train,
val_ts_scaled, val_series, conv_h_d_val, val_ts_sca, N, num_blocks, num_layers, layers_widths):
'''
:param model: 模型
:param train_scaled:归一化后的训练数据
:param conv_h_d_train: 训练相关的conv
:param val_ts_scaled: 验证集的
:param val_series:
:param conv_h_d_val:
:param val_ts_sca:
:return:
'''
epoch = 1
# epoch = 1
best_mape = 0.0
count = 0
for i in range(epoch):
model.fit(train_scaled, past_covariates=conv_h_d_train)
res_mape = caculatemape(model, val_ts_scaled, val_series, conv_h_d_val, val_ts_sca, N, num_blocks, num_layers,
layers_widths)
print(res_mape)
now_mean_mape = np.mean(res_mape)
if now_mean_mape > best_mape:
print("有更加优秀的结果,mape为:\t", now_mean_mape)
best_mape = now_mean_mape
day = datetime.datetime.now().strftime('%y-%m-%d')
foldername = ('./T_test_NBeats' + day + 'N_' + str(N) + 'num_blocks_' +
str(num_blocks) + 'num_layers_' +
str(num_layers) + 'layers_widths_' +
str(layers_widths) + 'Nbeats_Model/')
if not os.path.exists(foldername):
os.mkdir(foldername)
save_url = foldername + '/NBeats_mape_' + str(round(best_mape, 4)) + '.pth'
best_url = foldername + '/NBeats_best.pth'
model.save(save_url)
model.save(best_url)
count = 0
else:
count += 1
if count > 10:
print("超过10次未更加优化")
break