4. 数据准备与特征工程:用户画像数据、交易流水数据、外部征信数据的清洗与特征衍生
信用额度定价模型的精度与稳定性,高度依赖底层数据的质量与特征表达能力。本章聚焦三类核心数据源——用户画像、交易流水、外部征信——的清洗规则与特征衍生方法,构建从原始数据到模型输入特征的标准链路。
4.1 三类数据源的特征定位与清洗要点
不同数据源在额度定价中承担的角色不同,清洗策略也各有侧重。下表梳理了各数据源的核心定位与关键清洗动作。
| 数据源 | 定价角色 | 关键清洗动作 | 常见问题 |
|---|---|---|---|
| 用户画像数据 | 基础风险分层与额度锚定 | 缺失值填充、异常年龄截断、职业编码标准化 | 年龄异常值、职业类别缺失、学历等级错位 |
| 交易流水数据 | 收入稳定性与消费行为刻画 | 重复交易去重、节假日效应调整、大额异常交易截尾 | 重复记录、空值商户、金额单位不一致 |
| 外部征信数据 | 多头借贷与历史违约识别 | 查询时间对齐、机构编码统一、逾期字段逻辑校验 | 查询日期缺失、机构名称不统一、逾期天数负值 |
清洗优先级建议: 交易流水数据量最大、噪声最多,建议优先完成去重与金额截尾;外部征信数据对模型区分度贡献高,需重点校验时间对齐与逻辑一致性。
4.2 用户画像数据清洗与特征衍生
用户画像数据通常包含年龄、性别、职业、学历、婚姻状况、居住城市等级等静态属性。清洗后需衍生出风险分层特征。
4.2.1 清洗规则
- 年龄截断: 将
age < 18或age > 80的样本标记为异常,按分位数截断或填充中位数。 - 职业编码标准化: 将自由文本职业映射到统一分类(如:01-公务员、02-企业职员、03-自由职业、04-其他)。
- 学历等级排序: 将学历转换为有序数值(1-初中及以下,2-高中,3-大专,4-本科,5-硕士及以上)。
4.2.2 特征衍生
- 年龄分段:
age_group = pd.cut(age, bins=[18,25,35,45,55,80], labels=['青年','青壮年','中年','中老年','老年']) - 职业风险等级: 基于历史违约率将职业映射为
职业风险分(1-低风险,2-中风险,3-高风险)。 - 学历-年龄交叉:
edu_age_ratio = 学历等级 / (年龄 - 18),反映教育投入密度。
# 用户画像特征衍生示例
import pandas as pd
import numpy as np
def user_profile_feature(df):
# 年龄分段
df['age_group'] = pd.cut(df['age'], bins=[18,25,35,45,55,80],
labels=['青年','青壮年','中年','中老年','老年'])
# 职业风险映射
risk_map = {'公务员':1, '企业职员':2, '自由职业':3, '其他':3}
df['occupation_risk'] = df['occupation'].map(risk_map).fillna(3)
# 学历-年龄交叉
df['edu_age_ratio'] = df['education_level'] / (df['age'] - 18 + 1e-5)
return df
4.3 交易流水数据清洗与特征衍生
交易流水数据是刻画用户收入与消费行为最直接的来源。清洗重点在于去重、异常值处理与时间序列对齐。
4.3.1 清洗规则
- 重复交易去重: 按
用户ID + 交易时间 + 交易金额 + 商户名称四字段去重。 - 大额交易截尾: 对单笔交易金额超过
99.5% 分位数的样本,以分位数替换。 - 节假日效应调整: 识别春节、双十一等特殊日期,标记为
is_holiday字段,后续建模时单独处理。
4.3.2 特征衍生
- 收入稳定性指标: 近6个月月均收入的标准差 / 均值,即
收入变异系数。 - 消费集中度: 前3大消费类别金额占比,反映消费结构。
- 夜间交易占比: 22:00-06:00 交易笔数 / 总交易笔数,刻画非正常消费行为。
# 交易流水特征衍生示例
def transaction_feature(df_txn):
# 月均收入与变异系数
monthly_income = df_txn[df_txn['type']=='收入'].groupby('user_id')['amount'].agg(['mean','std'])
monthly_income['income_cv'] = monthly_income['std'] / (monthly_income['mean'] + 1e-5)
# 夜间交易占比
df_txn['is_night'] = ((df_txn['hour'] >= 22) | (df_txn['hour'] < 6)).astype(int)
night_ratio = df_txn.groupby('user_id')['is_night'].mean().rename('night_txn_ratio')
return monthly_income.join(night_ratio, how='left')
4.4 外部征信数据清洗与特征衍生
外部征信数据是额度定价中风险区分能力最强的数据源之一,但数据质量参差不齐,需严格清洗。
4.4.1 清洗规则
- 查询时间对齐: 将不同征信机构的查询日期统一为
YYYY-MM-DD格式,缺失日期按最近一次查询填充。 - 机构编码统一: 建立机构名称与标准编码的映射表,如
{"人行征信":"PBOC", "百行征信":"Baihang", "朴道征信":"Pudao"}。 - 逾期字段逻辑校验: 逾期天数
overdue_days必须为非负整数,若出现负值则置为0并记录异常标记。
4.4.2 特征衍生
- 多头借贷指数: 近3个月征信查询次数 / 近3个月成功借款次数,反映资金饥渴程度。
- 最大逾期深度: 历史最大逾期天数,按
max_overdue_days分箱(0, 1-30, 31-60, 61-90, 90+)。 - 征信查询趋势: 近1个月查询次数 / 近6个月月均查询次数,反映近期借贷行为突变。
# 外部征信特征衍生示例
def credit_report_feature(df_credit):
# 多头借贷指数
df_credit['multi_head_index'] = df_credit['query_cnt_3m'] / (df_credit['loan_cnt_3m'] + 1)
# 最大逾期深度分箱
bins = [0, 1, 30, 60, 90, 999]
labels = ['无逾期','轻度','中度','重度','严重']
df_credit['overdue_depth'] = pd.cut(df_credit['max_overdue_days'], bins=bins, labels=labels)
# 查询趋势
df_credit['query_trend'] = df_credit['query_cnt_1m'] / (df_credit['query_cnt_6m']/6 + 1e-5)
return df_credit
4.5 特征工程最终输出与质量校验
完成三类数据源的特征衍生后,需进行特征融合与质量校验,确保进入模型的特征集无泄漏、无高相关性、无缺失率过高。
4.5.1 特征融合策略
- 时间窗口对齐: 所有特征以
观察点日期为基准,向前回溯固定窗口(如6个月、12个月)。 - 用户ID关联: 以
user_id为主键,将用户画像、交易流水、外部征信特征进行left join。 - 缺失值处理: 缺失率 < 5% 的特征用中位数填充;缺失率 > 50% 的特征直接剔除。
4.5.2 质量校验清单
| 校验项 | 标准 | 处理方式 |
|---|---|---|
| 缺失率 | 单特征 < 50% | 超过则剔除 |
| 相关性 | 特征间 Pearson 相关系数 < 0.8 | 保留与目标变量相关性更高的特征 |
| 唯一值数量 | 连续特征至少 10 个唯一值 | 不足则合并或剔除 |
| 时间泄漏 | 特征计算不包含未来信息 | 严格按观察点回溯 |
常见陷阱: 交易流水中的“未来收入”特征(如当月工资在月底发放,但观察点在月初)会导致严重的时间泄漏。务必确保所有特征在观察点时刻是已知的。
4.6 特征工程全链路总览
下图展示了从三类原始数据到最终特征矩阵的完整链路,包含清洗、衍生、融合与校验四个阶段。
完成本章的数据准备与特征工程后,将进入模型训练与额度定价环节。特征质量直接决定模型上限,建议在特征衍生阶段多轮迭代验证,确保每个特征都有明确的业务含义与区分能力。