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

如何用Python构建联邦学习LSTM模型实现股票收盘价预测

步骤1:补全客户端数据集构造函数,完成时间序列滑窗处理

你之前定义的create_tf_dataset_for_client_fn需要实现时间序列样本构造逻辑,用历史N个时间步的特征预测下一个时间步的Close收盘价,参考实现如下:

import tensorflow as tf

# 超参数设置
TIME_STEPS = 30  # 用过去30天的数据预测下一天收盘价
FEATURE_COLS = ['Open', 'High', 'Close', 'Volume']
TARGET_COL = 'Close'
BATCH_SIZE = 32

def create_tf_dataset_for_client_fn(client_id):
    # 取出对应客户组的原始数据,按日期排序保证时间序列顺序
    client_df = df[df[client_id_colname] == client_id].sort_values('Date').reset_index(drop=True)
    # 提取特征和目标值
    features = client_df[FEATURE_COLS].values
    targets = client_df[TARGET_COL].values
    
    # 滑窗构造样本
    X, y = [], []
    for i in range(TIME_STEPS, len(client_df)):
        X.append(features[i-TIME_STEPS:i])
        y.append(targets[i])
    
    # 转为TF数据集,按时间顺序切分训练/测试集,禁止打乱
    dataset = tf.data.Dataset.from_tensor_slices((X, y))
    train_size = int(len(dataset) * 0.8)
    # 训练场景取前80%,测试场景取后20%
    if 'train' in tf.data.Dataset.context:
        dataset = dataset.take(train_size)
    else:
        dataset = dataset.skip(train_size)
    
    # 每个客户端独立做特征归一化,避免跨客户端数据泄露
    def normalize(x, y):
        x = tf.cast(x, tf.float32) / tf.reduce_max(x, axis=0)
        y = tf.cast(y, tf.float32) / tf.reduce_max(y)
        return x, y
    
    return dataset.map(normalize).batch(BATCH_SIZE).prefetch(tf.data.AUTOTUNE)
步骤2:构建LSTM收盘价预测模型

定义符合TFF要求的Keras LSTM模型,输入维度为(时间步长, 特征数),输出为单值的收盘价预测结果:

def build_lstm_model():
    model = tf.keras.Sequential([
        tf.keras.layers.LSTM(64, return_sequences=True, input_shape=(TIME_STEPS, len(FEATURE_COLS))),
        tf.keras.layers.LSTM(32, return_sequences=False),
        tf.keras.layers.Dense(16, activation='relu'),
        tf.keras.layers.Dense(1)
    ])
    model.compile(
        loss=tf.keras.losses.MeanSquaredError(),
        optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),
        metrics=[tf.keras.metrics.MeanAbsoluteError(), tf.keras.metrics.RootMeanSquaredError()]
    )
    return model

# 验证模型输入输出格式是否符合要求
test_model = build_lstm_model()
sample_input = tf.random.normal((1, TIME_STEPS, len(FEATURE_COLS)))
print(test_model(sample_input).shape) # 输出应为(1,1)
步骤3:定义TFF联邦学习训练与评估流程

将Keras模型转为TFF可识别的格式,使用联邦平均算法完成训练流程定义:

import tensorflow_federated as tff

# 定义TFF模型包装器
def model_fn():
    keras_model = build_lstm_model()
    loss = tf.keras.losses.MeanSquaredError()
    metrics = [tf.keras.metrics.MeanAbsoluteError(), tf.keras.metrics.RootMeanSquaredError()]
    return tff.learning.models.from_keras_model(
        keras_model,
        input_spec=train_data.create_tf_dataset_for_client(train_data.client_ids[0]).element_spec,
        loss=loss,
        metrics=metrics
    )

# 构建加权联邦平均训练过程
training_process = tff.learning.algorithms.build_weighted_fed_avg(
    model_fn=model_fn,
    client_optimizer_fn=lambda: tf.keras.optimizers.Adam(learning_rate=0.001),
    server_optimizer_fn=lambda: tf.keras.optimizers.SGD(learning_rate=1.0)
)

# 构建联邦评估过程
eval_process = tff.learning.build_federated_evaluation(model_fn=model_fn)
步骤4:执行联邦训练与评估

初始化训练状态,迭代多轮联邦训练,每轮训练后可在测试集上评估效果:

# 初始化服务端模型状态
state = training_process.initialize()

# 训练轮次超参数
NUM_ROUNDS = 20

for round_num in range(1, NUM_ROUNDS+1):
    # 每轮选中所有客户端参与训练,也可根据需求按比例采样
    train_client_datasets = [train_data.create_tf_dataset_for_client(cid) for cid in train_data.client_ids]
    # 执行一轮训练
    result = training_process.next(state, train_client_datasets)
    state = result.state
    train_metrics = result.metrics
    print(f'第{round_num}轮训练结束,训练MSE:{train_metrics["client_work"]["train"]["loss"]:.4f},训练MAE:{train_metrics["client_work"]["train"]["mean_absolute_error"]:.4f}')
    
    # 每5轮做一次测试集评估
    if round_num %5 ==0:
        test_client_datasets = [test_data.create_tf_dataset_for_client(cid) for cid in test_data.client_ids]
        eval_metrics = eval_process(state.model, test_client_datasets)
        print(f'第{round_num}轮测试结果,测试MSE:{eval_metrics["eval"]["loss"]:.4f},测试MAE:{eval_metrics["eval"]["mean_absolute_error"]:.4f}')
注意事项
  • 时间序列数据切分训练测试集必须严格按时间顺序划分,禁止随机打乱,避免未来数据泄露
  • 特征归一化的统计值只能用对应客户端的训练集数据计算,不能用到测试集或其他客户端的数据
  • 可以根据实际效果调整LSTM层数、隐藏单元数、时间步长、学习率等超参数

内容的提问来源于stack exchange,提问作者Lim Shi Hao

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 07:36:03