在本篇案例中,我们将基于来自FRED(美国联邦储备经济数据库)的电力和天然气生产指数数据进行时间序列分析和预测。该数据涵盖从1992年1月至2019年1月(共325个记录)的工业生产指数变化情况。

数据来源:

数据来自:https://fred.stlouisfed.org/series/IPG2211A2N

1. 数据加载和预处理

        首先,我们使用pandas加载数据,并删除缺失值。为了便于时间序列预测,我们将数据分成训练集和测试集。

df = pd.read_csv('../data/Energy_Production.csv',index_col=0,parse_dates=True)
df.dropna(inplace=True)
print(len(df))
df.head()

2. 数据可视化

        我们绘制了工业生产指数的时间序列图,展示了从1992年到2019年电力和天然气生产的变化趋势。

plt.figure(figsize=(12,4))
plt.title('Industrial Production Index for Electricity and Gas Utilities')
plt.ylabel('Index 2012=100, Not Seasonally Adjusted')
plt.grid(True)
plt.autoscale(axis='x',tight=True)
plt.plot(df['IPG2211A2N'])
plt.show()

3. 数据准备

3.1 划分训练集和测试集

        我们将数据分为训练集和测试集,训练集包含313个记录,测试集包含12个记录。

y = df['IPG2211A2N'].values.astype(float)

test_size = 12
window_size = 12

train_set = y[:-test_size]
test_set  = y[-test_size:]

print(f'Train: {len(train_set)}')
print(f'Test:  {len(test_set)}')
3.2 数据归一化

        为了提高模型的收敛速度,我们将训练数据归一化至[-1, 1]范围。

scaler = MinMaxScaler(feature_range=(-1, 1))
train_norm = scaler.fit_transform(train_set.reshape(-1, 1))
3.3 为LSTM准备数据

        将训练数据按窗口大小分割成输入序列和对应的标签,以便输入到LSTM模型中。

def input_data(seq,ws):
    out = []
    L = len(seq)
    for i in range(L-ws):
        window = seq[i:i+ws]
        label = seq[i+ws:i+ws+1]
        out.append((window,label))
    return out

train_data = input_data(train_norm,window_size)

4. 定义LSTM模型

        我们设计了一个包含64个隐藏层神经元的LSTM模型,随后添加一个全连接层来预测最终输出。

class LSTMnetwork(nn.Module):
    def __init__(self,input_size=1,hidden_size=64,output_size=1):
        super().__init__()
        self.hidden_size = hidden_size
        self.lstm = nn.LSTM(input_size,hidden_size)
        self.linear = nn.Linear(hidden_size,output_size)
        self.hidden = (torch.zeros(1,1,self.hidden_size),
                       torch.zeros(1,1,self.hidden_size))

    def forward(self,seq):
        lstm_out, self.hidden = self.lstm(
            seq.view(len(seq),1,-1), self.hidden)
        pred = self.linear(lstm_out.view(len(seq),-1))
        return pred[-1]

        我们使用均方误差(MSE)作为损失函数,Adam优化器进行优化。

criterion = nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

5. 模型训练

        我们训练模型50个周期,并在每个周期重置LSTM的隐藏状态。

epochs = 50
for i in range(epochs):
    for seq, y_train in train_data:
        optimizer.zero_grad()
        model.hidden = (torch.zeros(1,1,model.hidden_size),
                        torch.zeros(1,1,model.hidden_size))
        y_pred = model(seq)
        loss = criterion(y_pred, y_train)
        loss.backward()
        optimizer.step()

6. 模型评估和测试集预测

        我们使用训练后的模型对未来12个月的电力和天然气生产进行预测,并将预测结果与实际测试数据进行比较。

future = 12
preds = train_norm[-window_size:].tolist()

model.eval()
for i in range(future):
    seq = torch.FloatTensor(preds[-window_size:])
    with torch.no_grad():
        model.hidden = (torch.zeros(1,1,model.hidden_size),
                        torch.zeros(1,1,model.hidden_size))
        preds.append(model(seq).item())

        通过逆归一化恢复原始数据范围,并将预测结果与实际数据进行可视化比较。

true_predictions = scaler.inverse_transform(np.array(preds[window_size:]).reshape(-1, 1))

x = np.arange('2018-02-01', '2019-02-01', dtype='datetime64[M]').astype('datetime64[D]')

plt.figure(figsize=(12,4))
plt.title('Industrial Production Index for Electricity and Gas Utilities')
plt.ylabel('Index 2012=100, Not Seasonally Adjusted')
plt.grid(True)
plt.autoscale(axis='x',tight=True)
plt.plot(df['IPG2211A2N'])
plt.plot(x,true_predictions)
plt.show()

结语

        在本案例中,我们使用了LSTM(长短期记忆网络)来预测电力和天然气的生产指数。通过对时间序列数据的归一化处理、构建基于LSTM的深度学习模型,以及模型的训练和测试,我们成功预测了未来12个月的能源生产趋势。

        这一案例展示了如何使用LSTM处理时间序列数据,特别是在能源生产等领域的应用。我们通过划分训练集和测试集,并使用滑动窗口方法生成输入序列,有效地提高了模型的学习能力。最终的预测结果通过与实际数据的对比,证明了模型的预测效果较为准确。

        在实际应用中,LSTM网络不仅可以应用于能源生产的预测,还可以广泛用于金融市场、销售预测等其他时间序列数据的建模与预测。这种方法能够有效捕捉数据的时间依赖性,为复杂的时间序列问题提供了有力的解决方案。

如果你觉得这篇博文对你有帮助,请点赞、收藏、关注我,并且可以打赏支持我!

欢迎关注我的后续博文,我将分享更多关于人工智能、自然语言处理和计算机视觉的精彩内容。

谢谢大家的支持!

10-08 16:31