2. 特征分层方法论:原始数据层、衍生特征层、聚合特征层、模型特征层的分层原则与设计
在风控特征工程中,特征分层是构建可维护、高性能特征体系的核心方法论。不同层次的特征在数据来源、计算复杂度、更新频率和业务含义上存在显著差异。合理的分层设计能够降低特征冗余、提升计算效率,并确保模型训练与线上推理的一致性。
2.1 四层特征体系总览
风控特征体系通常划分为四个层次:原始数据层(Raw Data Layer)、衍生特征层(Derived Feature Layer)、聚合特征层(Aggregated Feature Layer)和模型特征层(Model Feature Layer)。每一层都承担特定的数据加工职责,并向下游提供标准化的特征输出。
核心原则:每一层只做本层该做的事,不越级加工;层与层之间通过明确的接口(特征表/特征视图)解耦,便于独立迭代与回溯。
工程提示:在Spark批处理实践中,分层设计直接对应ETL作业的DAG划分。原始数据层通常对应贴源层(ODS),衍生层和聚合层对应中间层(DWD/DWS),模型特征层对应应用层(ADS)。
2.2 原始数据层(Raw Data Layer)
定义:直接来自业务系统、埋点日志、第三方数据源的最细粒度数据,不做任何业务逻辑加工,仅做格式清洗与字段映射。
| 属性 | 说明 |
|---|---|
| 数据粒度 | 单条事件/单笔交易/单次请求 |
| 更新频率 | 实时流或T+1批量 |
| 存储周期 | 全量保留(通常30-90天) |
| 典型字段 | 用户ID、设备ID、IP、时间戳、金额、渠道编码 |
| 加工操作 | 空值填充、类型转换、异常值截断(仅限明显错误) |
-- 原始数据层示例:用户登录日志表(Spark SQL)
CREATE TABLE dwd_user_login_raw (
user_id STRING,
device_id STRING,
login_ip STRING,
login_time TIMESTAMP,
channel STRING,
login_result STRING
)
USING parquet
PARTITIONED BY (dt STRING);
2.3 衍生特征层(Derived Feature Layer)
定义:基于单条原始记录,通过简单的数学变换、编码映射或规则计算得到的特征。不涉及跨记录聚合,仅对当前行数据进行加工。
- 数值变换:对数变换、标准化、分箱、百分位排名
- 类别编码:Label Encoding、One-Hot Encoding、Target Encoding
- 时间特征:小时、星期几、是否节假日、距离上次操作间隔
- 文本特征:设备型号提取、IP段提取、邮箱域名提取
避坑指南:衍生特征层严禁引入历史统计量(如“过去7天登录次数”),这类特征应归属聚合特征层。衍生层只做“行内计算”,不做“跨行聚合”。
-- 衍生特征层示例:从原始登录日志衍生特征
SELECT
user_id,
login_time,
HOUR(login_time) AS login_hour,
CASE WHEN DAYOFWEEK(login_time) IN (1,7) THEN 1 ELSE 0 END AS is_weekend,
SPLIT(login_ip, '\\.')[0] AS ip_segment_a,
DATEDIFF(login_time, LAG(login_time)
OVER (PARTITION BY user_id ORDER BY login_time)) AS interval_seconds
FROM dwd_user_login_raw
WHERE dt = '2025-01-15';
2.4 聚合特征层(Aggregated Feature Layer)
定义:在指定时间窗口内,对原始数据或衍生特征进行统计聚合,刻画用户/设备/IP的长期行为模式。这是风控特征体系中信息密度最高的层次。
| 聚合维度 | 常用窗口 | 聚合函数 | 典型特征示例 |
|---|---|---|---|
| 用户级 | 1h / 6h / 24h / 7d / 30d | COUNT, SUM, AVG, STDDEV, MAX, MIN | 过去24h登录次数、近7d交易总金额 |
| 设备级 | 1d / 7d / 30d | COUNT(DISTINCT), RATIO | 近30d关联用户数、设备活跃天数占比 |
| IP级 | 1h / 24h | COUNT, COLLECT_SET | 过去1h该IP下不同设备数、不同用户数 |
| 滑动窗口 | 最近N笔交易 | AVG, SUM, RATE | 最近10笔交易平均金额、失败率 |
-- 聚合特征层示例:用户级24h滑动窗口聚合
SELECT
user_id,
COUNT(*) AS login_cnt_24h,
COUNT(DISTINCT device_id) AS device_cnt_24h,
COUNT(DISTINCT login_ip) AS ip_cnt_24h,
SUM(CASE WHEN login_result = 'FAIL' THEN 1 ELSE 0 END) AS fail_cnt_24h,
ROUND(SUM(CASE WHEN login_result = 'FAIL' THEN 1 ELSE 0 END)
/ NULLIF(COUNT(*), 0), 4) AS fail_rate_24h
FROM dwd_user_login_raw
WHERE login_time >= DATE_SUB('2025-01-15', 1)
AND login_time < '2025-01-16'
GROUP BY user_id;
2.5 模型特征层(Model Feature Layer)
定义:面向具体风控模型(如XGBoost、逻辑回归、深度学习模型)的最终特征输入。该层负责特征选择、特征交叉、特征降维以及特征格式对齐。
- 特征选择:基于IV值、特征重要性、相关性矩阵筛选Top-K特征
- 特征交叉:笛卡尔积、多项式组合、FM二阶交叉
- 特征降维:PCA、AutoEncoder嵌入、Hash Trick
- 格式对齐:统一为LibSVM格式或TFRecord格式,填充缺失值
关键设计:模型特征层必须保证训练时与推理时的特征逻辑完全一致。建议将特征计算逻辑封装为UDF或特征函数,避免训练代码与线上代码分叉。
-- 模型特征层示例:最终特征宽表输出
SELECT
user_id,
-- 原始层特征
login_hour,
is_weekend,
-- 衍生层特征
ip_segment_a,
interval_seconds,
-- 聚合层特征
login_cnt_24h,
device_cnt_24h,
fail_rate_24h,
-- 模型层交叉特征
CONCAT(ip_segment_a, '_', CAST(login_hour AS STRING)) AS ip_hour_cross,
-- 目标变量
is_fraud
FROM (
-- 各层特征JOIN逻辑
...
) final_features
WHERE dt = '2025-01-15';
2.6 四层特征体系架构图
下图展示了风控特征从原始数据到模型输入的完整分层流转路径,以及各层之间的数据依赖关系。
2.7 分层设计对比总结
| 对比维度 | 原始数据层 | 衍生特征层 | 聚合特征层 | 模型特征层 |
|---|---|---|---|---|
| 数据来源 | 业务系统/日志 | 原始数据层 | 原始层+衍生层 | 前三层+外部特征 |
| 计算复杂度 | 低(仅清洗) | 中(行内计算) | 高(窗口聚合) | 中高(选择/交叉) |
| 存储量级 | 最大(全量明细) | 较大(每行多字段) | 中等(聚合后压缩) | 最小(精选特征) |
| 更新策略 | 增量追加 | 增量计算 | 增量+全量重算 | 按模型版本全量 |
| 回溯能力 | 天然支持 | 支持(需重跑) | 支持(需重算窗口) | 需保留特征版本 |
| 业务语义 | 原始事件 | 单点特征 | 行为模式 | 模型视角 |
2.8 分层设计在Spark中的落地要点
- 作业拆分:每层对应独立的Spark Job,通过中间表(Parquet格式)解耦,便于失败重跑和增量更新。
- 分区策略:原始层和衍生层按事件时间(dt+hh)分区;聚合层按聚合窗口结束时间分区;模型层按模型版本+日期分区。
- 缓存策略:聚合层中间结果建议使用Spark Cache或持久化到内存表,避免重复计算高频特征。
- 血缘管理:每层特征表记录上游表名、加工SQL版本、运行时间戳,便于问题排查和特征回溯。
实战建议:在初期搭建特征体系时,优先保证原始数据层的完整性和准确性。原始层一旦出现数据质量问题,所有上层特征都会受到污染。建议对原始层设置严格的数据质量监控(空值率、枚举值分布、时间戳连续性)。