大规模特征工程
概述
特征工程决定模型上限。大规模场景下,特征要统一管理、实时计算、在线离线一致、可回溯。Feature Store 就是为此而生。本文讲透特征存储、实时特征、一致性保障与特征回溯。
一、特征工程的挑战
1.1 规模化问题
痛点:
特征散落各处(各团队各写)
在线离线不一致(效果打折)
特征重复开发
无法回溯(历史特征丢失)
特征治理缺失(没人知道有哪些)| 问题 | 后果 |
|---|---|
| 散落 | 重复开发 |
| 不一致 | 线上效果差 |
| 无回溯 | 无法重训历史 |
| 无治理 | 特征不可控 |
1.2 Feature Store 的价值
价值:
统一存储(在线 + 离线)
统一管理(注册/版本/血缘)
保证一致性(同一套定义)
支持回溯(历史特征重放)
复用共享(团队间共享特征)二、Feature Store 架构
2.1 核心组件
Feature Store:
特征注册(定义/Schema/owner)
离线存储(数仓/湖存储)
在线存储(Redis/HBase 等低延迟)
特征服务(在线获取)
批量/流式计算(特征生成)| 组件 | 职责 |
|---|---|
| 特征注册中心 | 元数据管理 |
| 离线库 | 历史特征(训练) |
| 在线库 | 实时特征(推理) |
| 特征服务 | 统一读取 API |
| 特征计算 | 批/流生成特征 |
2.2 双存储设计
离线特征库(训练用):
数据量大、按时间分区
支持回溯查询
在线特征库(推理用):
低延迟读取
键值存储(Redis/Aerospike)
同一特征两份存储
靠"同一套生成逻辑"保持一致三、特征定义与管理
3.1 特征注册
注册内容:
特征名称/描述
特征类型
计算逻辑(SQL/代码)
来源表/依赖
更新频率
负责人
版本特征命名规范:
{域}_{实体}_{含义}
user_age、item_ctr_7d3.2 特征类型
| 类型 | 说明 | 示例 |
|---|---|---|
| 用户特征 | 用户侧 | 用户年龄 |
| 物品特征 | 物品侧 | 物品类目 |
| 上下文特征 | 场景 | 时间/渠道 |
| 行为特征 | 交互 | 近 7 天点击 |
| 交叉特征 | 组合 | 用户×物品类目 |
特征粒度:
用户级(user_id)
物品级(item_id)
用户×物品级(pair)
会话级(session_id)3.3 特征血缘
价值:
特征从哪来(来源表/计算逻辑)
特征被哪些模型用
变更影响分析
数据质量追溯四、实时特征计算
4.1 为什么要实时
场景:
推荐/风控需要秒级最新特征
用户刚点击 → 特征要更新
实时特征:
近期行为(分钟级窗口)
实时统计(频次/金额)
实时标签(当前状态)4.2 实时计算架构
架构:
行为事件 → Kafka → Flink
→ 实时特征计算(窗口聚合)
→ 写入在线特征库
特征服务:
请求 → 在线库取特征 → 返回模型
批流互补:
离线特征:日/小时更新
实时特征:秒级更新
两者合并使用4.3 实时特征实现
Flink 窗口示例:
近 5 分钟点击次数:
keyBy(user_id)
.window(TumblingEventTimeWindows.of(5min))
.aggregate(count)
结果写在线特征库
注意:
时间语义(事件时间/水位线)
窗口状态清理
特征新鲜度要求五、在线离线一致性
5.1 不一致的根源
原因:
计算逻辑不同(离线 SQL vs 在线代码)
时间口径不同(离线用 T-1,在线用实时)
数据源不同
特征缺失时的默认值不同
后果:
训练特征与线上特征分布不同
模型效果明显下降5.2 一致性保障方案
| 方案 | 说明 |
|---|---|
| 统一特征定义 | 同一份逻辑生成 |
| Feature Store 生成 | 批流共用一套计算 |
| 对账 | 定期对比离线/在线值 |
| 兜底值统一 | 缺失特征默认值一致 |
| 时序对齐 | 在线特征按"过去"计算 |
对账机制:
同一实体同时取:
离线库历史值 vs 在线库当前值
对比差异率
超过阈值 → 告警排查5.3 时间穿越问题
时间穿越(Data Leakage):
特征用了未来数据 → 训练虚高
例子:
预测今天,却用了"今天之后"的行为
防护:
特征生成用截止时间前的数据
窗口边界严格
离线验证用点(point-in-time)回溯六、特征回溯
6.1 什么是特征回溯
回溯(Backfill):
生成历史某个时间点的特征
用于重新训练历史模型
或验证新特征效果
需求场景:
新特征需要历史数据验证
模型重训需要历史特征
线上问题复盘6.2 回溯实现
实现方式:
离线特征库按时间分区存储
指定时间范围重新计算
(或直接读历史分区)
点回溯:
对每条训练样本
用样本时间点前的特征
(保证无未来信息)回溯流程:
选择实体集合 + 时间范围
按时间切分计算特征
写入训练数据集
训练/评估6.3 回溯的挑战
| 挑战 | 说明 |
|---|---|
| 数据量大 | 按时间分批 |
| 计算成本 | 复用离线任务 |
| 时间对齐 | 严格按时间点 |
| 特征版本 | 用当时的特征定义 |
七、Feature Store 实践
7.1 开源方案
| 方案 | 特点 |
|---|---|
| Feast | 开源 Feature Store |
| Tecton | 商业版(云端) |
| Hopsworks | 全栈平台 |
| 自建 | 基于 Redis+Hive 组装 |
自建要点:
离线:Hive/Iceberg 特征表
在线:Redis/HBase
服务:统一特征 API
注册:元数据表
计算:Spark(离线)+ Flink(实时)7.2 落地步骤
步骤:
1. 梳理核心特征(先做高价值)
2. 建立特征注册规范
3. 搭离线特征库
4. 搭在线特征库 + 服务
5. 批流特征对账
6. 接入训练与推理7.3 最佳实践
实践:
特征先离线后在线
高价值特征优先沉淀
统一默认值/兜底
定期对账与血缘维护
特征质量监控(缺失/漂移)八、常见问题
8.1 特征缺失怎么处理
策略:
在线:兜底值(均值/众数/0)
离线:与在线一致的兜底
关键:两边一致!
示例:
特征默认值 = 全局均值
在线缺失也用全局均值8.2 特征漂移检测
检测:
统计特征分布(均值/分位数)
对比训练期分布
漂移指标(PSI/KL 散度)
超阈值 → 告警/重训8.3 特征太多怎么办
处理:
特征选择(相关性/重要性)
在线成本评估(只留高价值)
特征下线(低使用率清理)九、小结
大规模特征工程的核心是一致性 + 可回溯 + 统一管理。Feature Store 把特征从"散落代码"变成"统一资产":离线库供训练、在线库供推理、同一套定义保证一致、按时间回溯支持迭代。做好对账与兜底统一,就解决了在线离线不一致这个最大坑。