时间序列预测是数据分析中的常见需求,无论是电力负荷预测、股票走势分析还是气象预报,都需要根据历史数据预测未来趋势。传统方法如ARIMA、LSTM在面对长期预测任务时往往力不从心,而Informer模型通过改进Transformer架构,在长序列时间序列预测(LSTF)任务中表现出色。
滚动预测是实际应用中更符合业务需求的预测方式。想象一下天气预报场景:气象台不会一次性预测未来30天的天气,而是每天根据最新观测数据更新预测结果。这种"预测-更新-再预测"的循环就是滚动预测的核心思想。相比单次预测,滚动预测能持续修正预测偏差,提高长期预测的准确性。
官方Informer代码虽然提供了基础预测功能,但存在两个主要局限:一是只能进行固定长度的单次预测,二是缺乏完整的评估体系。我在原代码基础上实现了自动化滚动预测功能,主要改进包括:
python复制# 滚动预测核心逻辑示例
def rolling_predict(model, initial_data, steps, window):
predictions = []
current_data = initial_data.copy()
for _ in range(steps // window):
# 单次预测
pred = model.predict(current_data[-seq_len:])
predictions.extend(pred)
# 自动填充新数据
current_data = np.concatenate([current_data, pred])
return predictions
建议使用Python 3.8+和PyTorch 1.10+环境。为方便复现,推荐使用conda创建独立环境:
bash复制conda create -n informer python=3.8
conda activate informer
pip install torch==1.10.0+cu113 -f https://download.pytorch.org/whl/torch_stable.html
pip install pandas scikit-learn matplotlib
硬件方面,GPU加速可以显著提升训练速度。我在RTX 3090上测试,相比CPU训练速度提升约8倍。如果没有GPU,可以减小batch_size和d_model参数降低计算需求。
ETTh1数据集包含电力系统7个维度的指标(温度、湿度等)和1个时间戳列。预处理时需要注意:
python复制# 数据预处理示例代码
def preprocess_data(df):
# 时间特征提取
df['hour'] = df['date'].dt.hour
df['day_of_week'] = df['date'].dt.dayofweek
# 归一化
scaler = MinMaxScaler()
scaled_values = scaler.fit_transform(df[feature_columns])
df[feature_columns] = scaled_values
# 构建时序样本
X, y = [], []
for i in range(len(df)-seq_len-pred_len):
X.append(df.iloc[i:i+seq_len][feature_columns].values)
y.append(df.iloc[i+seq_len:i+seq_len+pred_len][target_column].values)
return np.array(X), np.array(y)
d_model(512):特征维度,越大表示模型容量越大,但计算开销也越大。对于简单数据集可以降至256
n_heads(8):注意力头数,建议设置为特征数的约数
e_layers/d_layers(2/1):编码器/解码器层数,层数增加可能提升效果但也会导致过拟合
seq_len(96):历史窗口大小。电力数据具有日周期(24小时),设置为4天(96小时)效果较好
label_len(48):解码器初始输入长度,通常设为seq_len的1/2
pred_len(24):预测长度,设置为24小时(1天)符合业务需求
python复制# 参数设置示例
args = {
'seq_len': 96, # 输入序列长度
'label_len': 48, # 解码器初始序列长度
'pred_len': 24, # 预测序列长度
'd_model': 512, # 模型维度
'n_heads': 8, # 注意力头数
'e_layers': 2, # 编码器层数
'd_layers': 1, # 解码器层数
'd_ff': 2048, # 前馈网络维度
'factor': 5, # ProbSparse因子
'dropout': 0.05 # 丢弃率
}
原始滚动预测需要手动拼接预测结果,我实现的自动化流程包括:
为全面评估预测效果,实现了三种评估方式:
python复制# 评估指标计算
def evaluate_predictions(true, pred):
mae = np.mean(np.abs(true - pred))
mse = np.mean((true - pred)**2)
# 趋势准确率
true_dir = np.sign(true[1:] - true[:-1])
pred_dir = np.sign(pred[1:] - pred[:-1])
trend_acc = np.mean(true_dir == pred_dir)
return {'MAE': mae, 'MSE': mse, 'TrendAccuracy': trend_acc}
python复制# 学习率预热实现
def adjust_learning_rate(optimizer, epoch, args):
lr = args.learning_rate
if epoch < 5: # 前5个epoch逐步提高学习率
lr = lr * (epoch + 1) / 5
for param_group in optimizer.param_groups:
param_group['lr'] = lr
模型支持标准CSV格式,需包含:
python复制# 自定义数据集配置示例
data_parser['my_data'] = {
'data': 'custom_data.csv',
'T': 'target_column', # 目标列名
'M': [feature_num, feature_num, feature_num], # 多元预测
'S': [1, 1, 1], # 单元预测
'MS': [feature_num, feature_num, 1] # 多元预测单元
}
项目主要文件结构:
code复制informer-rolling/
├── data/ # 数据目录
│ ├── ETTh1.csv # 原始数据
│ └── ETTh1-Test.csv # 测试数据
├── checkpoints/ # 模型保存
├── utils/ # 工具函数
│ ├── metrics.py # 评估指标
│ └── timefeatures.py # 时间特征处理
├── exp/ # 实验模块
│ └── exp_informer.py # 主实验类
└── main_informer.py # 入口文件
典型执行流程:
对于希望进一步提升效果的开发者,可以考虑:
python复制# 不确定性估计示例
class ProbabilisticInformer(nn.Module):
def __init__(self, model):
super().__init__()
self.model = model
self.logvar = nn.Linear(model.d_model, model.pred_len)
def forward(self, x):
mean = self.model(x)
logvar = self.logvar(x[:, -1:])
return torch.distributions.Normal(mean, torch.exp(0.5*logvar))
实际项目中,我发现预测效果与数据质量强相关。曾遇到因传感器故障导致数据异常,使预测误差突然增大。建议在预处理阶段加入严格的数据质量检查,这对工业级应用尤为重要。