2. 特征分层理论基础

在风控规则引擎中,特征(Feature)是规则判断的最小原子。随着业务规模增长,特征数量往往从几百膨胀到数万。如果不进行分层管理,特征库将陷入“重复定义、口径混乱、性能低下”的泥潭。本章从必要性出发,系统阐述特征分层的三大原则与工程收益。

2.1 特征分层的必要性

未分层的特征库通常表现为“平铺式”结构——所有特征直接依赖原始数据,规则编写者各自为政。这种模式在初期尚可维持,但一旦超过 500 个特征,就会出现以下问题:

问题 具体表现 后果
口径不一致 多个规则分别计算“近30天交易总额”,有的用自然月,有的用滚动窗口 规则冲突、决策结果不可复现
重复计算 同一中间结果(如“近7天登录次数”)被不同规则重复执行 CPU/内存浪费,响应延迟升高
维护成本高 修改底层数据源时,需要逐一排查所有依赖特征 上线周期长,易遗漏
可测试性差 特征与原始数据强耦合,无法单独 mock 测试 回归测试覆盖不足
核心结论:特征分层不是架构上的“过度设计”,而是应对特征数量指数级增长的必然选择。分层后,80% 的规则只需在衍生层或聚合层组合特征,无需直接接触原始数据。

2.2 分层原则:原子层 → 衍生层 → 聚合层

特征分层遵循“自底向上、逐层抽象”的原则,共分为三个层次。每一层都有明确的定义边界和复用约束。

2.2.1 原子层(Atomic Layer)

定义:直接来源于原始数据源(如数据库字段、API 响应、埋点事件),不做任何跨实体或跨时间窗口的加工。

  • 示例:user.gender、order.amount、device.os_type、ip.country_code
  • 约束:一个原子特征只对应一个数据源字段;禁止在原子层做聚合、转换或衍生计算。
  • 命名规范:{数据源}.{字段名},如 db_user.gender。

2.2.2 衍生层(Derived Layer)

定义:基于一个或多个原子特征,通过函数、表达式或简单规则计算得到。衍生层不涉及跨实体聚合,只做单实体内的变换。

  • 示例:age_group = floor((today - birth_date) / 365)、email_domain = split(email, '@')[1]
  • 约束:衍生层可以引用原子层或其他衍生层特征,但禁止引用聚合层特征(避免循环依赖)。
  • 命名规范:derived.{业务含义},如 derived.age_group。

2.2.3 聚合层(Aggregate Layer)

定义:跨实体、跨时间窗口的统计或汇总结果。聚合层是规则引擎中最常用的特征层,也是性能优化的重点。

  • 示例:agg.last_30d_transaction_count、agg.avg_order_amount_7d、agg.max_login_interval_24h
  • 约束:聚合层只能引用原子层或衍生层特征,且必须明确指定时间窗口和聚合函数(SUM、COUNT、AVG、MAX、MIN 等)。
  • 命名规范:agg.{窗口}_{聚合函数}_{业务实体},如 agg.30d_count_transaction。
分层依赖规则:上层可以引用下层,下层不能引用上层。即:聚合层 → 衍生层 → 原子层。这条规则保证了特征依赖图是一个有向无环图(DAG),避免循环计算。
特征分层架构图 特征分层架构图 聚合层(Aggregate Layer) 跨实体、跨时间窗口统计 agg.30d_count_transaction | agg.avg_amount_7d 衍生层(Derived Layer) 单实体变换、函数计算 derived.age_group | derived.email_domain 原子层(Atomic Layer) 原始数据字段,无加工 user.gender | order.amount | device.os_type 依赖方向:聚合层 → 衍生层 → 原子层(上层可引用下层,反之禁止)

2.3 分层带来的可维护性与性能优势

特征分层不是理论空谈,它在工程落地中带来了实实在在的收益。以下从可维护性和性能两个维度展开。

2.3.1 可维护性优势

维度 未分层 分层后
特征复用 同一逻辑被复制到多个规则中 衍生层/聚合层特征被统一引用,修改一处即可
口径管理 每个规则自行定义计算逻辑 口径在特征定义层固化,规则只做组合
变更影响 修改底层字段需排查所有规则 只需修改对应特征定义,依赖自动更新
测试覆盖 特征与规则耦合,测试用例爆炸 每层可独立单元测试,上层 mock 下层
新人上手 需要理解全部原始数据 只需熟悉聚合层和衍生层特征目录

2.3.2 性能优势

分层架构天然支持“计算复用”和“缓存优化”,具体体现在:

  • 共享计算:同一个衍生特征(如 derived.age_group)被多个聚合特征引用时,只计算一次。
  • 预聚合缓存:聚合层特征通常使用滑动窗口或预计算表,避免每次规则评估都扫描全量数据。
  • 并行执行:特征依赖图(DAG)允许引擎并行计算无依赖的节点,减少总耗时。
  • 冷热分离:高频使用的聚合特征可以常驻内存,低频原子特征按需加载。
性能陷阱提醒:分层虽然带来复用,但过度分层(如衍生层再衍生多层)会导致依赖链路过长,增加计算延迟。建议衍生层不超过 2 级,聚合层直接引用原子层或 1 级衍生特征。
分层计算复用示意图 分层计算复用示意图 order.amount order.create_time user.id derived.order_hour derived.is_weekend agg.7d_avg_amount agg.7d_count_order 衍生层只计算一次 被两个聚合特征复用

2.4 分层落地建议

在实际项目中,特征分层需要配合元数据管理和版本控制才能发挥最大价值。以下是几条落地建议:

  1. 建立特征目录:使用统一的元数据平台登记每个特征的分层、口径、数据源、负责人,支持检索和依赖分析。
  2. 分层代码隔离:在代码仓库中,原子层、衍生层、聚合层的特征定义放在不同目录或模块中,禁止跨层引用。
  3. 自动化依赖检查:在 CI/CD 流程中加入依赖图校验,确保没有循环依赖或跨层违规引用。
  4. 性能基线:对聚合层特征设置 P99 延迟基线,超过阈值时触发预计算或缓存优化。
最佳实践:建议将 60% 的特征设计为聚合层,30% 为衍生层,10% 为原子层。这个比例在大多数风控场景中能平衡复用率和计算开销。