3. 特征工程概述:特征定义、特征类型与业务应用

特征工程是金融图谱建模的核心环节,其质量直接决定模型性能的上限。在风控与营销场景中,特征不仅是原始数据的数学映射,更是业务逻辑的量化表达。本节从定义、类型划分到业务落地,系统梳理特征工程的基础框架。

3.1 特征定义:从数据到模型的语言

特征(Feature)是用于描述观测对象某一可测量属性的数值化或类别化表示。在金融图谱中,特征通常来源于用户属性、交易行为、关系网络等异构数据源。一个有效的特征需满足:区分度(正负样本分布差异显著)、稳定性(跨时间窗口分布波动小)、可解释性(业务含义清晰)。

核心原则:特征不是数据的简单搬运,而是通过聚合、变换、组合等方式提炼出的信息浓缩体。例如,原始交易金额是数据,而“近30天交易金额的变异系数”才是特征。

3.2 特征类型:数值、类别与时序

根据数据形态与建模方式,金融特征可划分为三大基础类型。下表对比了各类特征的核心属性与典型处理方式:

特征类型 定义 典型示例 常用处理方式 风控场景 营销场景
数值特征 连续或离散的定量度量 收入、负债率、交易金额 标准化、分箱、对数变换 信用评分卡阈值 客群价值分层
类别特征 有限离散值的定性标签 职业、地区、设备类型 独热编码、目标编码、频次编码 欺诈团伙识别 偏好画像细分
时序特征 带时间维度的序列数据 近7天交易频次、还款间隔 滑窗统计、差分、趋势分解 逾期预警模型 响应时效预测

三类特征并非孤立存在,实际业务中常通过交叉组合生成高阶特征。例如,将“近30天交易金额(数值)”与“交易时段(类别)”组合,可得到“夜间大额交易次数”这一强区分度特征。

3.3 特征在风控与营销中的应用

特征工程在不同业务场景中的侧重点差异显著。以下从风控与营销两个维度展开:

3.3.1 风控场景:以稳定性和区分度为核心

  • 反欺诈识别:利用图谱特征(如二度关联节点数、设备共用率)捕捉团伙欺诈模式。类别特征中的“设备指纹”与数值特征中的“IP地址变更频次”是关键输入。
  • 信用评估:时序特征(如近6个月逾期次数趋势)与数值特征(如收入负债比)共同构成评分卡基础。特征稳定性(PSI < 0.1)是模型上线前的硬性门槛。
  • 贷后预警:通过滑窗统计特征(如近3天联系人失联比例)实时捕捉风险信号,要求特征计算延迟低于分钟级。

3.3.2 营销场景:以响应率和转化率为导向

  • 精准推荐:类别特征(如历史点击品类)与数值特征(如近7天浏览时长)组合,构建用户兴趣向量。时序特征中的“购买间隔”用于预测复购窗口。
  • 客群分层:基于RFM模型(最近一次消费、频率、金额)的数值特征,将用户划分为高价值、沉睡、流失等群体。类别特征中的“渠道来源”辅助归因分析。
  • 响应预测:时序特征(如近30天打开推送次数)与类别特征(如活动偏好标签)共同输入LR或XGBoost模型,提升营销活动ROI。
关键差异总结:风控特征更关注长周期稳定性与异常捕获能力;营销特征更关注短期行为响应与群体区分粒度。同一原始数据(如交易金额)在风控中可能做对数变换以压缩极端值,在营销中则可能做分箱以形成价值等级。

3.4 特征工程全景流程

下图展示了从原始数据到建模特征的标准处理链路,涵盖特征定义、类型识别、加工与监控四个阶段:

特征工程全景流程 原始数据接入 用户属性 / 交易 / 图谱 特征定义与类型识别 数值 / 类别 / 时序 特征加工与组合 变换 / 编码 / 交叉 监控 数据源类型 • 用户基础信息 • 交易流水 • 关系图谱 类型判定依据 • 数值:连续/离散 • 类别:枚举/标签 • 时序:时间窗口 加工方法 • 标准化 / 分箱 • 独热 / 目标编码 • 滑窗统计 PSI IV 缺失 特征工程核心产出物 特征字典(名称 / 类型 / 计算口径 / 稳定性指标) 特征缺失巡检报告(缺失率 / 异常值 / 分布漂移) 特征重要性排序(用于模型筛选与业务解释)

3.5 特征缺失巡检的定位

特征缺失是金融图谱建模中最常见的数据质量问题。缺失原因包括:数据采集失败、关系图谱稀疏、时间窗口未覆盖等。在特征工程流程中,缺失巡检应嵌入特征加工后、模型训练前的环节,作为质量门禁。

常见误区:直接删除含缺失值的样本或特征,可能导致样本选择偏差或信息损失。正确的做法是先分析缺失机制(MCAR / MAR / MNAR),再选择填充策略(均值填充、模型预测填充、图谱邻居填充)。

以下代码展示了使用Python进行特征缺失率统计与类型识别的基础实现:

import pandas as pd
import numpy as np

# 模拟金融特征数据
df = pd.DataFrame({
    'income': [5000, 8000, np.nan, 12000, 6500],
    'age': [25, 30, 35, np.nan, 28],
    'occupation': ['engineer', 'teacher', 'doctor', 'engineer', np.nan],
    'trans_amount_7d': [1200, np.nan, 800, 2000, 1500]
})

# 特征缺失率统计
missing_rate = df.isnull().mean().round(4) * 100
print("=== 特征缺失率 (%) ===")
print(missing_rate)

# 特征类型自动识别
def infer_feature_type(series):
    if series.dtype in ['int64', 'float64']:
        if series.nunique() < 10:
            return '类别(数值型枚举)'
        else:
            return '数值'
    elif series.dtype == 'object':
        return '类别'
    else:
        return '其他'

print("\n=== 特征类型推断 ===")
for col in df.columns:
    ftype = infer_feature_type(df[col])
    print(f"{col}: {ftype}")