数据集链接

数据链接: 氣候數據

数据集简介

该数据集于想要训练印度气候天气预报模型的开发人员。该数据集提供了印度德里市2013年1月1日至2017年4月24日的数据。这里的4个参数是 平均温度、湿度、风速、平均气压。

工具

使用pytorch作爲工具,構建简单CNN+LSTM的模型对该天气数据集的平均温度时间序列进行预测。

数据分析流程

数据读取-

用pands读取数据,绘制时序图

白噪声检验

对平均温度进行白噪声检验,由以下随机性检验的数据可得,数据具有明显的自相关性,可以进行时序预测

自相关系数

 

描述性统计

模型训练

数据归一化

1
2
3
4
5
from sklearn.preprocessing import MinMaxScaler
# 创建MinMaxScaler对象
scaler = MinMaxScaler()
# 将数据进行归一化
meantemp = scaler.fit_transform(meantemp.reshape(-1,1))

数值范围统一化:

  • 将所有数据映射到[0,1]区间
  • 有利于消除量纲影响
  • 使模型更容易收敛

提高模型训练效果:

  • 避免因数值差异过大导致的梯度爆炸或消失
  • 加快模型收敛速度
  • 提高模型训练的稳定性

创建时间序列滑动窗口数据

1
2
3
4
5
6
7
8
9
def split_data(data,time_step=12):
dataX=[]
datay=[]
for i in range(len(data)-time_step):
dataX.append(data[i:i+time_step])
datay.append(data[i+time_step])
dataX=np.array(dataX).reshape(len(dataX),time_step,-1)
datay=np.array(datay)
return dataX,datay

参数data: 输入的时间序列数据

参数time_step=12: 时间窗口大小,默认使用12个时间步

表示用前12天的数据来预测第13天的数据

这种数据处理方式的优点:

  1. 适合时间序列预测

  2. 保留了时序依赖关系

  3. 符合LSTM等循环神经网络的输入要求

    1
    2
    3
    4
    5
    6
    7
    8
    原始数据: [T1, T2, T3, T4, T5, T6, T7, ...]

    转换后:
    输入X 输出y
    [T1,T2,T3] -> T4
    [T2,T3,T4] -> T5
    [T3,T4,T5] -> T6
    [T4,T5,T6] -> T7

划分训练集和测试集的函数

参数说明:

  • dataX:特征数据集

  • datay:标签数据集

  • shuffle:是否打乱数据,默认True

  • percentage:训练集比例,默认0.8(80%)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def train_test_split(dataX,datay,shuffle=True,percentage=0.8):
"""
将训练数据X和标签y以numpy.array数组的形式传入
划分的比例定为训练集:测试集=8:2
"""
if shuffle:
random_num=[index for index in range(len(dataX))]
np.random.shuffle(random_num)
dataX=dataX[random_num]
datay=datay[random_num]
split_num=int(len(dataX)*percentage)
train_X=dataX[:split_num]
train_y=datay[:split_num]
test_X=dataX[split_num:]
test_y=datay[split_num:]
return train_X,train_y,test_X,test_y

将数据以8比2进行拆分,并且随机打乱索引顺序 ,

构建CNN+LSTM神经网络

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class CNN_LSTM(nn.Module):
def __init__(self, conv_input,input_size, hidden_size, num_layers, output_size):
super(CNN_LSTM,self).__init__()
self.hidden_size = hidden_size
self.num_layers = num_layers
self.conv=nn.Conv1d(conv_input,conv_input,1)
self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True)
self.fc = nn.Linear(hidden_size, output_size)

def forward(self, x):
x=self.conv(x)
h0 = torch.zeros(self.num_layers,x.size(0), self.hidden_size) # 初始化隐藏状态h0
c0 = torch.zeros(self.num_layers,x.size(0), self.hidden_size) # 初始化记忆状态c0
#print(f"x.shape:{x.shape},h0.shape:{h0.shape},c0.shape:{c0.shape}")
out, _ = self.lstm(x, (h0, c0)) # LSTM前向传播
out = self.fc(out[:, -1, :]) # 取最后一个时间步的输出作为预测结果
return out
  • CNN层用于特征提取
  • LSTM层处理时序关系
  • 全连接层做最终预测
  1. 前向传播过程:

输入 x -> CNN -> LSTM -> 取最后时间步 -> 全连接层 -> 输出

  1. 各层功能:
  • CNN层:
    • 使用1x1卷积
    • 提取局部特征
    • 保持输入输出通道数相同
  • LSTM层:
    • batch_first=True表示输入形状为(batch, seq, feature)
    • 处理时序依赖关系
    • 多层LSTM叠加
  • 全连接层:
    • 将LSTM输出映射到目标维度
    • 只使用最后一个时间步的输出
  1. 模型特点:
  • 结合了CNN和LSTM的优势
  • CNN提取空间特征
  • LSTM捕捉时序关系
  • 适合时间序列预测任务

输入参数,进行训练

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
test_X1=torch.Tensor(test_X)
test_y1=torch.Tensor(test_y)

# 定义输入、隐藏状态和输出维度
input_size = 1 # 输入特征维度
conv_input=12
hidden_size = 64 # LSTM隐藏状态维度
num_layers = 5 # LSTM层数
output_size = 1 # 输出维度(预测目标维度)

# 创建CNN_LSTM模型实例
model =CNN_LSTM(conv_input,input_size, hidden_size, num_layers, output_size)

#训练周期为500次
num_epochs=500
batch_size=64#一次训练的数量
#优化器
optimizer=optim.Adam(model.parameters(),lr=0.0001,betas=(0.5,0.999))
#损失函数
criterion=nn.MSELoss()

train_losses=[]
test_losses=[]

 

数据反归一化+计算mse误差

1
2
3
4
5
6
7
8
train_X1=torch.Tensor(X_train)
train_pred=model(train_X1).detach().numpy()
test_pred=model(test_X1).detach().numpy()
pred_y=np.concatenate((train_pred,test_pred))
pred_y=scaler.inverse_transform(pred_y).T[0]
true_y=np.concatenate((y_train,test_y))
true_y=scaler.inverse_transform(true_y).T[0]
print(f"mse(pred_y,true_y):{mse(pred_y,true_y)}")
1
2
3
4
5
6
训练数据 -> 预测 -> 反归一化
测试数据 -> 预测 -> 反归一化

合并结果

计算误差
1
mse(pred_y,true_y):5.5372205189883985

获取完整的预测结果

将结果转换回原始尺度

评估模型性能

对于天气温度预测:

  • MSE < 4: 非常好
  • 4 ≤ MSE < 6: 良好(当前模型处于这个范围)
  • 6 ≤ MSE < 9: 一般
  • MSE ≥ 9: 需要改进

 

额外测试集测试

挑选了后面未参与模型训练的时间步来检验泛化效果,拟合后如下,蓝色为预测值,橙色为真实值。可观察到趋势基本一致。