第 26 章 · 模型选型:没有银弹
这一章要解决什么:前面所有章节都在比较"模型好不好"。 这一章要回答一个更根本的问题:"对我的场景来说,什么叫做'好'?"
最容易踩的坑:把选型当成"挑 R² 最高的"。 更隐蔽的坑是:用场景标签代替量化 —— 听说"实时场景要选线性模型"就选线性模型,却从没测过延迟到底是多少。
本章你需要完成的代码:demos/ch26-model-selection.py
26.1 四个维度的量化
选型不是"排名",是"在约束下求最优"。 所以第一步是把约束量化。
真实输出:
模型 R² 训练 单行预测 可解释 ±σ
线性回归 0.95053 0.01s 0.0004ms 高 无
随机森林(200) 0.96503 4.70s 0.0220ms 中 无
HistGB(300) 0.96429 35.75s 0.0148ms 中低 无
高斯过程(800行) 0.82693 0.47s 0.0204ms 低 有
(GPR 只喂 800 行、只用 cycle 一个特征,R² 不参与横向比较)
(它的 ±2σ 覆盖率 = 91.8%,区间可信)★ 这张表就是选型的原材料。 逐列读:
| 维度 | 数据 | 解读 |
|---|---|---|
| 精度 | 0.95053 ~ 0.96503(三个主流模型) | 极差只有 0.0145 |
| 训练速度 | 0.01s ~ 35.75s | 差 3500 倍 |
| 单行预测 | 全部 < 0.03 ms | 都不构成约束 |
| 可解释性 | 高 / 中 / 中低 / 低 | 线性最好 |
| 不确定性 | 只有 GPR 有 | 且覆盖率 91.8% 可信 |
点开:这张表里有两个反直觉的地方
反直觉一:训练耗时的差异,比精度差异大 3500 倍
精度差异:0.0145(相对差异 1.5%)
训练耗时:0.01s vs 35.75s(相对差异 357500%)但大多数人的注意力 95% 花在精度上。
为什么这是错的:
精度差异 0.0145 的实际含义:
MAE 从 0.00968 降到 0.00790
→ 平均误差从 0.97 个百分点降到 0.79 个百分点
→ 差异 0.18 个百分点
训练耗时差异的实际含义:
离线:无所谓(一周跑一次,35 秒不算什么)
频繁重训(比如每天):35 秒也无所谓
超参搜索(要跑几百次):0.01s × 500 = 5 秒 vs 35.75s × 500 = 5 小时
↑ 这里差异就变成"能做完"和"做不完"的区别了★ 所以"耗时重要不重要"取决于你的工作流,不是一个绝对值。
反直觉二:单行预测耗时全部 < 0.03 ms —— 速度根本不构成约束
很多人会说:"实时场景要用线性模型,因为树模型慢。"
↓
实测:线性 0.0004ms,森林 0.0220ms
↓
100 ms 的延迟预算下,两者都完全没问题
↓
【所以"实时"这个标签,在这里不构成"必须选线性"的理由】★ 这是一个很重要的思维修正:
约束只有在"真的构成约束"时才能用来做取舍。先量化,再取舍 —— 不要凭场景标签做决定。
那什么时候速度会成为约束?
| 场景 | 延迟预算 | 会不会成为约束 |
|---|---|---|
| 离线批处理 | 分钟~小时 | ❌ 不会 |
| Web API | 100~500 ms | ⚠️ 看模型大小和批量 |
| 高频交易 | 微秒级 | ✅ 会 |
| 边缘设备(单片机) | 内存/算力都受限 | ✅ 会(模型大小是关键) |
| 本数据的所有模型 | — | ❌ 都不会 |
结论:在这份数据上,"速度"不是决定性维度。而"不确定性"和"精度"才是。
⚠️ 但关于"训练耗时"有一个必须说明的细节
同一个 HistGB(300 棵)在本章不同位置跑出了:
15.22 s (第 23 章四路横评)
35.75 s (本章第 26.1 节的表)
28.44 s (本章练习 1)
↑
相差 2 倍以上为什么:树模型的训练耗时受并行调度、当前机器负载、内存带宽影响很大, 不是一个稳定指标(n_jobs=-1 时会和系统里其他进程抢 CPU)。
★ 所以对"耗时"这一维度,正确的用法是:
✅ 看数量级:线性是 0.0x 秒级,森林是秒级,提升是十秒级 —— 这个关系是稳定的
❌ 拿具体数值做精确比较:"森林比提升快 7.6 倍" ← 这个倍数每次跑都不一样★ 汇报时的写法:
"线性回归在毫秒级,树模型在秒到十秒级" ← ✅ 稳定的表述
"随机森林 4.70s,比 HistGB 的 35.75s 快 7.6 倍" ← ❌ 换个环境就不成立这条纪律对所有"性能数字"都适用(延迟、吞吐、内存): 报数量级和量测条件,不要报看起来精确的倍数。
26.2 精度维度:换模型的天花板很低
真实输出:
=== ② 精度维度的结论:换模型的天花板很低 ===
三个主流模型 R² 极差 = 0.01449
→ 换模型最多只能再挤出 0.0145;而第 13 章显示【加特征】能涨 0.12★ 把两个数字放在一起,方向就清楚了
单特征 → 七特征 : +0.12183 (第 13 章)
线性 → 随机森林 : +0.01449 (本章)
加特征的收益是换模型的 8.4 倍★ 这不是"随机森林不好",而是"问题的瓶颈不在模型"
数据里的可预测部分(R² 上限)≈ 0.965
↓
线性回归已经拿到 0.95053(占 98.5%)
↓
剩下的 1.5% 需要更复杂的模型去挤
↓
而那 3.5% 的误差(1 - 0.965)是测量噪声,任何模型都消不掉★ 所以选型的结论不是"哪个最好",而是:
在这份数据上,选模型对精度的边际收益已经很小。 选型的意义在于"找到满足约束的最便宜方案",而不是"榨出最后 0.015"。
26.3 不确定性维度:只有 GPR 给区间
真实输出:
=== ④ 不确定性维度:只有 GPR 给区间 ===
用一个具体决策看差别(退役线 0.80):
GPR:0.815 ± 0.055 → 区间 [0.705, 0.925] 跨过 0.80 → 需要人工复检
森林:0.815(单个数字) → 无法判断,只能凭感觉★ 同一个预测值,两种读法给出相反的结论
随机森林说:"0.815"
↓
0.815 > 0.80 → 高于退役线 → "可以继续用"
↓
但模型的平均误差是 0.008 —— 0.815 离 0.80 只差 0.015
↓
【这个数字的精度不足以支撑"换不换"的决定,而你不知道这一点】
GPR 说:"0.815 ± 0.055"
↓
区间 [0.705, 0.925] 跨过了 0.80
↓
正确的动作不是"按 0.815 决定",而是【安排人工复检】★ 这就是"精度不是唯一指标"的具体含义
| 森林 | GPR | |
|---|---|---|
| R² | 0.96503 | 0.82693 |
| 能不能说"我不确定" | ❌ | ✅ |
| 在"决定是否退役"这个动作上 | 给出一个不可靠的确定值 | 主动指出需要复检 |
★ 一个关键的工程认知
点预测的真实问题是:它【隐藏了不确定性】。
↓
"0.815" 和 "0.815 ± 0.055" 看起来都是"0.815"
↓
但后者告诉你"这个数可能偏 0.11",前者让你以为"就是 0.815"
↓
在【决策代价不对称】的场景里,这个差别是决定性的注意:GPR 的 R² 更低(0.82693 vs 0.96503),但它在这个场景更合适。
★ 这里有一个前提必须检查(第 24 章的教训):
# GPR 的区间是可信的,因为覆盖率合格
print(f"±2σ 覆盖率 = {cover:.1%}") # 91.8%,接近理论 95%如果覆盖率只有 29%(第 24 章那个 bug),那 GPR 的区间就是错的, 它在"退役决策"场景里反而不如森林 —— 因为一个错误的"我很确定"会误导决策。
26.4 三种场景,三个答案
真实输出:
=== ⑤ 结论:没有银弹,只有约束下的最优 ===
离线周报(一周一次) → 随机森林 / 提升 理由:精度优先,慢一点无所谓
实时看板(100ms 内) → 线性回归 理由:延迟预算内,精度只差 0.014
退役决策(要风险区间) → 高斯过程 理由:宁可不那么准,也要给 ±σ★ 同一个数据、同一个问题,三个场景三个答案。
这就是"没有银弹"的意思:
选型取决于【约束】,不取决于【排行榜】。
点开:逐个场景的推理链(这才是选型的正确姿势)
场景 1:离线周报(一周跑一次,给质量部门看分布)
第 1 步:列出约束
· 延迟:无要求(一周一次)
· 成本:可以接受几分钟
· 输出:一批设备的健康度分布
第 2 步:确定主导维度
→ 精度优先(其他维度都不构成约束)
第 3 步:选择
→ 随机森林(0.96503)或提升(0.96429)
→ 两者精度几乎相同,随机森林训练更快(4.70s vs 35.75s)→ 选随机森林
第 4 步:说明不选其他的理由
→ 线性(0.95053):精度低 0.0145,而这里精度是唯一约束
→ GPR(0.82693):精度明显低,且这里不需要区间场景 2:实时看板(每来一组数据要 100 ms 内出结果)
第 1 步:列出约束
· 延迟:100 ms
· 输出:单条记录一个数
第 2 步:量化约束是否真的构成约束
→ 实测单行预测:线性 0.0004ms、森林 0.0220ms
→ 【都远低于 100 ms】
第 3 步:约束不成立 → 退回到精度优先
→ 那还是选随机森林?
★ 但这里有一个现实考量:
实时系统通常要求模型"小、快、可解释、易维护"
线性回归的系数能写成一个公式,部署和排查都简单得多
而精度只差 0.0145(MAE 差 0.0018)
↓
如果业务上 0.0018 的 MAE 差异可以接受 → 选线性更划算★ 场景 2 是最有意思的:它的正确答案不是由技术指标唯一决定的, 而是"技术指标的差异能否被业务接受"这个判断。
场景 3:退役决策(要决定设备换不换)
第 1 步:列出约束
· 决策代价不对称:
误判"该换"(其实不用换)→ 浪费设备
误判"不用换"(其实该换)→ 设备故障风险
· 需要:知道"这个预测有多可信"
第 2 步:确定主导维度
→ 不确定性优先
第 3 步:选择
→ GPR(能给 ±σ,且覆盖率 91.8% 合格)
第 4 步:说明代价
→ R² 从 0.965 降到 0.827 —— 精度放弃了 0.14
→ 换来的是"哪些预测需要人工复检"这个能力★ 三个场景的推理链有一个共同结构
① 列出约束(延迟/成本/输出形式/决策代价)
② 量化每个约束是否真的构成约束
③ 找出主导维度
④ 选择 + 说明代价
⑤ 说明不选其他的理由★ 第 ② 步是最容易被跳过的,也是最重要的。
它防止你"为了满足一个不存在的约束"而牺牲精度。
26.5 常见坑
① 只比精度 → 忽略了"能不能给不确定性"这类根本差异
② 用场景标签代替量化("实时就要用线性模型")→ 从没测过延迟
③ 横评时四路条件不同(划分/特征/预处理)→ 数字不可比
④ 把训练耗时当成"速度" → 部署关心的是单行预测耗时和模型大小
⑤ 只报一个维度 → 别人无法判断你的取舍是否合理
⑥ 忘了说明"不选其他模型的理由" → 结论像是拍的
⑦ 引用了不可信的区间 → GPR 的 σ 必须先验覆盖率(第 24 章)26.6 完整示例与输出
cd code
python demos/ch26-model-selection.py真实输出:
=== ① 四个维度的量化:精度 / 速度 / 可解释性 / 不确定性 ===
模型 R² 训练 单行预测 可解释 ±σ
线性回归 0.95053 0.01s 0.0004ms 高 无
随机森林(200) 0.96503 4.70s 0.0220ms 中 无
HistGB(300) 0.96429 35.75s 0.0148ms 中低 无
高斯过程(800行) 0.82693 0.47s 0.0204ms 低 有
=== ② 精度维度的结论:换模型的天花板很低 ===
三个主流模型 R² 极差 = 0.01449
=== ⑤ 结论:没有银弹,只有约束下的最优 ===
离线周报(一周一次) → 随机森林 / 提升
实时看板(100ms 内) → 线性回归
退役决策(要风险区间) → 高斯过程本章练习
练习 1:给四个模型做一次完整的四维量化
用四个模型(线性、随机森林 100 棵、HistGB、GPR)在同一份按设备划分的数据上, 测出四个维度的数字,填进一张表。
要求:
- 精度用 R²;
- 速度分"训练耗时"和"单行预测耗时"两列;
- 可解释性用"高/中/低"标注并说明依据;
- 不确定性用"有/无"标注;对有的那个,报出 ±2σ 覆盖率。
参考答案
import time
import numpy as np
import pandas as pd
from sklearn.ensemble import HistGradientBoostingRegressor, RandomForestRegressor
from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.gaussian_process.kernels import RBF, WhiteKernel
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score
from sklearn.model_selection import GroupShuffleSplit
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
df = pd.read_csv("data/battery/soh_features.csv")
FEATS = ["cycle", "mean_charge_voltage_v", "mean_temp_rise_c", "resistance_mohm",
"coulombic_eff", "cap_fade_rate_ah_per_100", "temp_std_c"]
X, y, groups = df[FEATS], df["soh"], df["cell_id"]
tr, te = next(GroupShuffleSplit(n_splits=1, test_size=0.2, random_state=42)
.split(X, y, groups=groups))
Xtr, Xte, ytr, yte = X.iloc[tr], X.iloc[te], y.iloc[tr], y.iloc[te]
rows = []
def bench(name, model, Xf, yf, Xt, interp):
t0 = time.time(); model.fit(Xf, yf); fs = time.time() - t0
t0 = time.time(); pred = model.predict(Xt); pr = (time.time() - t0) / len(Xt) * 1000
rows.append((name, r2_score(yte, pred), fs, pr, interp, "无"))
bench("线性回归", Pipeline([("s", StandardScaler()), ("m", LinearRegression())]),
Xtr, ytr, Xte, "高")
bench("随机森林(100)", RandomForestRegressor(n_estimators=100, random_state=42, n_jobs=-1),
Xtr, ytr, Xte, "中")
bench("HistGB", HistGradientBoostingRegressor(max_iter=300, learning_rate=0.05, max_depth=4,
random_state=42, early_stopping=False),
Xtr, ytr, Xte, "低")
# GPR:单特征 + 抽子集
rng = np.random.default_rng(42)
gi = rng.choice(tr, size=800, replace=False)
k = (RBF(30.0, length_scale_bounds="fixed")
+ WhiteKernel(1e-3, noise_level_bounds=(1e-8, 1e1)))
gpr = GaussianProcessRegressor(kernel=k, normalize_y=True, random_state=42)
t0 = time.time(); gpr.fit(df[["cycle"]].iloc[gi], y.iloc[gi]); fs = time.time() - t0
t0 = time.time(); mu, sd = gpr.predict(df[["cycle"]].iloc[te], return_std=True)
pr = (time.time() - t0) / len(te) * 1000
rows.append(("高斯过程(800行)", r2_score(yte, mu), fs, pr, "低", "有"))
cover = np.mean(np.abs(yte.to_numpy() - mu) <= 2 * sd)
print(f"GPR ±2σ 覆盖率 = {cover:.1%}\n")
print(f"{'模型':<18}{'R²':>9}{'训练':>9}{'单行':>11}{'可解释':>8}{'±σ':>5}")
for n, r2, fs, pr, it, sg in rows:
print(f"{n:<18}{r2:>9.5f}{fs:>8.2f}s{pr:>10.4f}ms{it:>8}{sg:>5}")期望输出:
GPR ±2σ 覆盖率 = 91.8%
模型 R² 训练 单行 可解释 ±σ
线性回归 0.95053 0.02s 0.0005ms 高 无
随机森林(100) 0.96487 2.71s 0.0124ms 中 无
HistGB 0.96429 28.44s 0.0192ms 低 无
高斯过程(800行) 0.82693 0.47s 0.0204ms 低 有★ 四个维度的标注说明
| 维度 | 怎么看 |
|---|---|
| 精度 | R²(也可以补 MAE,给业务看) |
| 训练耗时 | 影响"能不能频繁重训 / 做超参搜索" |
| 单行预测 | 影响"能不能上实时服务" |
| 可解释性 | 线性"高"(系数就是一个公式);森林"中"(有重要性但看不到方向);HistGB"低"(几百棵树的组合,说不清);GPR"低"(核函数不直观) |
| ±σ | 只有 GPR 有,且必须报覆盖率证明它可信 |
★ 这张表最该注意的两点
① 单行预测耗时四者都在 0.03 ms 以内
说明"实时场景"在这份数据上【不构成约束】
↓
如果你因为"实时"而选了线性模型,那是基于误解做的决定② GPR 的 R² 低是"条件不同"造成的
GPR:800 行 + 1 个特征
其他:17,244 行 + 7 个特征
↓
这个比较【不公平】—— 报数时必须说明★ 一个完整的"四维表"应该再补一列"适用场景":
extra = {
"线性回归": "基线;可解释性要求高",
"随机森林(100)": "表格数据稳健起点",
"HistGB": "精度优先;有缺失值也扛得住",
"高斯过程(800行)": "样本少 + 需要风险区间",
}练习 2:为一个真实场景写选型建议
场景:你要给一家工厂做一个"设备健康度预警系统",约束如下:
- 每小时对全部在役设备(约 5000 台)算一次健康度;
- 结果推送给 3 个工程师,他们每天最多能人工复检 20 台;
- 误判"该检修"会浪费人力,漏判"该检修"可能导致停机事故;
- 系统跑在一台普通服务器上,没有 GPU。
写出你的选型建议(不超过 6 句话),必须包含:选什么、为什么、代价是什么。
参考答案
参考建议:
推荐用梯度提升(HistGB)做主体预测 + 高斯过程做风险分诊的组合。 理由:每小时 5000 台、单行预测在 0.01 ms 量级,速度完全不构成约束, 所以精度优先(HistGB 的 R² 0.96429 最高);但"漏判会导致停机事故"意味着 决策代价不对称,必须知道哪些预测不可信 —— 这需要一个能给区间的高斯过程。 用它把预测值附近的区间算出来,凡是区间跨过预警线的设备就进入"人工复检"队列, 每天正好排满 20 台。代价是 GPR 是 O(n³),只能对"高风险子集"跑(几百台), 不能对全量 5000 台跑 —— 这也是为什么用两个模型分工,而不是只用一个。
★ 这段建议的结构拆解
| 要素 | 在文中的位置 |
|---|---|
| 选什么 | 第 1 句(GBDT + GPR 组合) |
| 为什么(速度不构成约束) | 第 2 句(量化了 5000 台/小时的可行性) |
| 为什么(需要不确定性) | 第 2-3 句(决策代价不对称) |
| 怎么用(落成流程) | 第 4 句(区间跨线 → 复检队列,对齐 20 台/天) |
| 代价是什么 | 第 5 句(O(n³),只能对子集跑) |
★ 这个答案的关键洞察:两个模型分工
约束之间是矛盾的:
· "全量 5000 台" → 需要快模型
· "必须知道风险" → 需要 GPR(慢)
一个模型解决不了 → 拆成两个阶段:
第 1 阶段:HistGB 对全量跑(快)→ 得到预测值
第 2 阶段:GPR 只对"预测值靠近预警线"的设备跑(几百台)→ 得到区间
第 3 阶段:区间跨线的进复检队列★ 这个模式在工程里非常常见,叫"two-stage / cascade":
便宜模型筛一遍 → 贵的模型只处理"需要精细判断"的那部分
↓
总成本可控,且关键部分享有最好的精度★ 一个可以运行出来的简化版
# 第 1 阶段:快模型算全量
mu_all = gbdt.predict(X_all)
# 第 2 阶段:只对"靠近预警线"的算区间
near = np.abs(mu_all - 0.80) < 0.10 # 落在 0.70~0.90 之间的
idx_near = np.where(near)[0]
mu_g, sd_g = gpr.predict(X_subset.iloc[idx_near], return_std=True)
# 第 3 阶段:区间跨线的进复检队列
lo, hi = mu_g - 2 * sd_g, mu_g + 2 * sd_g
need_check = (lo < 0.80) & (hi > 0.80)
print(f"全量 {len(mu_all)} 台 → 需精算 {len(idx_near)} 台 → 进复检 {need_check.sum()} 台")★ 这个练习最重要的一点
"选哪个模型"这个问题,答案常常是【组合】,而不是"某一个"。
↓
而且组合的依据来自【约束的量化】(5000 台、20 台/天、代价不对称)
↓
不是来自"哪个 R² 高"练习 3:为什么"用场景标签代替量化"是错的?
有人这样说:"实时看板场景,肯定要选最快的模型,所以用线性回归。"
请指出这个推理的问题,并给出正确的推理方式。
参考答案
这个推理有三个问题。
问题一:没有量化"实时"到底是多少
"实时"可能是:
· 100 ms 内(Web 服务)
· 1 秒内(看板刷新)
· 1 分钟内(准实时报表)
· 1 小时内(批处理)
↓
每个量级的约束强度完全不同
↓
而【没有量化,就无法判断它是否构成约束】问题二:把"最快的模型"当成了目标
"选最快的"这个目标本身是错的 ——
↓
如果所有模型都满足延迟要求,那"最快"就没有意义了
↓
正确的目标应该是:"在满足约束的前提下,最大化你真正在意的那个维度"问题三:没有验证"树模型真的慢"这个假设
本数据的实测:
单行预测耗时:
线性回归 0.0004 ms
随机森林 0.0220 ms ← 慢 55 倍
HistGB 0.0148 ms但看绝对值:
100 ms 的预算下:
线性 用了预算的 0.0004%
森林 用了预算的 0.022%
↓
【两者都绰绰有余】★ 正确的推理方式
第 1 步:量化约束
"实时" = ? ms(去问业务方,或者去查系统需求文档)
第 2 步:测出候选模型在这个约束下的表现
单行预测耗时、批量预测吞吐、模型加载时间、内存占用
第 3 步:判断约束是否成立
如果所有候选都在预算内 → 这个约束不构成约束 → 排除它
如果只有部分候选在预算内 → 它构成约束 → 用它筛掉不合格的
第 4 步:在剩下的候选里,按真正的目标维度选
如果精度是目标 → 选精度最高的
如果需要不确定性 → 选能给的★ 一个真实的教训
某团队认为"实时场景必须用线性模型",于是放弃了 GBDT
↓
后来做性能测试发现:GBDT 单次预测 8 ms,而延迟预算是 500 ms
↓
【他们为一个不存在的约束,牺牲了 0.03 的 R² 和大量的实际效果】★ 一条通用原则
约束必须被量化,才能被用来做取舍。 没有量化的"约束"只是一个猜测,而基于猜测做的技术决策, 很可能是在优化一个不存在的瓶颈。
★ 这个原则的推广
它不只适用于延迟。所有"性能约束"都一样:
| 约束类型 | 常见误解 | 正确做法 |
|---|---|---|
| 延迟 | "实时必须用简单模型" | 测 P50/P99 延迟,和预算对比 |
| 内存 | "树模型太占内存" | 测模型文件大小和运行时峰值 |
| 训练时间 | "深度模型训不起" | 测一次完整训练要多久、多久重训一次 |
| 数据量 | "样本不够不能上树模型" | 看学习曲线,而不是看经验值 |
★ 一句话总结
先测量,再取舍。 这条纪律在整本书里出现了很多次 (划分前先看数据结构、调参前先看学习曲线、选型前先量化约束), 它是同一个思维习惯的不同应用。
面向工程实践:选型是一次"被记录的决策"
① 选型结论必须留下"为什么不选别的"
❌ 只写结论:
"选用随机森林。"
✅ 完整的决策记录:
"选用随机森林(n_estimators=200)。
理由:三个主流模型 R² 极差仅 0.0145,精度维度上差异很小;
随机森林训练 4.70s,比 HistGB 快 7.6 倍,精度相当(0.96503 vs 0.96429);
不选线性:精度低 0.0145,而本场景精度是唯一约束;
不选 GPR:R² 低 0.14,且本场景(离线周报)不需要区间。"★ 后面那句话的价值:
六个月后有人问:"为什么不用 XGBoost?"
↓
翻到这份记录 → 有数字、有理由 → 不用重新做一遍实验② 一个可复用的选型决策记录模板
## 模型选型决策(2026-10-10)
### 场景与约束
| 约束 | 量化值 | 是否构成约束 |
|---|---|---|
| 延迟预算 | 100 ms | ❌ 否(最快 0.0004ms,最慢 0.022ms,都远低于预算) |
| 训练频率 | 每天 1 次 | ❌ 否(最慢 35.75s,可接受) |
| 需要风险区间 | 是 | ✅ 是 |
| 可解释性要求 | 中(要给工程师看趋势) | ⚠️ 弱约束 |
### 候选与量化结果
| 模型 | R² | 训练 | 单行 | 可解释 | ±σ |
|---|---|---|---|---|---|
| ... |
### 决策
**选定:<模型>**
- 主导维度:<哪个>
- 理由:<数字支撑>
- 代价:<放弃了什么>
### 未选说明
- <模型 A>:<为什么不选>
- <模型 B>:<为什么不选>
### 局限
- <数据范围 / 覆盖率 / 合成数据 / 未覆盖的子群>③ 为什么"局限"这一节不能省
没有局限说明的结论 = 无法判断它什么时候会失效
↓
而模型一定会失效(数据漂移、场景变化、上游改动)
↓
那时你需要知道:"原来的结论建立在什么假设上"本项目的三条局限(第 27 章的报告会写进去):
① 数据是合成的:单调退化、无随机跳变、无工况切换
② 覆盖面有限:只有 60 支设备、4 个批次
③ GPR 的区间只在训练分布内可信(超出 cycle 1440 属于外推)★ 最后:这一章想留给你的思维
"用哪个模型?"
↓
这个问题本身是不完整的。
↓
完整的问法是:"在 <这些约束> 下,为了 <这个目标>,用哪个模型最划算?"
↓
把约束量化、把目标说清、把取舍记录下来
↓
【这就是"选型"和"挑一个"的区别】下一章(阶段目标)会把这一切拼起来: 一条命令产出一张对比表、两张图、一份带结论的报告。