跳转至

第 27 课 让一棵树学会提问,再让许多树共同判断

线性模型像一张固定权重的评分表,决策树则会根据答案继续提问。本课从一次可以手算的分叉开始,逐步走到随机森林、提升树和截面排序。

适合谁已经理解线性与逻辑回归的读者
前置知识特征、标签、时间切分和线性基线
建议用时150 分钟,可以分两次完成
本课成果一张树模型选择与检查卡

一条直线解释不了的组合条件

第 26 课的线性模型会给每个特征一个权重,再把所有结果相加。它很适合作为第一条基线,但有些市场想法天然带有条件。研究者可能认为过去涨幅较高是一条积极线索,不过只有在波动不太大、成交仍然活跃时,这条线索才值得相信。

若用人工规则表达,可以先问“二十日收益是否超过 5%”,回答为是以后再问“六十日波动是否低于 25%”。只有两个条件同时满足,股票才进入高分组。这种一问一答、根据回答继续走向不同分支的结构,就是决策树

假设训练数据中有八行已经走完的历史样本。四行的二十日收益高于 5%,其中三行后来上涨;另外四行不高于 5%,其中只有一行后来上涨。若树在 5% 处分开,左边上涨比例为 25%,右边上涨比例为 75%。这个阈值让两个分组的答案明显不同,所以程序可能选择它作为第一问。

树选择“5%”只因为这个位置让历史分组更清楚。训练程序会尝试许多候选阈值,寻找能让分组内部答案更一致的位置。分类树常用基尼不纯度或交叉熵衡量混杂程度,回归树则常用平方误差衡量组内数值差异。初学者不必先背公式,只要理解它们都在奖励“分开以后,同组答案更相似”。

flowchart TB
    accTitle: 一棵浅决策树怎样给股票分组
    accDescr: 树先检查二十日收益,只有较强股票继续检查波动,最后得到三个不同预测组

    a{二十日收益<br/>是否高于 5%} -->|否| b[组一<br/>预测较弱]
    a -->|是| c{六十日波动<br/>是否低于 25%}
    c -->|否| d[组二<br/>趋势伴随高波动]
    c -->|是| e[组三<br/>趋势较强且较稳定]

这张图也揭示了树相对线性模型的优势。线性模型会让波动的影响在所有样本上保持同一种加减方式,树却可以只在动量已经较高的分支继续检查波动。变量之间“一个条件成立以后,另一个变量才重要”的关系叫交互作用

一棵树为什么很容易记住历史

如果不限制树继续提问,它可以不断切分,直到每个叶子只剩很少样本。训练数据几乎都能被正确分类,但新的日期只要稍有不同,预测就可能完全改变。这是树模型最典型的过拟合方式。

最大深度限制从树根到最远叶子最多能问几次,叶子最小样本数要求每个最终分组至少保留一定数量的历史样本,最小改进则要求一次新分叉必须带来足够明显的误差下降。这些限制让树放弃解释太细小的历史差异。

量化样本还会随时间变化。某个阈值可能只在一段牛市中有效,换到震荡年份就失去意义。因此树的深度不能根据全部历史的最高成绩决定,而应只在训练窗口内部用后续验证期选择。最终测试期仍要保持封闭。

随机森林怎样把许多不稳定判断平均起来

一棵树可能因为少数样本变化就换掉第一处分叉。随机森林会训练许多棵略有不同的树,再把它们的预测平均。每棵树只看到训练样本的一次有放回抽取,并且每次分叉只考虑一部分特征,所以这些树不会完全相同。

可以把它想成让许多研究员各自查看不同的历史切片和部分指标。单个研究员可能判断偏激,汇总以后偶然误差会互相抵消。这种通过对多个模型平均来降低不稳定性的办法叫集成学习

随机森林仍然不能修复时间错误。它内部的样本抽取只发生在已经确定的训练窗口中,外部训练、验证和测试仍按时间排列。若把未来日期先混入训练,再建立一千棵树,得到的只是更稳定的数据泄漏。

树的数量增加到一定程度以后,平均结果通常会趋于稳定,但计算量继续上升。最大深度和叶子最小样本数仍然决定单棵树是否过于复杂,特征抽样比例则决定各棵树之间有多少差异。参数要一起理解,不能只盯着树的数量。

提升树为什么让后一棵树专门修正错误

随机森林中的树大体同时训练,最后取平均。梯度提升树采用另一种合作方式。第一棵浅树先给出粗略预测,第二棵树重点学习第一棵留下的误差,第三棵继续修正前两棵的不足,许多小步最终叠加成较强模型。

假设某行样本的真实标签为 5%,第一轮只预测 2%,还差 3 个百分点。下一棵树会尝试解释这部分剩余误差。若它补上 1 个百分点,总预测变成 3%;后面的树再继续处理尚未解释的 2 个百分点。真实算法会同时处理全部样本,并用损失函数的梯度决定修正方向,但“后来者专门补前面的缺口”是理解提升方法的核心。

学习率控制每棵新树的修正有多少真正加入总模型。学习率较小,单步更谨慎,通常需要更多树;学习率较大,收敛更快,也更容易追随噪声。树深、叶子数、学习率和树数量共同决定模型容量,不能分别挑一个看起来流行的数值。

XGBoost、LightGBM 和 CatBoost 都属于梯度提升家族。它们在树的生长方式、速度、正则化和类别变量处理上有所不同。对入门研究而言,先理解共同原理并固定公平的时间验证,比争论哪个库名字更先进更重要。LightGBM 的原始论文可以作为进一步阅读材料,见高效梯度提升决策树论文

代码出现以前先明确这一小段要做什么

下面的示例只负责训练一个回归型提升树,它不下载数据、不制作标签,也不构造持仓。进入这段代码以前,X_train 已经是只包含训练期特征的表,y_train 是时间对齐后的未来收益标签,验证和测试数据没有参与任何填补、标准化或参数选择。

import lightgbm as lgb

model = lgb.LGBMRegressor(
    n_estimators=150,
    learning_rate=0.05,
    max_depth=5,
    num_leaves=24,
    reg_lambda=1.0,
    random_state=42,
)

model.fit(X_train, y_train)
prediction = model.predict(X_test)

n_estimators 表示最多叠加多少棵树,learning_rate 控制每棵树加入总预测的步幅,max_depthnum_leaves 限制单棵树的复杂程度,reg_lambda 对过大的叶子取值施加惩罚,random_state 固定随机过程以便复现。最后两行先在训练数据上学习,再对从未参与训练的测试特征给出分数。

这段代码能够运行,不等于研究已经完成。参数候选必须在训练窗口内部比较,测试期只能在方案冻结以后打开一次。还要把预测分数转换成相同交易规则,扣除费用,再与第 26 课的线性模型和更简单的单特征排名比较。

为什么选股问题常常更关心排序

预测某只股票未来收益为 2.13% 很困难,策略也未必需要如此精确。若每天只打算从一百只候选股票中选择十只,更直接的问题是把相对更强的股票排到前面。

排序学习会把同一天的股票看成一组,学习组内谁应该排在谁前面。训练数据必须保留日期分组,因为 1 月 10 日的甲公司应与 1 月 10 日的乙公司比较,不应与三个月后的另一只股票直接争夺同一个名次。模型分数主要用于同日比较,跨日期的 0.8 和 0.8 未必代表同样强度。

第 21 课已经用因子分数认识过排名信息系数,英文常写作 Rank IC。树模型也可以使用同一个指标。它通常计算同一天预测分数排名与未来收益排名的 Spearman 相关系数。结果接近 1,表示两种排名大体同向;接近负 1,表示大体反向;接近 0,则表示没有明显的单调排序关系。

例如三只股票的预测顺序是甲、乙、丙,未来收益顺序也是甲、乙、丙,这一天的 Rank IC 会很高。若未来顺序恰好完全相反,结果为负。这个指标不包含收益差距,也不包含交易成本,所以还要查看分组收益、顶部命中率、换手和最终组合表现。

超参数为什么要在两层时间中选择

模型中由训练程序自动学习的数值叫参数,例如树的分叉阈值和叶子预测。研究者在训练以前设置的深度、学习率和树数量叫超参数。若反复查看测试结果再调整超参数,测试集就变成了另一份训练资料。

更可靠的做法是在外层训练时间内部再划分一段内层验证。少量候选模型先在内层比较,达到预先写下的标准以后,用外层训练数据重新训练一次,最后只在紧随其后的未来区间评价。整个外层窗口向前移动,便形成第 17 课介绍的滚动前推验证。

flowchart TB
    accTitle: 超参数只能在训练时间内部选择
    accDescr: 少量候选设置在内层训练和验证中比较,方案冻结后才进入外层未来测试

    a[外层训练历史] --> b[内层较早部分<br/>拟合候选模型]
    b --> c[内层较晚部分<br/>比较稳定性与换手]
    c --> d{复杂模型是否<br/>稳定超过基线}
    d -->|否| e[保留简单基线]
    d -->|是| f[冻结设置并重训]
    e --> g[外层未来测试一次]
    f --> g

预先写下的标准不应只有最高收益。可以同时要求验证期 Rank IC 方向稳定、分组差异清楚、换手没有失控,并且扣费组合超过简单基线。若复杂模型的预测略好,却需要频繁换仓,最终仍可能选择简单模型。

从预测分数到权重怎样保持透明

模型分数不是资金比例。最容易核对的起点,是在同一天选择分数最高的十只股票,然后等分资金。下面代码出现以前,自然语言规则已经确定,因此每行都能找到对应含义。

score = pd.Series(model.predict(X_today), index=tickers)
selected = score.nlargest(10).index

weight = pd.Series(0.0, index=tickers)
weight.loc[selected] = 1 / len(selected)

第一行把股票代码与模型分数放在一起,第二行取最高的十个代码。第三行先让全部权重为零,第四行只给入选股票分配相同权重。如果当日可交易股票少于十只、某只股票停牌,或者单股权重超过风险上限,组合层还要明确处理。

把分数放进指数函数或直接按概率比例加权,会让高分股票得到更激进的仓位,也会放大模型校准误差。初学者应先保留等权基线,只有当更复杂的权重映射在多个未来窗口中稳定改善风险收益时,才有理由采用。

特征重要性与 SHAP 到底能说明什么

训练完树模型以后,研究者常想知道模型主要使用了哪些特征。按分叉次数或误差下降统计的树重要性可以提供第一张地图,但它可能偏爱取值较多、可切分机会较多的变量。两个高度相关的特征还会互相分摊重要性,新增一个几乎重复的变量以后,原特征排名可能下降,模型预测却没有明显变化。

置换重要性会把某一特征的取值打乱,再观察模型表现下降多少。下降越多,说明当前模型比较依赖这项信息。SHAP 是 SHapley Additive exPlanations 的缩写,可以译作基于夏普利值的加性解释。它把某一次预测相对基准值的差异分摊到各个特征,帮助读者观察哪些输入把这次预测推高或压低。

SHAP 解释的是当前模型怎样使用现有数据,不证明某个变量在经济上导致了未来收益。若模型已经学到数据泄漏,SHAP 只会忠实展示模型依赖那条泄漏特征。解释结果也应跨时间窗口比较。某个特征在一个年份总是推高分数,下一个年份却方向混乱,可能说明关系不稳定或数据口径发生了变化。

最有说服力的检查仍然包括单特征基线、删除一组特征后重新训练的消融实验,以及完全相同时间窗口中的未来表现。模型解释工具用于提出进一步问题,不能代替样本外验证和经济机制分析。

模型选择表应该怎样阅读

模型 它怎样表达关系 适合的起点 最先防范什么
线性或逻辑回归 所有特征按固定权重相加 任何表格任务的第一条基线 关系过于简单
单棵浅树 少量阈值和条件分支 演示非线性与交互 小样本分叉不稳定
随机森林 许多有差异的树取平均 中等规模表格数据 时间抽样和校准问题
梯度提升树 后续树逐步修正已有误差 特征较多的表格排序 超参数搜索和过拟合
排序模型 直接优化同日对象先后 每日选择前若干资产 日期分组错误和成本

复杂模型样本外没有稳定增量、解释在不同窗口大幅改变、换手远高于基线,或者实时数据经常无法准时提供时,都应该退回简单模型。主动减少复杂度说明研究者愿意让结论服从现有证据。

容易弄错的地方

容易出现的做法 隐藏问题 检查办法
让树一直长到训练分数最高 叶子可能只记住极少历史样本 限制深度和叶子样本,并用后续时间验证
比较模型时更换标签或成本 无法判断差异来自模型还是实验条件 固定数据、标签、组合和费用
在最终测试期挑学习率 测试答案参与了超参数选择 只在训练窗口内部设置验证段
把重要性当成经济因果 解释工具只描述当前模型 做消融、跨期稳定性和机制检查
Rank IC 略高就激进加仓 排名指标不含收益幅度与费用 先看分组、换手和扣费组合

一分钟自测

假设一棵深树在训练期几乎没有错误,未来一年却明显输给线性模型。增加更多树能否自动解决问题?请先说出你的理由,再展开答案。

查看答案 不能自动解决。问题可能来自单棵树过深、时间关系变化、数据泄漏或样本不足。随机森林可以减少单树的不稳定,却不能修复错误的时间流程;提升树还可能继续追逐残差。应先限制复杂度,并在相同的向前时间窗口中与线性基线比较。

本课术语

词语 现在应该怎样理解
决策树 用一连串阈值问题把样本分组的模型
交互作用 一个特征的影响会随另一个特征条件而变化
随机森林 训练许多有差异的树并平均预测的集成方法
梯度提升树 让后续浅树逐步修正已有模型误差的方法
学习率 每棵新树对总预测贡献多大的一步
超参数 训练前由研究者设定并在验证期选择的选项
Rank IC 同日预测排名与未来收益排名的相关程度
SHAP 把一次模型预测的变化分摊到各特征的解释方法

课后练习

  1. 基础理解 决策树怎样表达“动量高并且波动不高”?
    提示把两个条件安排成前后相接的问题。
答案树可以先按动量阈值分支,再在高动量分支中检查波动阈值,只有两个条件同时满足的叶子得到高分。
  1. 数字理解 一棵树预测 2%,第二棵树修正 1%,学习率为 0.2 时,总预测增加多少?
    提示提升树只加入修正值的一部分。
答案第二棵树贡献 `1% × 0.2 = 0.2%`,总预测从 2% 增加到 2.2%。
  1. 排错 在 2025 年测试结果上比较十种树深度,再报告其中最好一个,问题是什么?
    提示测试期是否仍然独立。
答案2025 年已经参与超参数选择,不再是独立测试。树深度应在较早训练窗口内部的验证段选择。
  1. 动手修改 把本课等权前十组合改成等权前五,需要改哪一行,单只股票初始权重是多少?
    提示修改 `nlargest` 的数量,权重仍由入选数量决定。
答案把 `nlargest(10)` 攚成 `nlargest(5)`。没有其他限制时,每只入选股票的初始权重为 20%。
  1. 开放思考 某特征 SHAP 重要性长期排名第一,为什么仍不能声称它导致未来收益?
    评价要点回答应区分模型依赖与经济因果,并讨论相关特征、数据泄漏、市场状态变化、消融实验和真正样本外检验。

下一课会把许多加权计算组成一层网络,并解释模型如何通过误差调整连接。继续阅读第 28 课 神经网络基础