3、风控特征工程:特征分类、特征构建、特征存储、特征监控

特征工程,说白了就是风控系统的“食材准备间”。

模型再牛,算法再先进,喂进去的特征是垃圾,出来的结果就是垃圾。我见过太多团队,花三个月调模型参数,结果一查,特征里居然有空值没处理干净。嗯,这种事,一次就够了。

3.1 特征分类:先分清楚再动手

我个人习惯把特征分成三大类。这样设计存储和计算的时候,思路会清晰很多。

特征类型 定义 典型例子 更新频率
静态特征 基本不变的用户属性 性别、注册时间、身份证归属地 一次性或低频
动态特征 随时间变化的行为数据 近7天登录次数、近30天交易金额 实时或准实时
衍生特征 基于原始数据加工计算 设备指纹、关系网络密度、多头借贷数 按需计算

核心原则:静态特征用宽表存,动态特征用时序存,衍生特征用特征服务实时算。千万别混在一起,否则后面维护成本会让你崩溃。

3.2 特征构建:从原始数据到高价值特征

特征构建是风控工程师的核心手艺。我刚开始做的时候,也踩过不少坑。

3.2.1 时间窗口特征

这是风控里最常用的。比如“过去7天申请次数”。

为什么用7天?不是5天也不是10天?

我在项目中遇到过,某现金贷产品,用户从注册到申请平均间隔是6.8天。所以7天窗口刚好能覆盖一个完整的行为周期。你想想看,如果窗口设成3天,很多正常用户的行为就抓不到,模型会误判。

-- 示例:计算近7天申请次数
SELECT user_id,
       COUNT(*) AS apply_cnt_7d
FROM event_log
WHERE event_type = 'apply'
  AND event_time >= NOW() - INTERVAL 7 DAY
GROUP BY user_id;

避坑指南:我曾经犯过一个低级错误——直接用当前时间计算窗口特征。结果线上和离线数据对不上。后来我改成用“事件发生时间”作为基准,才彻底解决。

3.2.2 比率与聚合特征

单一维度的特征往往不够。比如“申请次数”本身,不如“申请通过率”有区分度。

  • 比率特征:通过率、逾期率、设备关联账户数
  • 聚合统计:最大值、最小值、均值、标准差、分位数
  • 序列特征:行为间隔、行为顺序、行为模式

举个例子。一个用户一天内申请了5次,每次间隔不到10分钟。这明显是机器行为。如果只看“申请次数”,可能只是觉得有点多。但加上“申请间隔标准差”,模型就能识别出这种异常模式。

3.2.3 图特征

这是高阶玩法。用户之间通过设备、IP、手机号等形成关系网络。

# 示例:计算用户的二度关联风险节点数
def get_second_degree_risk_nodes(user_id, graph, depth=2):
    visited = set()
    queue = [(user_id, 0)]
    risk_count = 0
    while queue:
        node, d = queue.pop(0)
        if d > depth:
            break
        if node in visited:
            continue
        visited.add(node)
        if graph.nodes[node].get('is_risk', False):
            risk_count += 1
        for neighbor in graph.neighbors(node):
            if neighbor not in visited:
                queue.append((neighbor, d+1))
    return risk_count

我记得有一次,一个团伙用200多个手机号申请贷款,每个号都换了设备。但图特征一跑,发现这些号都共用同一个WiFi MAC地址。嗯,图特征就是这么好用。

3.3 特征存储:选对工具,事半功倍

特征存储不是随便找个数据库就行的。不同特征有不同的存储需求。

存储类型 适用特征 推荐技术 关键指标
在线特征存储 实时决策需要的特征 Redis、HBase P99延迟 < 10ms
离线特征存储 模型训练、批量分析 Hive、ClickHouse 高吞吐、低成本
特征元数据存储 特征定义、版本、血缘 MySQL、Neo4j 强一致性、可追溯

注意:在线特征存储一定要做缓存降级。我曾经遇到Redis集群宕机,结果所有风控请求都超时,业务直接停摆。后来加了本地缓存+降级策略,才稳住。

3.4 特征监控:别等出事了再后悔

特征监控是风控系统的“体检中心”。没有监控,你根本不知道特征什么时候坏了。

3.4.1 监控什么

  • 特征覆盖率:是不是有大量用户特征缺失?
  • 特征分布漂移:均值、方差有没有突然变化?
  • 特征时效性:特征是不是过期了?
  • 特征一致性:在线和离线算出来的值是否一致?

3.4.2 怎么监控

我个人习惯用PSI(群体稳定性指标)来监控特征分布漂移。

# 示例:计算PSI
def calculate_psi(expected, actual, bins=10):
    # 将数据分箱
    expected_hist, _ = np.histogram(expected, bins=bins, range=(0,1))
    actual_hist, _ = np.histogram(actual, bins=bins, range=(0,1))
    
    # 转换为比例
    expected_pct = expected_hist / len(expected)
    actual_pct = actual_hist / len(actual)
    
    # 计算PSI
    psi = 0
    for e, a in zip(expected_pct, actual_pct):
        if e == 0:
            e = 0.0001
        if a == 0:
            a = 0.0001
        psi += (a - e) * np.log(a / e)
    
    return psi

PSI超过0.1就要报警。超过0.25,基本可以确定特征出了问题。

我的经验:特征监控的报警阈值不要设太死。我刚开始设了0.05,结果每天几百条报警,全是误报。后来调到0.1,再配合人工复核,才真正有效。

3.5 本章知识体系

下面这张图,是我自己总结的特征工程全流程。你照着这个框架去设计,基本不会漏掉关键环节。

风控特征工程全流程 数据源层 用户基本信息 | 行为日志 | 设备指纹 | 外部数据 特征构建层 时间窗口特征 比率与聚合特征 图特征 特征存储层 在线存储 (Redis/HBase) 离线存储 (Hive/ClickHouse) 元数据存储 (MySQL/Neo4j) 特征监控层 覆盖率 | 分布漂移(PSI) | 时效性 | 一致性 反馈优化

特征工程不是一锤子买卖。它是一个持续迭代的过程。特征构建完,上线跑一段时间,监控发现分布漂移了,回头重新构建,再存储,再监控。这个闭环,才是风控特征工程的核心。

最后说一句:特征工程做得好不好,直接决定风控模型的天花板。我见过太多团队,模型调参调了半年,效果提升不到1%。结果花两周时间重构了几个关键特征,AUC直接涨了5个点。你想想看,哪个投入产出比更高?


公众号:蓝海资料掘金营,微信deep3321