4. 数据管道构建
数据管道,说白了就是整个 ML 流水线的「水源」和「血管」。我见过太多团队把精力全砸在模型调参上,结果数据一换,模型直接崩盘。这一章咱们就聊聊怎么把数据管道搭得又稳又可控——特征工程流水线、数据验证、数据版本控制,三件套一次讲透。
4.1 特征工程流水线——别让手工操作拖垮你
特征工程是模型效果的天花板。但很多人还在用 Notebook 手动跑,今天改个参数,明天换个逻辑,最后谁也说不清线上用的是哪一套。我个人习惯是把特征工程写成可编排的流水线,每个步骤独立、可测试、可复用。
举个例子,我用 scikit-learn 的 Pipeline 配合 ColumnTransformer,把数值型、类别型、文本型特征分开处理。你想想看,这样改一个特征逻辑,只需要改对应的 transformer,完全不影响其他环节。
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
numeric_features = ['age', 'income', 'click_count']
categorical_features = ['city', 'device_type']
preprocessor = ColumnTransformer(
transformers=[
('num', StandardScaler(), numeric_features),
('cat', OneHotEncoder(handle_unknown='ignore'), categorical_features)
]
)
pipeline = Pipeline(steps=[
('preprocessor', preprocessor),
('classifier', LogisticRegression())
])
我在项目中遇到过最头疼的事:特征逻辑散落在各个 Notebook 里,线上推理时少了一个特征变换,模型直接报错。后来我把所有特征算子统一注册到 Feature Store 里,训练和推理用同一份配置,再也没出过这种低级问题。
4.2 数据验证——用 Great Expectations 给数据上「安检」
数据质量是模型的生命线。脏数据进,垃圾模型出。Great Expectations(简称 GX)是我目前用过最顺手的工具,它让你用「断言」的方式定义数据期望,然后自动验证。
说白了,就是给数据写测试用例。比如「年龄字段不能为负」「用户ID必须唯一」「转化率在0到1之间」。GX 会生成一个 HTML 报告,哪里不合格一目了然。
import great_expectations as ge
# 加载数据集
df = ge.read_csv("training_data.csv")
# 定义期望
df.expect_column_values_to_be_between("age", 0, 120)
df.expect_column_values_to_not_be_null("user_id")
df.expect_column_distinct_values_to_be_in_set("device_type", ["ios", "android", "web"])
# 执行验证
results = df.validate()
print(results["statistics"])
我习惯把 GX 验证放在特征工程流水线的入口和出口。入口验证原始数据,出口验证加工后的特征。一旦某个批次的数据质量不达标,流水线直接中断,并发送告警。你想想看,这比模型上线后才发现数据有问题,省了多少事。
4.3 数据版本控制——用 DVC 让数据像代码一样可追溯
代码有 Git,数据呢?我早期做项目时,数据集存在网盘里,文件名带「_v2」「_final」「_final_v3」,简直灾难。后来用 DVC(Data Version Control),才真正把数据纳入版本管理。
DVC 的核心思路:数据存在远程存储(S3、GCS、本地磁盘),Git 里只存一个元数据文件(.dvc 文件)。每次数据变更,DVC 会生成新的哈希值,Git 记录这个哈希。这样你就能通过 Git 的 commit 来回滚数据版本。
# 初始化 DVC
dvc init
# 添加数据目录
dvc add data/raw/
# 关联远程存储
dvc remote add -d myremote s3://my-bucket/dvc-store
# 推送数据
dvc push
# 切换版本时,先 git checkout 到对应 commit,然后
dvc pull
我记得有一次,业务方说「上周的模型效果更好,但数据好像换过」。我直接 git log 找到上周的 commit,dvc checkout 把数据恢复到当时的状态,重新跑了一遍训练,结果完全一致。那一刻,数据版本控制的价值体现得淋漓尽致。
4.4 三者如何协同?
特征工程流水线、数据验证、数据版本控制,不是三个孤立的工具。我通常这样组织:
| 阶段 | 工具/方法 | 产出 |
|---|---|---|
| 原始数据入库 | DVC add + push | 数据版本哈希 |
| 数据验证(入口) | Great Expectations | 质量报告 + 通过/失败 |
| 特征工程 | Pipeline + ColumnTransformer | 特征数据集 + 特征元数据 |
| 数据验证(出口) | Great Expectations | 特征质量报告 |
| 特征数据版本化 | DVC add + push | 特征数据版本哈希 |
整个流程可以封装成一个 Makefile 或者 CI 任务。每次数据更新,自动触发:拉取原始数据 → 验证 → 特征工程 → 验证 → 版本化。这样,任何一次模型训练都能追溯到具体的数据版本和特征逻辑。
feature_config.yaml,记录当前使用的特征列表和变换参数。这样即使过了半年,你也能知道「当时用了哪些特征,怎么处理的」。
嗯,这一章的内容就到这里。数据管道是 ML 流水线的地基,地基不稳,上面盖的模型再漂亮也白搭。希望你能把特征工程、数据验证、版本控制这三样东西真正用起来,别让数据成为你项目里的黑盒。