You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Keras/TensorFlow的多维多变量时间序列预测数据格式疑问

多城市多特征时间序列预测:Keras/TensorFlow数据塑形指南

我太懂这种迷茫了——翻了一堆博客、教程,大多都是单变量单序列的简单示例,真碰到多城市、多特征的日度数据,瞬间就不知道该怎么把数据掰成模型要的形状了。咱们一步步来拆解,帮你理清思路:

先明确核心维度要求

Keras里的时间序列模型(比如LSTM、GRU)最常用的输入形状是 (样本数, 时间步长, 特征数):

  • 样本数:指你能生成的「输入窗口-目标值」对的总数
  • 时间步长:比如用过去7天的数据预测第8天,时间步长就是7
  • 特征数:每个时间点上的特征数量(温度、车流量、湿度,再加上城市标识的话也算)

针对你的多城市场景,有两种主流处理思路,选哪种取决于你希望模型学习的目标:


思路1:把城市当作额外特征(适合城市间共性强的场景)

如果不同城市的规律比较相似,你希望模型学习通用模式,可以把城市转换成编码特征(比如one-hot编码),和温度、车流量等放在一起作为特征组。

操作步骤:

  1. 先对原始数据按「城市+日期」排序,确保每个城市的时间序列是连续的
  2. 给每个城市生成one-hot编码(比如城市A是[1,0,0],城市B是[0,1,0])
  3. 把one-hot编码和原有特征(温度、车流量、湿度)合并
  4. 用Keras的工具函数生成时间序列数据集

代码示例:

import pandas as pd
import numpy as np
from tensorflow.keras.utils import timeseries_dataset_from_array
from sklearn.preprocessing import StandardScaler

# 假设你的原始数据已加载到df,包含列:city, date, temperature, traffic, humidity
df = df.sort_values(['city', 'date'])

# 1. 特征标准化(非常重要,时间序列模型对尺度敏感)
scaler = StandardScaler()
feature_cols = ['temperature', 'traffic', 'humidity']
df[feature_cols] = scaler.fit_transform(df[feature_cols])

# 2. 生成城市one-hot编码
city_one_hot = pd.get_dummies(df['city'], prefix='city')
df = pd.concat([df, city_one_hot], axis=1)

# 3. 定义时间步长和目标列
time_steps = 7  # 用过去7天预测第8天
target_col = 'traffic'  # 假设要预测车流量

# 4. 提取特征和目标
all_features = df.drop(['city', 'date', target_col], axis=1).values
all_targets = df[target_col].values

# 5. 生成时间序列数据集
dataset = timeseries_dataset_from_array(
    data=all_features,
    targets=all_targets[time_steps:],  # 目标是每个窗口之后的第一个值
    sequence_length=time_steps,
    batch_size=32,  # 批次大小根据你的显存调整
    shuffle=True  # 训练时打乱数据
)

# 查看批次形状:(32, 7, 特征数),完全符合LSTM输入要求
for batch in dataset.take(1):
    inputs, targets = batch
    print(f"输入形状: {inputs.shape}")
    print(f"目标形状: {targets.shape}")

思路2:每个城市作为独立序列(适合城市间差异大的场景)

如果不同城市的规律差异很大,你希望模型针对每个城市的特性学习,可以把每个城市的时间序列单独处理,再合并成数据集。这种方式可以保留城市的独立性,甚至可以用共享权重的模型分别训练。

操作步骤:

  1. 按城市分组,每个城市单独处理时间序列
  2. 对每个城市生成「输入窗口-目标值」对
  3. 把所有城市的数据集合并

代码示例:

import pandas as pd
import tensorflow as tf
from tensorflow.keras.utils import timeseries_dataset_from_array
from sklearn.preprocessing import StandardScaler

df = df.sort_values(['city', 'date'])
scaler = StandardScaler()
feature_cols = ['temperature', 'traffic', 'humidity']
df[feature_cols] = scaler.fit_transform(df[feature_cols])

time_steps = 7
target_col = 'traffic'

# 定义单个城市的数据集生成函数
def create_city_dataset(city_df):
    features = city_df.drop(['city', 'date', target_col], axis=1).values
    targets = city_df[target_col].values
    
    return timeseries_dataset_from_array(
        data=features,
        targets=targets[time_steps:],
        sequence_length=time_steps,
        batch_size=32
    )

# 遍历所有城市,生成数据集并合并
city_datasets = []
for city_name in df['city'].unique():
    city_df = df[df['city'] == city_name]
    city_ds = create_city_dataset(city_df)
    city_datasets.append(city_ds)

# 合并所有城市的数据集
combined_dataset = tf.data.Dataset.concatenate(*city_datasets)
combined_dataset = combined_dataset.shuffle(buffer_size=1000)

模型适配示例

不管用哪种思路,生成的数据集都直接可以喂给LSTM模型:

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense

# 获取特征数(从第一个批次里提取)
for batch in combined_dataset.take(1):
    inputs, _ = batch
    num_features = inputs.shape[-1]

model = Sequential([
    LSTM(64, input_shape=(time_steps, num_features)),  # 输入形状匹配时间步长和特征数
    Dense(32, activation='relu'),
    Dense(1)  # 单输出(预测车流量),如果是多输出改成对应数量即可
])

model.compile(optimizer='adam', loss='mse')
model.fit(combined_dataset, epochs=10)

避坑提醒

  • 缺失值处理:每个城市的时间序列必须连续,有缺失值的话用插值、均值填充等方式补全
  • 标准化注意:如果是按城市单独处理,建议每个城市单独拟合标准化器;如果是全局处理,要确保不同城市的特征尺度不会互相干扰
  • 多输出预测:如果要同时预测温度、车流量、湿度,只需要把目标改成多列数组,最后一层Dense改成Dense(3)即可

内容的提问来源于stack exchange,提问作者Bastien

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 04:27:47