ML Design
🪛

ML Design

 
好的!下面给你一套“从 0 到 1”的、可落地的 ML 系统设计,用“Google 搜索信号 → 预测股价(或可交易回报)”。我按“问题定义→数据→特征→建模→评估→交易→上线与监控→风险与合规→可扩展性”的顺序展开,并把常见坑和工程细节一并考虑进去。

1. 问题定义(What exactly are we predicting?)

  • 可交易目标(建议二选一)
      1. 次日开盘到收盘的日内回报 (),交易于 T+1 开盘,用 T 日收盘后可获得的全部搜索特征。
      1. 隔夜回报 (),交易于 T 日收盘,持有到 T+1 开盘
      理由:与搜索行为节律匹配(周末/晚间搜索显著),并能严格避免“看到当日收盘信息后再预测当日”的泄露。
  • 预测形式
    • 回归(直接预测回报),或二分类(预测方向 sign)。
    • 横截面设定更稳健:一次性对一篮子股票(如 S&P 500 历史成分,使用历史成分以避免生存者偏差)做 cross-sectional 预测。
  • 样本频率:日频为主(Google Trends 的稳定粒度),必要时叠加周末/小时级近实时信息做 nowcasting(仅限近 7 天窗口,工程成本更高)。

2. 数据选择与采集(Data)

2.1 市场与元数据

  • 价格与交易数据:日开高低收、成交量、前复权价;指数/行业 ETF(SPY、QQQ、XLF…)、VIX、无风险利率。
  • 公司元信息:ticker、全称、历史更名/并表/M&A、主要品牌/产品线、CEO 姓名、行业/板块映射、上市交易所、ISIN/CUSIP。
  • 交易日历:NYSE/NASDAQ 交易日、夏令时、节假日(对齐时间戳)。

2.2 Google 搜索信号(核心)

首选来源:Google Trends(pytrends)。它返回 0–100 的 SVI(Search Volume Index),按查询词或主题 Topic、地区、时间段归一化。
  • 查询词典(Query Dictionary)设计(每个公司一组):
    • Topic 优先(避免歧义):如“Apple Inc.(公司主题)”,而非“apple(苹果/水果)”。
    • 别名/产品/CEO:公司全称、Ticker 组合词("MSFT stock")、品牌与主打产品("iPhone")、CEO("Satya Nadella")。
    • 消歧策略:对易混淆词("CAT"、"NOW"、"META")使用 "TICKER stock" / "Company Name (firm)" Topic / 限定地区("United States")与类别(Finance)。
    • 行业层级词:行业名 + “stocks”(如 "semiconductor stocks")构造 行业面搜索热度,供横截面相对特征。
  • 采样与对齐
    • 频率:以 日频 SVI 为主;周末有数据但无交易,后续做周末聚合特征。
    • 时间戳对齐:SVI_t 只能用于 t 之后的交易决策。若 Google Trends 有 数据刷新延迟(通常当日数据晚间或隔日稳定),保守起见对全部 SVI 右移 1 天或按可得性时间戳对齐。
    • 多次抓取方差:Trends 同一查询会有轻微采样噪声,重复抓取多次取均值/中位数降低噪声。
  • 尺度一致性(大坑)
    • Trends 的 0–100 在不同查询/不同时间窗口不可直接横比
    • 锚定缩放(Anchor scaling):将多个查询与一个(或一组)锚词(如 "YouTube" Topic 或行业稳定词)放入同一次请求,利用锚词在不同批次中的相对比例进行 链式重标定;或使用 多词同批的相对刻度,再把所有批次拼接。
    • 窗口拼接:长区间日频数据可用 重叠 90 天窗口 滚动抓取 + 重叠区间均值对齐 消除再归一化断点。
  • 补充 Google 信号(可选)
    • Related queries/topics 的上升/突破(Breakout)标签计数;
    • 地区分布(州/城市)→ 和公司收入地域结构对齐做加权;
    • Google News 热度或 GDELT 新闻计数(虽非“搜索”,但与搜索强相关,标记事件强度)。
    • 注意 TOS:避免未经许可的抓取,优先使用官方接口或合规数据源。

3. 特征工程(Feature Engineering)

记 () 为某查询 q 在 t 日的 SVI(已完成锚定与对齐)。

3.1 基础变换(每个查询 q)

  • 水平与变化
    • 变化率:();相对变化:()。
    • 滚动 z 分数:()(w=28/60)。
    • 动量/均线:EMA、MACD-style(对 SVI 做快慢均线差)。
    • 周末搜索冲击:sum/max(Sat–Sun)→ 周一或周二收益。
    • 异常尖峰:基于 STL/LOF/3σ 检测尖峰强度与持续期。
  • 语义桶(公司、产品、CEO、行业)分别聚合(均值/加权和/最大),形成 多头特征组(减少单词典漂移风险)。

3.2 横截面与相对特征

  • 行业内分位:某日公司在行业内的 SVI z-score 分位/排名。
  • 相对指数/同业差:公司组特征 − 行业均值 / 市场均值。
  • 异质性指标:公司组内“公司名 vs 产品词”的占比变动(是否从品牌搜索转向危机相关词,如 "layoff")。

3.3 与市场变量交互

  • 交互项:()(前一日收益、波动率、VIX 水平、财报/事件哑变量)。
  • 日历特征:月内/周内/财报周,财报前后 k 天窗口哑变量。
  • 稳定化:所有滚动统计用 仅历史窗口(防泄露),并按 ticker 内 标准化(避免横跨公司比较导致的规模混淆)。

3.4 质量与稳健性特征

  • 信号置信度:有效查询数量、锚定重标定的重叠 R²、重复抓取方差;
  • 稀疏/低量:对低搜索量公司的特征打折或弃用,或采用 行业层级 替代。

4. 训练集构造(Supervised framing)

  • 样本单位:日×股票(横截面面板)。
  • 特征时间:全部特征在 T 日收盘后可得(或更保守 T+1 早盘前)。
  • 标签:T+1 的目标回报(选定的交易定义)。
  • 去极值/缩放:winsorize 1–99%(或中位绝对偏差),分组标准化(行业内)。

5. 数据切分与评估方案

  • 时序滚动验证(Time-series CV)
    • 例:训练 2014–2019,验证 2020;滑动到 2015–2020 训练,验证 2021 … 直至样本结束。
    • 禁止随机打乱;保持横截面充分(每折包含足够多股票)。
  • 指标
    • ML:MSE/MAE(回归)、AUC/Logloss(分类)、IC(Spearman 相关)。
    • 交易:年化 Sharpe、胜率、均/中位单笔收益、Tail 风险(max drawdown、CVaR)、换手与成本后收益
    • 事件窗:财报周与非财报周分别评估;牛/熊市子样本;疫情等结构突变前后。

6. 基线与模型选择

强烈建议“从简到繁,逐步上楼”:
  1. 基线
      • 仅用价格/量技术因子(AR/ARX、Lasso Ridge、简单树)→确认搜索信号增益。
  1. 线性+正则
      • Lasso / ElasticNet(解释性强、可做行业 group-lasso)。
  1. 树模型
      • XGBoost / LightGBM / CatBoost(非线性、处理缺失、重要度可解释)。
  1. 时序深度学习(样本与工程成熟后)
      • TCN/Temporal Fusion Transformer/LSTM(面板输入,加入静态 embedding:行业、规模)。
      • 多任务学习:共享干净的公共干特征,ticker 作为 task head(或用 entity embedding)。
      • 注意过拟合与漂移,必须严格滚动验证与早停。
类别选择:若以方向为目标(涨跌),用 带阈值的回归 or 直接二分类;若交易成本高,适当 边际区间(只在|score|>θ时交易),以控制换手。

7. 超参、特征选择与稳健性

  • 超参:在每一时序折上网格/贝叶斯搜索;以 验证集金融指标 + IC 共同作为目标(不是只看 AUC)。
  • 特征重要度:树模型 Gain/Split、Permutation Importance、SHAP(注意时序泄露;仅在验证期内做)。
  • 消融实验:仅搜索、仅价格、两者融合;不同子词典分组(公司/产品/CEO/行业)分别上阵。
  • 稳健性检验
    • 置换检验:打乱 SVI 时间序列或公司映射,应显著劣化;
    • 前后样本稳定性:分阶段对比(如 2016–2019 vs 2020–2022 vs 2023–2025)。
    • Granger 因果:() vs (),避免“价格先动、搜索后跟”的伪因果。

8. 交易与风险控制(Backtest → Live)

  • 信号到仓位
    • 回归分数 → zscore 横截面标准化 → 多空分层(如 top 20% 多、bottom 20% 空,行业中性/市值中性约束)。
    • 分类概率 → 只在高置信度阈值上建仓。
  • 成本模型:双边佣金 + 价差/冲击(按市值/成交额分段)。
  • 风险:行业/风格中性、单票权重上限、日换手上限、止损止盈、波动目标(target volatility)。
  • 价格落点
    • 预测 () → 用 t+1 开盘价 建仓,t+1 收盘价平仓(或持更久,另行定义)。
    • 预测 () → t 收盘建仓,t+1 开盘平仓。
  • 执行延迟:确保特征在实盘下 可在下单前拿到;若 Trends 延迟不确定,使用 保守时移

9. 上线与 MLOps

  • 数据编排:Airflow/Prefect 定时抓取 Trends 与行情;落地到数据湖/仓(Hive/Parquet/Delta)。
  • 特征库:定义可复用、版本化的特征(含锚定比例、滚动窗口等元数据)。
  • 模型注册与版本:MLflow/Weights & Biases 记录参数、数据快照哈希、训练代码 Image。
  • 在线推理:日批(EOD)产出次日交易信号;保存到信号表。
  • 监控
    • 数据质量:缺失率、锚定因子漂移、重复抓取方差超阈值报警;
    • 模型漂移:特征分布 PSI、残差/IC 滚动下降报警;
    • 实盘对账:信号→成交→持仓 PnL 的链路健康度。
  • 重训练策略:月度/季度滚动再训练;发生结构突变(监控触发)时提前重训。

10. 合规与风险

  • 合规:遵守 Google 服务条款;尽量使用官方接口与授权数据;保存 API 配额与失败重试策略。
  • 可复制性:锁定依赖与容器镜像,保留原始与锚定后数据版本。
  • 解释与审计:保留每次预测的特征切片与重要度,便于事后审计与迭代。

11. 常见坑位清单(Checklist)

Trends 归一化不可直接横比锚定缩放 + 窗口拼接
时间泄露 → 所有滚动统计窗口仅用过去数据;Trends 数据右移到可得时点。
歧义词与重名 → Topic/限定词/地区/类别处理。
低搜索量 → 置信度权重或行业层级替代。
生存者偏差 → 用历史成分与退市股;公司更名/并表映射。
成本后收益 才算数;控制换手。
多次抓取噪声 → 重复采样取均值。
结构突变 → 子样本与时间稳定性检验。

12. 最小可行落地(MVP)路线图

  1. 选 300–800 只美股(历史成分),日频收集 5–8 年数据;
  1. 为每家公司构建 Topic + "ticker stock" + 主产品 词典;
  1. 锚词法 拉一遍日频 SVI(重叠 90 天拼接),对齐到交易日;
  1. 变化率/滚动 z/周末冲击/行业分位 等 20–60 个特征;
  1. 模型:ElasticNet 基线LightGBM
  1. 时序滚动 CV + 成本后回测
  1. 通过 消融 证明搜索信号增益,稳定后再上 多任务 Transformer

13. (可选)建模细节示例(简要伪代码)

# 1) 构造面板数据 X, y = build_panel_features( prices, trends_scaled, meta, label='next_day_open_to_close_return', feature_time='EOD', horizon='1d' ) # 2) 时序滚动验证 for fold in rolling_splits(X, y, by_date=True): X_tr, y_tr, X_val, y_val = fold model = LGBMRegressor( n_estimators=2000, learning_rate=0.02, num_leaves=63, colsample_bytree=0.6, subsample=0.8, reg_alpha=1.0, reg_lambda=2.0 ) model.fit( X_tr, y_tr, eval_set=[(X_val, y_val)], eval_metric='l2', early_stopping_rounds=200 ) preds = model.predict(X_val) # 3) 横截面打分 → 分层多空 → 成本后绩效 portfolio = build_long_short(preds, y_val.index, industry_neutral=True) report_metrics(portfolio, preds, y_val)

14. 可扩展方向

  • 语义子词典:公司 +("earnings"、"guidance"、"layoff"、"scandal"…)细化搜索意图。
  • 多语言区域:按公司营收地域权重加总不同国家的 SVI。
  • 事件检测:基于 related queries 的“Breakout”事件触发战术仓位。
  • 多目标学习:同时预测隔夜与日内回报,共享搜索特征主干。

如果你愿意,我可以基于你指定的“股票池 + 时间段”,直接给你一份 可运行的 pytrends 拉数 + 锚定缩放 + LightGBM 训练与回测 的模板代码(含锚定拼接与周末冲击特征)。