状态机里最好的那个区域,数学上永远到不了¶
现象¶
我的量化系统里有一个三态市场状态机:把每个板块的动力学状态判定为 stable(稳态)/ transition(过渡)/ critical(临界)。围绕它建了一整套消费逻辑:板块过滤只允许 stable 行业入池、仓位门控在 critical 时禁止新开仓、过渡期自动缩仓。
问题是:stable 从来没有出现过。一次都没有。
没有报错,没有告警,没有任何异常——只有一个统计学上的痕迹:几万次判定的结果分布里,永远缺一个类别。更要命的是,这个"永远缺一个"在系统里长出了两层完全不同的后果:
- 板块过滤:stable 行业永远是空集 → 每个调仓日都触发兜底回退全市场 → 过滤器形同虚设(A/B 验证里,开过滤和不开过滤的逐日持仓完全相同);
- 仓位门控:系统永远处于 critical/transition → 模拟盘下单引擎长期禁止新开仓。
同一个缺陷,在两个消费点上一个"无害地失效",一个"保守方向地瘫痪"。而它的表面现象,是一个看起来像业务结论的东西:市场从不稳定。
直觉判断的盲区¶
面对"stable 从不出现",直觉给出的路线有三条,每条都看起来合理:
- 当业务结论接受:市场本来波动就大,没有稳态很正常——何况 critical 和 transition 此消彼长,分布看起来是"活的";
- 当参数问题调参:把 ε 调大一点、原型数改一改、训练窗口挪一挪——但在同一个(坏掉的)度量空间里,没有任何参数能修复空间错位;调参注定无效,却每次都会带来"有进展"的错觉;
- 当数据问题补数据:训练样本不够、特征不行、模型不行。
三条路的共同盲区:默认了"距离计算是对的"。验证正确理解的入口,恰恰是绕过一切调参、直接构造反证——输入一个必然落在原型中心的点,看距离是不是零。一个恒为 False 的判定值,最危险的地方不是它错了,而是它错得像一个结论:报告和图表都会顺着"市场从不稳定"讲下去,没有任何异常会拦住你。
至于二次标准化那行代码当初为什么被写出来,已无法还原——它只是低维几何直觉的直译,并且在任何一次代码审查里都长得无害。局限不在于写错了一行,在于没人问过"这个阈值在这个空间里够得着吗"。
排查与关键证据¶
起点是一次 A/B 验证。 我想做"先按板块状态锁定板块、再在板块内选股"的收益验证,四臂对照跑出来,开了过滤的 A1 和不开过滤的 A0 逐日持仓完全相同。方法无效?还是方法根本没被执行?——顺着这个问题挖下去。
第一个证据,反证实验。 构造一个"输入恰好等于某个原型中心"的点:它到这个中心的距离按定义应该是 0。实测:19.13σ。一个点到它自己的距离是 19 倍标准差——只有一种可能:距离计算里的两个坐标不在同一个空间。
根因是二次标准化:模型训练时存入的原型中心已经是标准化空间的坐标,而推理函数又对它做了一次"减均值除方差"。空间错位,距离被系统性放大,ε 覆盖判定恒 False。
第二个证据,量纲分析。 修掉二次标准化之后,stable 仍然是 0。这才是更深的坑:特征空间是 14 维标准化空间,点到最近原型中心的期望距离约 √14≈3.7σ,训练样本的实测中位数在 2~5σ 之间;而配置里的固定 ε=0.15,折算到每一维只有约 0.04σ。这个覆盖球在数学上几乎不包含任何点。ε 不是"太小",是在这个空间里语义蒸发。
第三个证据,校准后的反转。 把 ε 从固定值改为"训练样本到最近原型距离的分位数"(q75 校准出 ε≈3.2,q50 校准出约 2.4),stable 占比从 0 跳到 10% / 4.4%(板块面板库),换市场级模型库后是 46%。两个分位方向一致,排除单点巧合。修复前后各配了 11 项回归测试:中心点距离必须小于十的负六次方、中心点必须落进 ε 覆盖、端到端必须能判出 stable、校准值必须经存取往返保持。
根因¶
三层,一层比一层难自查:
- 表层(bug):存储空间与推理空间的约定不一致。中心存的是标准化坐标,推理时又标准化了一次。
- 深层(设计):高维空间的几何直觉失效。ε 覆盖是从低维几何借来的概念,方法论文档里它理直气壮,落到 14 维标准化空间后,它的数值语义完全变了。阈值不随度量空间重新校准,就只是一段死字母。
- 伴生(工程):同一个 ε 在置信度模块里引用的是配置默认值、在推理模块里引用的是模型携带值——两处来源不同,常量多出处必然漂移。
- 最深层(组织):方法论文档里其实早就写着一条原则:"阈值需再校准"。但它只是一行字。文档里的约束,要么变成代码里的强制环节(校准函数、断言、测试),要么必然失效。
还有一个值得单独说的教训:结果分布本身就是监控对象。一个类别长期零命中,在调试它之前,先把它当作系统疑点——"业务结论"和"系统故障"在这里长得一模一样。
约束与取舍¶
- 放弃固定 ε 的绝对几何语义,改为训练分布分位校准。 固定值可解释、可从方法论直接引用;校准值数据驱动、能落地。代价:ε 失去先验含义,每次重训都可能变,必须随模型元数据持久化、并对旧结果对象做兼容回退。
- 放弃马氏距离 / 逐维校准方案。 各向异性特征空间里球形覆盖仍是近似,但马氏距离的实现和调参复杂度在这个阶段不值。代价:覆盖语义仍是近似——这是一个明知保留的已知缺陷。
- 修复不追求"一步到位的正确阈值",追求"阈值有定义方式"。 校准分位本身也是超参,同样有多重检验风险——这一点在验证报告的局限里写明了,不能装作没有。
可复用检查清单¶
- 任何"距离/相似度阈值"上线前,先打印它在实际度量空间里的分位——不可达的阈值等于没有阈值;
- 度量空间只在代码里定义一次:谁标准化、在哪标准化、存的坐标属于哪个空间,写成约定或类型约束;
- 状态机的每个可达区域,必须有一个"构造出必然落入该区域的输入"的回归测试;
- 分类结果的分布本身要监控:某类别长期零命中不是业务结论,是系统疑点;
- 同一常量被多模块使用时只允许一个出处(随模型持久化),禁止各处兜底默认值;
- 方法论文档里的每条"必须",要么变成代码里的强制环节,要么注定失效。