4. 特征工程基础:特征分类(静态/动态)与特征存储选型
特征工程是商户风险评分通道的核心环节。原始数据(如商户注册信息、交易流水、外部黑名单)必须经过提取、转换与选择,才能成为模型可用的特征。本章聚焦于特征的两大分类方式以及存储选型策略,为后续特征加工与上线提供理论基础。
4.1 特征分类:静态特征 vs 动态特征
根据特征随时间变化的规律,可将商户风险特征分为静态特征与动态特征两类。两者的核心差异在于更新频率与时效性要求。
| 对比维度 | 静态特征 | 动态特征 |
|---|---|---|
| 定义 | 商户注册时即确定、后续极少变化的信息 | 随商户经营行为持续变化、需要定期更新的信息 |
| 典型字段 | 注册时间、营业执照号、法人身份证、注册地址、行业类别 | 近7天交易金额、近30天退款率、实时在途订单数、设备指纹活跃度 |
| 更新策略 | 一次性写入,仅当商户信息变更时触发更新 | 按固定时间窗口(T+1、小时级、实时)批量或流式更新 |
| 存储特点 | 数据量稳定,适合关系型数据库或宽表 | 数据量大、写入频繁,适合高性能缓存或时序存储 |
| 风险含义 | 刻画商户的“身份”与“资质”,用于准入与分层 | 刻画商户的“行为”与“趋势”,用于实时监控与预警 |
实践建议:在商户风险评分通道中,静态特征通常用于构建“基础画像层”,动态特征则用于构建“行为评分层”。两者结合才能覆盖从准入到交易监控的全链路风险识别。
4.2 特征存储选型:Redis vs Feature Store
特征存储的选型直接影响特征读取延迟、数据一致性与运维成本。当前业界主流方案为Redis(高性能缓存)与Feature Store(专用特征平台)。
4.2.1 Redis 方案
Redis 以其极低延迟(毫秒级)和丰富的数据结构(Hash、Sorted Set、Bitmap)成为实时特征存储的首选。适用于高频读取、单特征键值对查询的场景。
- 优势:读写性能极高,部署简单,社区生态成熟。
- 劣势:不支持复杂查询(如范围扫描、多维度聚合),数据持久化能力弱,缺乏特征血缘与版本管理。
- 典型用法:存储商户实时计数器(如“近5分钟交易笔数”)、在线模型所需的特征快照。
4.2.2 Feature Store 方案
Feature Store(如 Feast、Tecton、Dell AFS)是专为机器学习设计的特征管理平台,提供特征注册、在线/离线存储、时间点一致性(Point-in-Time Correctness)等能力。
- 优势:统一特征管理,支持离线批处理与在线实时双链路,自动处理特征回溯与时间对齐。
- 劣势:系统复杂度高,引入额外运维成本,查询延迟通常高于 Redis(毫秒级 vs 微秒级)。
- 典型用法:管理大规模商户特征(数千维),支撑模型训练时的特征工程与上线后的在线推理。
选型决策矩阵:
| 场景 | 推荐方案 | 原因 |
|---|---|---|
| 实时风控(延迟 < 10ms) | Redis | 极低延迟,简单键值查询即可满足 |
| 大规模特征管理(维度 > 500) | Feature Store | 统一元数据、血缘与版本控制 |
| 离线训练 + 在线推理双链路 | Feature Store | 自动保证训练/推理特征一致性 |
| 小团队快速原型 | Redis + 手动脚本 | 降低系统复杂度,快速验证 |
4.3 特征存储架构示意
下图展示了一个典型的商户风险评分通道中,静态特征与动态特征分别通过不同存储层服务于模型训练与在线推理的架构。
4.4 特征存储选型对比总结
| 选型维度 | Redis | Feature Store |
|---|---|---|
| 读写延迟 | < 1ms(纯内存) | 1-10ms(视后端存储) |
| 特征管理 | 无内置管理,需自行维护 | 特征注册、血缘、版本、监控 |
| 时间一致性 | 不支持 | 原生支持 Point-in-Time |
| 离线/在线一致性 | 需手动对齐 | 自动保证 |
| 运维复杂度 | 低 | 高(需部署多个组件) |
| 适用团队规模 | 小团队 / 快速迭代 | 中大型团队 / 规范化MLOps |
常见误区:不要将所有特征都放入 Redis。静态特征(如注册时间)几乎不会变化,放入 Redis 浪费内存且无性能收益;应将其存储在离线宽表中,仅在推理时通过 Key-Value 查询加载。动态特征才适合放入 Redis 或 Feature Store 的在线存储。
4.5 代码示例:Redis 特征写入与读取
以下示例展示如何使用 Python 将商户动态特征写入 Redis,并在推理时快速读取。
import redis
import json
# 连接 Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# 写入商户动态特征(使用 Hash 结构)
merchant_id = "M10086"
features = {
"trans_amt_7d": 125000.00,
"refund_rate_30d": 0.023,
"order_cnt_1h": 45,
"device_cnt_7d": 3
}
r.hset(f"merchant:features:{merchant_id}", mapping=features)
# 读取特征(用于模型推理)
raw = r.hgetall(f"merchant:features:{merchant_id}")
parsed = {k.decode(): float(v) for k, v in raw.items()}
print(parsed)
# 输出: {'trans_amt_7d': 125000.0, 'refund_rate_30d': 0.023, 'order_cnt_1h': 45.0, 'device_cnt_7d': 3.0}
对于 Feature Store(以 Feast 为例),特征注册与读取通常通过 YAML 配置和 SDK 完成,此处不再展开。