Files
ProStock/src/experiment/README_TABM_TOPK.md
liaozhaorun a66d5e9db3 feat(training): 新增 TabM 排序学习模型支持并优化训练流程
- 新增 TabMRankModel、TabMRankTask 及配套损失函数与配置
- 将 DataQualityAnalyzer 从 experiment 迁移至 training 模块
- 调整数据处理器移除过度的 NaN/null 硬填充逻辑
- 优化 RankTask 评估指标使用分位数标签替代原始收益率
- 更新实验脚本处理器顺序与模型超参数配置
2026-04-04 22:39:58 +08:00

4.1 KiB
Raw Blame History

TabM Top-K 优化指南

针对每日只买入预测分最高的 5-10 只股票的 Top-K 选股场景,对 TabM 排序学习进行了三大方向优化。

优化概述

1. 损失函数优化(核心)

加权 ListNet (推荐首次尝试)

  • 原理:给予高分标签样本更高的损失权重
  • 参数:loss_type="weighted_listnet", topk_weight=5.0
  • 效果:头部样本权重是尾部的 5 倍,强迫模型关注头部排序

LambdaLoss (精细 Top-K 优化)

  • 原理:基于 DeltaNDCG 计算每对样本交换位置后的损失
  • 参数:loss_type="lambda", lambda_sigma=1.0, ndcg_weight_power=1.5
  • 效果:精准优化 NDCG@K 指标,适合追求极致 Top-K 性能

2. 标签工程优化(增强)

指数化增益变换

  • 公式:Gain = 2^(rank/scale) - 1
  • 参数:label_transform="exponential", label_scale=20.0
  • 效果rank=0 → 0, rank=19 → ~0.93, rank=99 → ~30.5
  • 用途:拉大高分样本与低分样本的差距,强化头部区分度

3. 推荐配置组合

# 配置 A: 温和优化(推荐首次尝试)
MODEL_PARAMS = {
    "loss_type": "weighted_listnet",
    "topk_weight": 3.0,
    # ... 其他参数
}
LABEL_TRANSFORM = None  # 保持标准分位数

# 配置 B: 平衡优化(兼顾效果和稳定性)
MODEL_PARAMS = {
    "loss_type": "weighted_listnet",
    "topk_weight": 5.0,
    "ndcg_k": 20,  # 验证时关注 NDCG@20
}
LABEL_TRANSFORM = "exponential"
LABEL_SCALE = 20.0

# 配置 C: 激进优化(专注 Top-10
MODEL_PARAMS = {
    "loss_type": "lambda",
    "lambda_sigma": 1.0,
    "ndcg_weight_power": 1.5,
    "ndcg_k": 10,
}
N_QUANTILES = 50  # 提高分位数分辨率
LABEL_TRANSFORM = "exponential"
LABEL_SCALE = 25.0

使用示例

tabm_rank_train.py 中修改配置:

# 分位数配置
N_QUANTILES = 30

# 标签工程配置
LABEL_TRANSFORM = "exponential"  # 启用指数化增益
LABEL_SCALE = 20.0

# 模型参数配置
MODEL_PARAMS = {
    # ... 基础参数 ...
    
    # Top-K 优化参数
    "loss_type": "weighted_listnet",  # 或 "lambda"
    "topk_weight": 5.0,  # 仅 weighted_listnet 有效
    "lambda_sigma": 1.0,  # 仅 lambda 有效
    "ndcg_weight_power": 1.0,  # 仅 lambda 有效
    "ndcg_k": 20,  # 验证指标
}

参数说明

损失函数参数

参数 类型 默认值 说明
loss_type str "listnet" 损失类型: "listnet"/"weighted_listnet"/"lambda"
topk_weight float 5.0 头部权重系数 (weighted_listnet),越大越关注头部
lambda_sigma float 1.0 Sigmoid 陡峭程度 (lambda)
ndcg_weight_power float 1.0 DeltaNDCG 权重幂次 (lambda)>1 进一步放大头部
ndcg_k int/None None 验证时计算的 NDCG@kNone 表示全局

标签工程参数

参数 类型 默认值 说明
n_quantiles int 20 分位数数量,越大分辨率越高
label_transform str/None None 变换类型: None/"exponential"
label_scale float 20.0 指数变换缩放因子,控制增益幅度

实施建议

  1. 渐进式优化

    • 第1轮仅启用 loss_type="weighted_listnet", topk_weight=3.0
    • 第2轮增加标签工程 label_transform="exponential"
    • 第3轮尝试 loss_type="lambda" 精细优化
  2. 监控指标

    • 关注 NDCG@KK 设为实际 Top-K 大小)
    • 对比不同配置的回测收益率
    • 观察训练损失是否稳定下降
  3. 注意事项

    • LambdaLoss 训练更慢,每 epoch 需更多时间
    • 指数化增益会改变标签分布,可能需要调整学习率
    • 过高的 topk_weight 可能导致过拟合头部样本

参考论文

  1. ListNet: "Learning to Rank: From Pairwise Approach to Listwise Approach" (Cao et al., 2007)
  2. LambdaRank: "From RankNet to LambdaRank to LambdaMART: An Overview" (Burges, 2010)
  3. LambdaLoss: "The LambdaLoss Framework for Ranking Metric Optimization" (Wang et al., 2018)
  4. 深度学习选股: "Deep Learning for Stock Selection" (Gu, Kelly, & Xiu, 2020)