📗
TimeSeriesAnalysis101
  • 时间序列分析101:序言
  • 1. 概述
  • 2. 准备和处理时间序列数据
    • 2.1 准备数据集
    • 2.2 寻找时间轴
    • 2.3 时间序列可能遇到的问题
    • 2.4 清洗数据
      • 2.4.1 缺失值处理
      • 2.4.2 改变数据集时间频率
      • 2.4.3 平滑数据
  • 3. 探索式分析(EDA)
    • 3.1 针对时间序列的特殊方法
      • 3.1.1 理解平稳性
      • 3.1.2 寻找自相关
      • 3.1.3 虚假相关性
    • 3.2 常用的可视化图表
      • 3.2.1 1D可视化
      • 3.2.2 2D可视化
  • 4. 基于统计学的时间序列分析方法
    • 4.1 自回归模型(Autoregressive)
    • 4.2 移动平均模型(Moving Average)
    • 4.3 差分整合移动平均自回归模型(Autoregressive Integrated Moving Average)
    • 4.4 向量自回归模型(Vector Autoregression)
    • 4.5 基于统计学方法的优势与劣势
  • 5. 特征生成和特征选择
    • 5.1 特征工程的考虑
    • 5.2 常用的特征清单
    • 5.3 自动特征生成与选择
  • 6. 基于机器学习的时间序列分析方法
    • 6.1 时间序列分类问题
    • 6.2 时间序列聚类问题
  • 7. 基于深度学习的时间序列分析方法
    • 7.1 LSTM长短期记忆网络
      • 7.1.1 使用Pytorch搭建
      • 7.1.2 使用Darts调用
    • 7.2 CNN卷积神经网络
  • 8. 模型评估和性能考虑
    • 8.1 模型评估的考虑
    • 8.2 计算效率的考虑
Powered by GitBook
On this page

Was this helpful?

  1. 7. 基于深度学习的时间序列分析方法

7.2 CNN卷积神经网络

CNN计算机视觉领域占据着重要地位,而CNN同样可以用在时间序列上。区别在于应用在图像上的卷积核是二维的,而应用在时间序列上的卷积核是一维的,也就是一维卷积神经网络,1D CNN。

相比于基于RNN的LSTM等模型,1D CNN的优势是训练快,可以并行计算,并且在某些场景下可以获得不输给LSTM的模型效果。

下面就来学习如何用1D CNN训练时间序列数据。

# 使用和上一节中LSTM准备好的相同数据样本,不再重复
# 构建一个简单的1D CNN模型
class CNNnetwork(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1d = nn.Conv1d(1,64,kernel_size=2)
        self.relu = nn.ReLU(inplace=True)
        self.fc1 = nn.Linear(64*11,50)
        self.fc2 = nn.Linear(50,1)

    def forward(self,x):
        # 该模型的网络结构为 一维卷积层 -> Relu层 -> Flatten -> 全连接层1 -> 全连接层2 
        x = self.conv1d(x)
        x = self.relu(x)
        x = x.view(-1)
        x = self.fc1(x)
        x = self.relu(x)
        x = self.fc2(x)
        return x
torch.manual_seed(101)
model =CNNnetwork()

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

model
# CNN用到的模型参数更少
def count_parameters(model):
    params = [p.numel() for p in model.parameters() if p.requires_grad]
    for item in params:
        print(f'{item:>6}')
    print(f'______\n{sum(params):>6}')

count_parameters(model)
   128
    64
 35200
    50
    50
     1
______
 35493
epochs = 100
model.train()
start_time = time.time()

for epoch in range(epochs):

    for seq, y_train in train_data:

        # 每次更新参数前都梯度归零和初始化
        optimizer.zero_grad()

        # 注意这里要对样本进行reshape,转换成conv1d的input size(batch size, channel, series length)
        y_pred = model(seq.reshape(1,1,-1))
        loss = criterion(y_pred, y_train)
        loss.backward()
        optimizer.step()

    print(f'Epoch: {epoch+1:2} Loss: {loss.item():10.8f}')

print(f'\nDuration: {time.time() - start_time:.0f} seconds')
future = 12

# 选取序列最后12个值开始预测
preds = train_norm[-window_size:].tolist()

# 设置成eval模式
model.eval()

# 循环的每一步表示向时间序列向后滑动一格
for i in range(future):
    seq = torch.FloatTensor(preds[-window_size:])
    with torch.no_grad():
        preds.append(model(seq.reshape(1,1,-1)).item())
# 逆归一化还原真实值
true_predictions = scaler.inverse_transform(np.array(preds[window_size:]).reshape(-1, 1))
# 对比真实值和预测值
plt.figure(figsize=(12,4))
plt.grid(True)
plt.plot(df['S4248SM144NCEN'])
x = np.arange('2018-02-01', '2019-02-01', dtype='datetime64[M]').astype('datetime64[D]')
plt.plot(x,true_predictions)
plt.show()
# 放大看
fig = plt.figure(figsize=(12,4))
plt.grid(True)
fig.autofmt_xdate()

plt.plot(df['S4248SM144NCEN']['2017-01-01':])
plt.plot(x,true_predictions)
plt.show()
Previous7.1.2 使用Darts调用Next8. 模型评估和性能考虑

Last updated 3 years ago

Was this helpful?