跳转至

同一个评分引擎里的三种「没数据」:把最好的维度剔掉,人反而更差

「给个人账本引擎挑刺」系列 · 第 4/5 篇。缺失从来不是中性的:中性分把总分拉向中位,剔除把总分交给剩余维度。我的引擎里两种都有,还加第三种——而实验证明,剔除最好的维度会让评价更低。

TL;DR 同一笔账,仅仅因为"有没有设预算"跨过评级线;不填使用次数反而被扣 9 分——因为剔除的是它最好的维度。缺失的语义必须按缺失原因裁决,而不是按哪个函数好写。

一个评分系统最诚实的时刻,是它面对"没数据"的时候。

现象

五维评审引擎对"缺数据"有三种互相矛盾的处理,全部无文档:

场景 处理 代码
应急金无历史数据 整维剔除 + 权重归一化 src/analysis.rs:163
单位价值没填使用次数 整维剔除 + 归一化,且不提示 src/analysis.rs:229
预算未设置 发中性分 70,保留权重 src/analysis.rs:115

同一个问题——"这个维度没数据怎么办"——在同一份引擎里被回答了三次,答案各不相同。

我一开始的错误判断:默认分是善意的

物证写在代码里:budget_dim 给出 70 分时,还贴心附了一句文案——「该类目未设月预算(设置后此维度会更准)」。善意写在文案里,失真写在分母里:70 分不是"没有信息",它是一个把总分往中位拉的力,而评级线两侧的判定全由总分决定。

另一半直觉是"缺就剔除,最公平"——直到实验证明,把最好的维度剔掉,人反而更差。

排查与关键证据

证据一:同一笔账,三种命运。 合成实验(docs/drafts/evidence/g2-*.txt):同一冲动「连衣裙 ¥129 / 服饰 / 自评 3 / 预计用 60 次」,唯一变量是预算设置:

库 预算状态 预算维得分 综合分 评级
A 设 ¥200,余量充足 100 58 需改进 ⚠️
B 未设置 70(中性分) 51 需改进 ⚠️
C 设 ¥100,超支 20 39 高冲动风险 🚨

同样的购买行为,仅仅因为"有没有顺手设预算"跨过了 40 分评级线(⚠️ → 🚨)——而"设没设预算"与这次购买的实际合理性毫无关系。

证据二:剔除不中性——把最好的维度剔掉,人反而更差。 在库 B 里再登记一条不填"预计使用次数"的(docs/drafts/evidence/g2-b2-no-uses.txt):单位价值维本可拿 90 分,被剔除后综合分从 51 跌到 42。机制在归一化(src/analysis.rs:280):剔除 90 分的维度后,剩余的 25 / 70 / 40 被放大 1/0.7 倍——总分被最差的维度接管。剔除一条你最好的证据,评价反而更低。

证据三:算术可复核,不是玄学。 A−B 的 7 分 = 预算维差 30 分 × 权重 0.20 ÷ 归一化分母 0.85;B−B2 的 8.5 分同理可推。分数对"缺失方式"的敏感度可以精确推导——这正是问题所在:用户看到的是评级 emoji,看不到分母变了。

根因

三种写法各自局部合理:函数手里有什么就用什么——没预算就给默认分,没历史就算不出、剔除。缺的是一次全局裁决:"缺失"的语义必须按缺失原因定(用户没填 / 系统算不出 / 维度不适用),而不是按"哪个函数好写"定。

在阈值驱动的系统里,这一点格外致命:评级线(80/60/40)两侧的判定、以及触发哪条改进建议,全都由综合分决定。缺失处理不一致,意味着同一行为的评价取决于用户填表的完整度——数据越穷的人,被评分系统对待的方式越不一样。

约束与取舍

  • 放弃了"强制填满才能评分":登记摩擦上升,直接顶撞产品第一死因——docs/EVALUATION.md 明文"记录习惯放弃率是行业第一死因,解法是降摩擦"。
  • 放弃了"全部剔除":权重漂移不可控(证据二就是现成的反例)。
  • 现状"混合但无文档":行为不可预测——本文写的就是这个代价。
  • 三者取其一的隐性前提:宁要"带噪声的低摩擦数据",不要"干净但没人记的数据"。这个前提值得写下来,而不是藏在代码里。

可复用检查清单

  1. 每个评分维度回答四选一并写进文档:0 分 / 中性分 / 剔除+归一化 / 报错——判据是缺失原因,不是实现便利。
  2. 剔除必须伴随权重归一化,且输出明示"该维度未参与"。
  3. 缺失场景的建议文案必须区分"数据缺失"与"表现差"——不许把"没设预算"说成"超支"。
  4. 用全数据 / 缺数据两份输入回归同一笔账,断言评级方向可解释(本文证据二就是反向案例)。
  5. 默认分值定期复核:它是否仍然中性,取决于其他维度的分布——分布变了,默认值会悄悄失效。

证据与复现

G2 实验全部输出见仓库 docs/drafts/evidence/g2-*.txt,一键重跑:bash docs/drafts/evidence/run-experiments.sh。实验为合成数据,不含任何真实账本。


本文是「给个人账本引擎挑刺」系列第 4/5 篇:①纯函数内核的污染 → ②没有事务的账本 → ③"72 小时冷却"的真相 → ④三种"没数据" → ⑤让政策会输的测试