2. 风控特征基础

在风控系统中,模型和规则只是“决策大脑”,真正决定判断质量的是喂给大脑的“信息原料”——特征。理解特征的定义、分类、生命周期以及承载它们的平台架构,是后续排查特征缺失异常、治理新鲜度问题的前提。本节从工程视角把“特征”讲清楚,为实战打好地基。

一、核心原理:什么是风控特征

风控特征(Feature)是指在风控决策时刻,能够被系统读取、用于刻画当前事件风险的一组结构化数值或标签。它通常由原始事件、历史行为、外部数据经过加工计算得到,具备三个关键属性:

  • 时效性:特征值必须对应某个明确的时间窗口,如“近1小时登录次数”“近30天逾期笔数”。
  • 可计算性:特征必须能由确定的加工逻辑产出,可复现、可回溯、可监控。
  • 决策相关性:特征需与风险目标有统计或业务上的关联,否则只是噪声。

一个常被忽视的点是:特征不是“数据库字段”,而是“在决策时刻可用的、带时间语义的派生量”。例如用户表里的“注册时间”是原始字段,而“注册距今天数”才是特征;“近7天同设备登录账号数”则是跨事件聚合特征。

特征的本质是“时间窗口 + 实体 + 聚合/变换逻辑”的三元组。缺失异常和新鲜度问题,几乎都能回溯到这三要素中的某一环。

二、特征的分类:从多个维度切分

分类不是为了贴标签,而是为了在设计监控、存储和回填策略时能对症下药。常见切分维度如下:

分类维度 类型 典型示例 工程关注点
数据来源 实时事件 / 离线数仓 / 外部三方 本次请求IP、近90天消费、征信分 依赖稳定性、回填能力
时间语义 实时特征 / 近线特征 / 离线特征 近5分钟频次、近1天设备数、近1年标签 新鲜度、窗口对齐
计算方式 统计聚合 / 序列 / 图关系 / 模型分 计数、滑动窗口、团伙关系、风险评分 计算成本、一致性
取值形态 数值 / 类别 / 布尔 / 向量 金额、渠道编码、是否黑名单、Embedding 缺失填充、编码方式

其中“时间语义”维度与后续新鲜度治理关系最密切。实时特征要求秒级更新,近线特征通常分钟到小时级,离线特征按天或按周更新。不同时间语义的特征混用,是新鲜度异常的常见根源。

三、特征生命周期:从定义到退役

特征不是一次性产物,它有一条完整的生命周期。理解这条链路,才能在异常发生时快速定位是哪个环节出了问题。

  1. 需求与定义:业务提出风险假设,数据团队将其转化为可计算的特征口径,明确实体、窗口、聚合函数。
  2. 开发与注册:在特征平台注册元数据,包括名称、类型、负责人、更新频率、依赖上游。
  3. 生产与写入:由批处理或流计算任务产出,写入在线存储(如Redis、HBase)供实时读取。
  4. 在线服务:决策引擎在请求时刻按实体Key拉取特征,组装成特征向量。
  5. 监控与回填:持续监控覆盖率、延迟、分布漂移;异常时触发回填或降级。
  6. 退役:当特征失效或冗余时,下线并清理存储与依赖,避免“僵尸特征”污染。
生命周期中最容易被忽略的是“退役”环节。大量僵尸特征长期不更新,却仍被模型引用,会直接表现为特征缺失或取值陈旧,是新鲜度治理的隐性债务。

四、常见特征平台架构

工业界特征平台通常采用“离线 + 在线”双链路架构,核心目标是保证离线与在线特征的一致性(即训练-服务一致性)。典型分层如下:

  • 数据源层:埋点日志、业务库、三方接口。
  • 计算层:离线用Spark/Hive做批聚合,实时用Flink/Kafka做流聚合。
  • 存储层:离线特征存Hive/ClickHouse,在线特征存Redis/HBase,向量特征存专用向量库。
  • 服务层:特征网关统一接收请求,按Key并行拉取多路特征,做超时与降级控制。
  • 治理层:元数据中心、血缘追踪、质量监控、回填调度。

下面是一段特征网关拉取在线特征的伪代码,展示了超时与缺失兜底的基本处理逻辑:

def fetch_features(entity_key, feature_names, timeout_ms=50):
    result = {}
    for name in feature_names:
        try:
            value = redis_client.get(f"{name}:{entity_key}", timeout=timeout_ms)
            if value is None:
                result[name] = DEFAULT_VALUE   # 缺失兜底
                metrics.incr(f"feature_missing.{name}")
            else:
                result[name] = value
        except TimeoutError:
            result[name] = DEFAULT_VALUE
            metrics.incr(f"feature_timeout.{name}")
    return result

这段代码里,DEFAULT_VALUE 和监控埋点是关键。缺失兜底保证决策不中断,监控埋点则为后续缺失异常分析提供数据。若没有这两者,特征缺失会直接表现为线上决策报错或静默错误。

五、案例与误区复盘

某信贷风控团队曾遇到一次典型的特征缺失事故:模型A依赖“近7天申请次数”这一实时特征,某日凌晨Flink任务因上游Kafka分区倾斜导致消费延迟,在线Redis中该特征大面积未更新。由于网关没有配置缺失监控,决策引擎读取到的是旧值,导致一批高风险申请被误判为低风险。

复盘后发现三个问题:

  • 误区一:认为“特征存在即有效”,忽略了新鲜度监控。旧值不等于缺失,但风险等价。
  • 误区二:缺失兜底策略过于简单,统一填0,掩盖了异常信号。
  • 误区三:离线与在线特征口径不一致,回填时无法对齐,延长了恢复时间。
特征缺失与新鲜度问题往往不是孤立的技术故障,而是架构、监控、口径三方面共同作用的结果。治理时必须同时关注“有没有值”“值新不新”“值对不对”三个层次。