2. 实时特征基础
在推荐、风控、搜索等在线系统中,模型效果的上限往往不由算法结构决定,而由特征质量决定。实时特征则是把“用户刚刚发生了什么”及时翻译成模型可用的数值信号。理解特征、特征工程、离线特征与实时特征的边界,是构建低延迟服务的第一块基石。
一、什么是特征:从原始行为到模型输入
特征是描述样本某一维度的可计算属性。以电商推荐为例,原始日志里是“用户A在10:03:12点击了商品B”,而模型需要的是“用户A近5分钟点击次数=7”“该商品近1小时CTR=0.032”这类结构化数值。特征工程就是完成从原始数据到模型输入的映射过程,通常包含四个环节:
- 特征定义:明确业务含义、统计口径、时间窗口与实体粒度(用户/商品/上下文)。
- 特征抽取:从日志、数据库、消息流中计算原始指标。
- 特征变换:归一化、分桶、Embedding、交叉组合等。
- 特征存储与服务:写入特征库,供训练与在线推理读取。
其中“时间窗口”和“实体粒度”是实时特征最容易出错的两个维度。窗口定义不清,会导致线上线下口径漂移;粒度不一致,则会出现特征错位。
二、离线特征与实时特征的本质区别
离线特征基于历史全量数据批量计算,通常以天或小时为周期写入数仓或特征平台,优点是口径稳定、可回溯、算力充足;缺点是时效性差,无法反映用户当前意图。实时特征则在事件发生后秒级或毫秒级完成计算并写入在线存储,优点是捕捉即时兴趣与突发风险,缺点是链路复杂、状态难管理、成本更高。
| 对比维度 | 离线特征 | 实时特征 |
|---|---|---|
| 计算周期 | 天/小时级批处理 | 秒级/毫秒级流式计算 |
| 数据范围 | 历史全量 | 滑动窗口/会话内增量 |
| 存储介质 | Hive/数仓/对象存储 | Redis/HBase/本地内存 |
| 时效性 | 低 | 高 |
| 一致性要求 | 最终一致即可 | 需严格保证线上线下一致 |
| 典型用途 | 用户长期画像、商品统计 | 实时兴趣、风控规则、热搜 |
三、实时特征在推荐、风控、搜索中的作用
在推荐系统中,实时特征主要捕捉用户当前会话兴趣。例如“最近3次点击的类目序列”“过去10分钟加购商品数”,能让模型在用户兴趣漂移时快速调整排序。在风控系统中,实时特征用于识别突发异常,如“同一设备1分钟内登录账号数”“近5分钟下单金额突增”,这类信号离线T+1根本无法拦截。在搜索系统中,实时特征体现为“查询词近1小时点击率”“当前热搜词热度”,用于动态调整召回与排序权重。
下面是一段典型的实时特征计算伪代码,展示滑动窗口计数逻辑:
# 用户近5分钟点击次数(滑动窗口)
def update_click_count(user_id, event_time):
key = f"click_cnt:{user_id}"
# 移除窗口外事件
redis.zremrangebyscore(key, 0, event_time - 300)
# 写入当前事件
redis.zadd(key, {event_time: event_time})
# 返回窗口内数量
return redis.zcard(key)
该逻辑在Flink或Spark Streaming中通常以KeyedProcessFunction配合状态后端实现,要求端到端延迟控制在百毫秒级。
四、常见误区与复盘要点
误区二:所有特征都实时化,造成Redis热点与流计算资源浪费。
误区三:只关注计算延迟,忽略特征写入与读取之间的“时间差”,产生特征穿越。
复盘时应重点检查三件事:口径一致性(离线回刷与实时计算是否同源同逻辑)、时间语义(事件时间还是处理时间)、降级策略(实时链路故障时能否回退到离线特征)。只有把这三项纳入监控,实时特征才能真正稳定服务于在线决策。