Skip to content

第 02 章 · 课程地图 ​

这一章要解决什么:32 章从哪读起、哪些是重点、卡住了回看哪一章。

最容易踩的坑:把这本书当"特征清单"读。 它不是"给你 20 个特征公式",而是教你判断一个特征值不值得做。 只抄公式不看判断方法,换一份数据就失效了。

本章你需要完成的代码:无(这一章是地图,不用敲代码)

2.1 全书一张图 ​

text
                    上一层:监督学习基础(另一本书)
                ┌──────────────────────────────────────┐
                │  X/y 切分 · 四个指标 · 按实体划分      │
                │  交叉验证 · 树/森林/提升 · 正则化      │
                └──────────────────────────────────────┘
                                  ↓ 本书从这里开始
   ┌──────────────────────────────────────────────────────────────┐
   │  A 视角转变(01–04)                                          │
   │     为什么横截面特征到顶了 · 模型只看到一行                    │
   └──────────────────────────────────────────────────────────────┘
                                  ↓
   ┌──────────────────────────────────────────────────────────────┐
   │  B 造时序特征(05–10)     ★ 本书第一个重点                    │
   │     滑动窗口 · 分组与排序 · 冷启动 NaN · 差分斜率 · 滚动统计   │
   │     构造纪律                                                  │
   └──────────────────────────────────────────────────────────────┘
                                  ↓
   ┌──────────────────────────────────────────────────────────────┐
   │  C 让特征能用(11–16)                                        │
   │     缩放 · 编码 · ColumnTransformer · 特征选择                │
   │     消融实验 · 特征账本                                        │
   └──────────────────────────────────────────────────────────────┘
                                  ↓
   ┌──────────────────────────────────────────────────────────────┐
   │  D 泄漏专题(17–22)       ★★ 全书重心                        │
   │     三种泄漏 · 亲手做出 R²=1.000000 · 防泄漏检查清单           │
   └──────────────────────────────────────────────────────────────┘
                                  ↓
   ┌──────────────────────────────────────────────────────────────┐
   │  E 别过拟合(23–27)                                          │
   │     过拟合的形状 · 早停 · 正则化 · 调参 · 调参的收益上限       │
   └──────────────────────────────────────────────────────────────┘
                                  ↓
   ┌──────────────────────────────────────────────────────────────┐
   │  F 集成与收口(28–32)                                        │
   │     多窗口平均 · 模型融合 · ❖ 阶段目标 · 从清单到流程          │
   └──────────────────────────────────────────────────────────────┘

★ 图例(两个符号含义不同,别混)

符号含义
★★全书重心:第 17–22 章的泄漏专题。如果只读一部分,读它。
★该组内的重点章:这组的知识主要靠它承载
◆补充章:源课程里没有独立步骤,是本书为"讲通"而补的

分界线在 C 组和 D 组之间:

A + B + C = 怎么造出好特征("加法")
D         = 怎么识别假特征("减法")  ← 更值钱

为什么"减法"更值钱:造一个特征的成本是几分钟,但用错一个特征的代价是上线后失效。 这本书把最多的篇幅给了"怎么发现自己在骗自己"。

2.2 32 章逐章清单 ​

A 视角转变(01–04)

章标题记号你会学到
01环境与数据准备三层数据、校验和、自检脚本
02课程地图这一章(依赖关系与读法)
03为什么横截面特征到顶了三个收益的量级对比
04信息结构:模型只看到一行◆"特征"到底是什么 —— 模型只看到一行数字

B 造时序特征(05–10)

章标题记号你会学到
05滑动窗口:把一段曲线压成几个数★窗口 = 采样;rolling 的三个默认语义
06rolling 的分组与排序跨设备串线 —— 最危险的静默错误
07冷启动 NaN 与 dropna 的代价为什么 fillna(0) 比丢行更毒
08差分与斜率绝对值说"多健康",变化量说"往哪走"
09滚动统计与极差极差作为稳定性指标
10特征构造的纪律◆统一判据:预测这一刻,我拿得到吗

C 让特征能用(11–16)

章标题记号你会学到
11缩放:让系数可比★Standard vs MinMax;"缩放提精度"的真因
12类别编码为什么 Label 编码会误导线性模型
13ColumnTransformer◆把数值列与类别列的处理合成一个预处理器
14特征选择:相关性与 k 曲线冗余怎么识别
15消融实验★逐组拿掉重训 —— 把"重要"变成数字
16特征账本◆给每列记账(交付物)

D ★★ 泄漏专题(17–22)

章标题记号你会学到
17三种泄漏总览◆划分 / 预处理 / 特征;统一判据
18泄漏①:划分泄漏★★按行随机为什么会虚高
19泄漏②:预处理泄漏★★Pipeline 的真正意义
20泄漏③:特征泄漏★★未来信息;cycle_frac 这类钩子
21亲手做出 R² = 1.000000★★高潮:一列 soh − 0.80 就能骗过所有人
22防泄漏检查清单★★交付物;从清单到流程卡点

E 别过拟合(23–27)

章标题记号你会学到
23过拟合的形状训练涨、验证不涨 —— 怎么分辨真假
24早停训练停在合适的位置
25正则化:L1 / L2 / 树深度三种"刹车"分别刹在哪
26超参搜索GroupKFold + 网格/随机搜索
27调参的收益上限◆为什么调参只涨千分之几

F 集成与收口(28–32)

章标题记号你会学到
28多窗口平均不同回看窗口;共同测试集口径
29模型融合权重必须用验证集定
30❖ 阶段目标:精度优化报告★一条命令产出完整报告
31从清单到流程卡点◆让纪律真正生效
32下一本:从离线到在线◆还有什么没解决

2.3 依赖关系:哪些章不能跳 ​

硬依赖(跳了会看不懂):

text
05 滑动窗口 ──→ 06 分组排序 ──→ 07 冷启动 NaN
                    │
                    ├──→ 08 差分斜率
                    └──→ 09 滚动统计 ──→ 10 构造纪律
                                              │
                                              ↓
                                        17 三种泄漏总览
                                              │
                    ┌─────────────────────────┼─────────────────────────┐
                    ↓                         ↓                         ↓
              18 划分泄漏              19 预处理泄漏              20 特征泄漏
                                                                        │
                                                                        ↓
                                                              21 亲手做出 1.000000
                                                                        │
                                                                        ↓
                                                              22 防泄漏检查清单

关键依赖说明:

依赖为什么不能跳
05 → 0605 讲 rolling 的语义,06 讲"忘了分组会怎样" —— 先懂语义才看得懂错误的可怕
10 → 1710 提出统一判据"预测这一刻拿得到吗",17 把它扩展成三种泄漏的分类
11 → 1919 的预处理泄漏要用到 11 讲的缩放与 Pipeline
16 → 2222 的清单复用 16 的"特征账本"格式
15 → 2727 用 15 的消融方法论证"调参收益上限"

软依赖(跳了会少一层理解,但不影响读下去):

text
03 三个收益量级  ──→  决定你要不要读 C、E 两组
04 信息结构      ──→  理解 05 为什么"窗口"这个动作有意义
12 编码          ──→  13 ColumnTransformer 会顺带复习

2.4 时间不够怎么读 ​

四条路线,按可用时间选。

路线 1:只有 3 小时 —— 读"最贵的 3 章"

text
03(为什么到顶了)→ 15(消融实验)→ 21(亲手做出 1.000000)

为什么是这三章:

03 告诉你【该往哪改进】
15 告诉你【怎么判断一个特征值不值得做】
21 告诉你【分数可以完全骗过你】
   ↓
三章合起来 = 特征工程的完整世界观,不需要写代码

路线 2:有一天 —— 加技能组

text
路线 1 + 05(滑动窗口)+ 06(分组排序)+ 18(划分泄漏)+ 20(特征泄漏)

这五章加上路线 1 的三章,就是特征工程的 80%。

路线 3:有一周 —— 按 B + D 两组走

text
05 → 06 → 07 → 08 → 09 → 10   (B 组:怎么造)
13 → 14 → 15 → 16              (C 组:怎么判断)★ 15 必读
17 → 18 → 19 → 20 → 21 → 22   (D 组:怎么不骗自己)★★ 全组必读

跳掉 01/02(自己看环境)、11/12(上一本讲过)、23–29(诊断与调参)、30–32(收口)。

路线 4:按顺序全读(推荐)

每一章都依赖前面建立的口径,尤其是"只含历史"这条纪律贯穿全书。

点开:每章的"最小可读单元"是什么?

如果你时间极度碎片化,可以从任何一章的这个部分开始:

部分价值适合什么时候读
开头「这一章要解决什么」判断这一章要不要读挑选章节时
「可运行示例」+ 真实输出核心内容有时间动手时
「常见坑」速查表遇到问题时
「本章练习」检验理解学完一章后
「面向工程实践」怎么用准备落地时

★ 如果只有 10 分钟:读开头 + 「常见坑」。 常见坑是每章信息密度最高的部分 —— 它直接列出"你会怎么错"。

★ 如果想深入:先自己做练习,再点开答案对照。

一个具体建议:

读第 06 章(分组与排序)时:
  ① 先看开头("最危险的静默错误")
  ② 直接跳到「常见坑」,看那三行错误的代码
  ③ 再回头读「可运行示例」,看它错得到底多离谱(0.8123 vs NaN)
  ④ 最后做练习

这个"先看坑、再看原理"的顺序,在读"常见错误"类章节时比顺序读更有效。

2.5 每条路线都会遇到的三条纪律 ​

这三条纪律在全书反复出现。贴在这里,卡住时回看。

纪律一:口径比代码重要

python
# ❌ 含当前行 —— 特征里混进了当前行的标签
df["soh_win_mean5"] = g["soh"].transform(lambda s: s.rolling(5).mean())

# ✅ 只含历史 —— shift(1) 把当前行推出去
df["soh_win_mean5"] = g["soh"].transform(lambda s: s.shift(1).rolling(5).mean())

记住这三件事的顺序:

① 先按(实体, 时间)排序   sort_values(["cell_id", "cycle"])
② 再按实体分组             groupby("cell_id")
③ 最后只含历史             shift(1) 之后才 rolling

任何一步漏掉,结果都错,而且不报错。

纪律二:分数不是判据

本书里有三次"分数不提醒你"的实测:
  ① 忘了分组 → 特征值错了,分数几乎没变
  ② fillna(0) 代替 dropna → 线性模型掉 0.056,树模型却无感
  ③ 加一列 soh − 0.80 → R² 恰好 1.000000

所以:

不要用"分数没变"证明"我没写错"。 要用结构检查(值域、NaN 数、量纲、恒等关系)来证明。

纪律三:信息上限由特征决定,不由超参决定

第 27 章会看到:调参后测试 R² 反而【略降】
   ↓
为什么?因为特征已经把可预测性吃到 0.999
      调参能动的只有千分之几
   ↓
推论:分数卡住时,先问"特征里还有信息吗",而不是"参数调够了吗"

2.6 常见坑 ​

text
① 把这本书当"特征公式清单" → 它教的是判断方法,不是 20 个公式
② 跳过 05–06 直接做特征   → rolling 的语义没搞清,后面全是静默错误
③ 跳过 D 组(17–22)      → 这是全书重心,跳了等于没读这本书
④ 只看"可运行示例"不看"常见坑" → 常见坑是信息密度最高的部分
⑤ 只读不做练习            → 特征工程是"手感",看懂和做对差很远
⑥ 记住结论但不记口径      → 换一份数据就失效

★ 关于 ⑥

"用过去 5 个窗口的均值" 这句话本身是【不完整】的
   ↓
完整说法必须包含四个信息:
   · 按什么分组(每支设备内)
   · 排好序了吗(按循环次数升序)
   · 含不含当前窗口(不含,用 shift(1))
   · 窗口长度是多少(5 个窗口 ≈ 15 圈)
   ↓
【少一个,别人就无法复现你的特征】

这也是第 16 章"特征账本"要解决的问题 —— 它强迫你把每个特征的口径写清楚。

2.7 完整示例与输出 ​

本章不需要运行代码。

但建议现在就做一件事:确认你的数据包解压正确。

bash
cd code
python check_env.py

期望看到(节选):

text
✅ Python 版本:CPython 3.13.x
✅ numpy       2.5.x
✅ pandas      3.0.x
✅ matplotlib  3.11.x
✅ sklearn     1.9.x
✅ 数据文件:…/code/data/battery
   cycle_raw.csv(共 3,767 KB,69,592 行含表头)
   soh_features.csv(共 1,221 KB,21,240 行含表头)
   soh_features_v2.csv(共 2,959 KB,21,240 行含表头)
   cells.csv(60 支设备的真值)
⚠️  xgboost      未安装(可选)
✅ 全部通过。下一步:从第 03 章开始,把代码敲进 demos/ 里跑起来。

如果这一步没通过,先回第 01 章。

本章练习 ​

练习 1:找出你该读的路线

根据你的可用时间,从 2.4 节的四条路线里选一条,然后回答:

  1. 你选哪条?为什么?
  2. 这条路线里,哪一章是你最需要的?
  3. 有没有哪一章是"我暂时不需要,但以后一定会回来读"的?
参考答案

没有标准答案 —— 这一题的目的是让你主动规划,而不是被动线性阅读。

一个示例回答(假设你是"有一天时间、已经做过特征工程"的人):

  1. 我选路线 2。我已经在项目里做特征,但分数总是卡住,说明问题不在"会不会写", 而在"判断得对不对"。
  2. 我最需要第 15 章(消融实验)。我现在的做法是"加一堆特征看分数涨没涨", 没有系统性地"逐组拿掉重训"。第 15 章会告诉我"加 10 列可能等于没加"。
  3. 第 22 章(防泄漏检查清单) 以后一定会回来 —— 因为它是交付物, 我要在每次上线前对着它过一遍。

★ 这个练习的真正价值

"哪一章我最需要" 这个问题逼你想清楚【你现在的瓶颈是什么】
   ↓
是"不会造特征"      → 读 B 组
是"造了但不知道有没有用" → 读 C 组
是"分数高但不敢信"   → 读 D 组(★ 最常见)
是"卡住了想调参"    → 读 E 组
   ↓
【先定位瓶颈,再选路线】—— 而不是从第 01 章开始顺序读

★ 一个反直觉的建议

如果你的分数已经很高(比如 R² > 0.99),最该读的是 D 组,不是 E 组。

R² = 0.999 时,你的第一反应可能是"再调调参挤到 0.9995"
   ↓
但更该问的是:"这个 0.999 是真的吗?"
   ↓
本书第 21 章会给你一个 1.000000 的真实例子 —— 而那完全是假的

分数越高,越该怀疑。 这是本书最重要的一条元纪律。

练习 2:画出你自己的依赖图

本书的章节顺序是为教学设计的,不一定是你项目里的执行顺序。

请为你自己的一个真实项目,画出:

  1. 你现在的特征是从哪来的(原始数据 → 特征的过程);
  2. 这个过程里哪些步骤可能泄漏;
  3. 你会按什么顺序去做(不一定是本书的章号顺序)。
参考答案

示例(假设你在做一个"用户流失预测"项目):

① 特征来源

text
原始事件流(用户每天的行为日志,一行 = 一个事件)
   ↓ 按用户-天聚合
日粒度行为表(一行 = 一个用户一天)
   ↓ 滚动窗口
用户特征表(一行 = 一个用户,含过去 7/30/90 天的统计)

② 可能泄漏的地方(对照本书三种泄漏)

本书的泄漏类型我的项目里对应的风险用本书哪一章的判据
划分泄漏同一用户的多天数据跨训练/测试集18 章:按用户划分,不是按行
预处理泄漏先对全量用户算归一化统计量,再划分19 章:fit 只能在训练集上
特征泄漏"距上次活跃天数"用了未来的登录记录20 章:预测这一刻拿得到吗

★ 第 3 类是最需要小心的:

python
# ❌ 用了未来信息:这个"最后活跃距今"是从全量数据算的
user["days_since_last_active"] = (NOW - user["last_active_date"]).dt.days

# ✅ 对每个预测时点,只用那一刻之前的记录
def days_since_last_active_asof(events, asof_date):
    past = events[events["date"] <= asof_date]
    return (asof_date - past["date"].max()).days

③ 我的执行顺序

text
① 先定"预测时点"(as-of date)—— 这是全书的统一判据
      ↓
② 按用户划分(不是按行)
      ↓
③ 构造只含历史的特征(shift / as-of join)
      ↓
④ 做消融,看哪一组真的值钱
      ↓
⑤ 写特征账本,标记每一列的"预测时刻可得性"
      ↓
⑥ 上线前过一遍防泄漏清单

★ 与我不同的地方(关键)

本书的章号顺序:05→06→07→...→22
我项目的顺序:  ①定判据 → ②划分 → ③特征 → ④消融 → ⑤账本 → ⑥清单

差别:我把"划分"(本书 18 章)放到了"特征"(本书 05–10 章)之前
    ↓
为什么?因为【划分方式决定了特征里能不能含跨实体信息】
       先定划分,才不会白做一批用不上的特征

★★ 这一题最重要的一句话

本书的章号是教学顺序,不是执行顺序。 在你的项目里,正确的顺序是:先定"预测时点",再定划分,最后做特征。

这个顺序错了,后面全部返工。

练习 3:找出本书"没讲"的东西

一本书的边界和它的内容一样重要。请列出至少三件这本书不会讲的事, 并说明"为什么它不讲"或"该去哪里学"。

参考答案

参考列表:

没讲的东西为什么不讲去哪学
按时间划分 vs 按实体划分的取舍上一本第 09–12 章讲过;本书只引用《监督学习实战》第 09–12 章
模型选型的四个维度属于"选模型",不属于"造特征"《监督学习实战》第 26 章
深度学习的特征提取(CNN/Transformer 自动学特征)本书专注表格数据的经典特征工程;那是另一个领域深度学习专门教材
流式/在线特征(特征实时计算)需要特征平台(Feature Store),是工程架构话题第 32 章会指出这个缺口
标签质量与标注本书假设"标签是对的";标签本身的问题另属一个专题需另外学习
因果推断("改变 X 能不能影响 Y")预测任务不问因果;上一本第 20 章提过"相关≠因果"因果推断专门教材
图像/文本/语音的特征工程那些是表示学习(representation learning)的领域各领域的专门资料

★ 为什么"列出没讲的东西"是一个好练习

只知道"这本书讲了什么" → 你会误以为它覆盖了全部
   ↓
知道"它没讲什么"       → 你才知道什么时候该去找别的资料
   ↓
【一本书的价值,一半来自它划清的边界】

★ 其中一个缺口特别重要:在线特征

本书全程假设:数据是【静态的一张表】
   ↓
但真实生产环境是【流式的】:
   特征要实时计算、历史要在线查得到、口径要一致(训练/服务一致)
   ↓
这就是"训练-服务偏差"(training-serving skew)的来源
   ↓
本书第 32 章会明确把这个缺口指出来,并说明它为什么是"下一本书"的主题

★ 一个自我检验

如果你读完这本书,能对任何一个新项目说出:

① 我的预测时点是什么?
② 我按什么划分?
③ 每一列在预测时点拿得到吗?
④ 哪一组特征真的值钱(消融怎么说)?
⑤ 我凭什么相信这个分数(结构检查是什么)?

那这本书的目的就达到了 —— 它教的就是这五个问题。

面向工程实践:把"路线"变成"团队规范" ​

① 这一章的地图不只给读者,也可以给团队

一个新同事加入你的建模项目:
   ↓
❌ "你先看看这些代码" → 他会花两周才明白为什么这样划分
✅ "先看这五章(03/15/18/20/22)" → 他三天就能明白项目的纪律
   ↓
【把书当入职材料,比写一份内部文档更省事,而且更完整】

② 一个可以直接用的"特征工程 checklist 起点"

markdown
## 我的特征工程流程

### 第一步:定预测时点(对应第 04、10 章)
- [ ] 我在什么时刻做预测?(as-of date)
- [ ] 那一刻,每条记录的状态是什么?

### 第二步:定划分方式(对应上一本第 09–12 章)
- [ ] 我按什么划分?(按实体 / 按时间)
- [ ] 划分后,训练集和测试集的实体有交集吗?(必须为 0)

### 第三步:造特征(对应第 05–10 章)
- [ ] 先排序、再分组、只含历史
- [ ] 每个特征的口径写清了吗?(分组 / 排序 / 含不含当前 / 窗口长度)

### 第四步:验证特征价值(对应第 14–16 章)
- [ ] 相关性有没有冗余?
- [ ] 消融实验做了吗?哪一组真的值钱?
- [ ] 特征账本写了吗?

### 第五步:守泄漏(对应第 17–22 章)
- [ ] 三种泄漏都排查了吗?
- [ ] 防泄漏清单过了一遍吗?

### 第六步:知道何时停手(对应第 23–27 章)
- [ ] 学习曲线走平了吗?(走平 → 改特征,不要调参)

★ 这份 checklist 的用法

不要把它当"打勾清单"(打完就完事)
   ↓
要把它当"卡点":每一步不通过就不进入下一步
   ↓
第 31 章会讲怎么把它真正变成一个【流程卡点】而不是一张纸

③ 关于"该读多少"的一个诚实建议

这本书 32 章,全读需要 2~4 周(按每天 1 小时算)
   ↓
但【读完不是目标】—— 目标是"下次做特征时不再犯那三类错"
   ↓
所以更有效的做法是:
   先读路线 2 的那 8 章
   → 立刻用在你手上的项目上
   → 遇到具体问题时再回来查对应的章
   ↓
【把书当工具,而不是当课程】

下一章:第 03 章 · 为什么横截面特征到顶了