4. 数据源接入与清洗:内部数据与外部数据的 ETL 实践

贷后预警模型的准确性高度依赖数据质量。本章聚焦于多源异构数据的接入策略与 ETL(Extract, Transform, Load)清洗流程,确保进入预警看板的数据具备一致性、完整性和时效性。

4.1 数据源分类与接入策略

贷后预警所需数据可分为内部与外部两大类,接入方式与更新频率差异显著:

数据类别 典型数据源 接入方式 更新频率 关键字段示例
内部-还款流水 核心账务系统、还款渠道 CDC(变更数据捕获)/ 批量接口 T+0 实时 / 每日 借据号、应还日、实还日、逾期天数、本金余额
内部-行为数据 APP 埋点、客服系统、交易日志 消息队列(Kafka)/ 日志采集 准实时 / 每小时 登录频次、设备变更、客服投诉次数、大额交易标记
外部-征信 人行征信、百行征信、朴道征信 API 查询 / FTP 文件 按需 / 每周 信贷记录、查询次数、逾期标识、担保余额
外部-工商司法 国家企业信用信息公示系统、裁判文书网 API 接口 / 爬虫(合规授权) 每日 / 每周 经营状态、行政处罚、被执行人、开庭公告
外部-黑名单 行业共享黑名单、反欺诈联盟 API 实时查询 / 离线文件 实时 / 每日 身份证号、手机号、设备指纹、命中规则
接入原则:内部高频数据优先采用 CDC + 消息队列实现准实时接入;外部低频数据(如工商、司法)采用每日批量调度,避免对源系统造成过大压力。

4.2 ETL 清洗核心流程

原始数据无法直接用于预警模型,必须经过标准化清洗。以下为贷后场景下的 ETL 关键步骤:

  1. 抽取(Extract): 按时间戳或增量标记拉取数据,避免全量重复抽取。还款流水按“最后修改时间”增量抽取;征信报告按“查询日期”增量抽取。
  2. 转换(Transform):
    • 字段标准化: 统一日期格式(YYYY-MM-DD)、金额单位(分转元)、枚举值映射(如“逾期1-30天”转为逾期天数数值)。
    • 衍生计算: 计算“距还款日天数”、“连续逾期次数”、“近30天查询征信次数”等预警特征。
    • 数据脱敏: 对身份证号、手机号等敏感字段进行 MD5 或 AES 加密,仅保留业务需要的脱敏标识。
  3. 加载(Load): 将清洗后的数据写入预警数据仓库(DWD 层),按客户 ID 和借据号建立宽表,供模型实时调用。
清洗规则示例(还款流水):
- 过滤掉测试借据(借据号以 'TEST' 开头)。
- 将“实还日期”为 NULL 且“应还日期”早于当前日期的记录标记为“逾期”。
- 逾期天数 = 当前日期 - 应还日期(若实还日期不为空,则取实还日期 - 应还日期)。

4.3 数据质量监控与异常处理

ETL 过程中必须嵌入质量监控规则,防止脏数据污染预警模型:

监控维度 规则描述 告警阈值 处理动作
完整性 关键字段(借据号、客户ID、应还日)不可为空 空值率 > 0.5% 阻断该批次加载,通知数据运维
一致性 同一借据在还款流水与核心系统余额一致 差异笔数 > 10 标记异常借据,人工复核
时效性 还款流水数据延迟不超过 30 分钟 延迟 > 30 分钟 触发 Kafka 消费积压告警
准确性 逾期天数计算值与业务系统一致 偏差 > 1 天 回刷历史数据,修复计算逻辑
避坑提示: 外部征信数据常存在“多头借贷”字段缺失或格式不统一的问题。建议在 ETL 中建立“征信字段映射表”,将不同征信机构的字段名统一映射到标准字段,避免模型训练时出现特征断裂。

4.4 数据接入与清洗架构总览

以下 SVG 图展示了从多源数据接入到清洗加载的完整链路,以及各环节的监控反馈机制:

贷后预警数据接入与 ETL 清洗架构 贷后预警数据接入与 ETL 清洗架构 数据源层 内部还款流水 内部行为数据 外部征信数据 工商司法黑名单 接入层 CDC / 批量接口 Kafka 消息队列 API / FTP 调度 API / 离线文件 ETL 清洗层 核心清洗步骤 字段标准化 衍生特征计算 数据脱敏 质量规则校验 加载层 预警数据仓库(DWD 宽表) 质量监控告警 异常反馈

4.5 实战:还款流水 ETL 清洗代码示例

以下为使用 PySpark 对还款流水进行清洗的典型代码片段,包含字段标准化、逾期标记和空值处理:

from pyspark.sql import SparkSession
from pyspark.sql.functions import col, when, datediff, current_date, to_date

spark = SparkSession.builder.appName("repayment_etl").getOrCreate()

# 读取原始还款流水
df_raw = spark.read.parquet("hdfs://data/repayment_raw/")

# 清洗逻辑
df_clean = df_raw \
    .filter(col("借据号").isNotNull()) \
    .filter(~col("借据号").startswith("TEST")) \
    .withColumn("应还日期", to_date(col("应还日期"), "yyyyMMdd")) \
    .withColumn("实还日期", to_date(col("实还日期"), "yyyyMMdd")) \
    .withColumn("逾期天数",
        when(col("实还日期").isNull(),
             datediff(current_date(), col("应还日期"))
        ).otherwise(
            when(col("实还日期") > col("应还日期"),
                 datediff(col("实还日期"), col("应还日期"))
            ).otherwise(0)
        )
    ) \
    .withColumn("逾期标记",
        when(col("逾期天数") > 0, 1).otherwise(0)
    ) \
    .withColumn("数据日期", current_date())

# 写入预警宽表
df_clean.write.mode("overwrite").parquet("hdfs://data/dwd/repayment_clean/")

print("ETL 清洗完成,共处理 {} 条记录".format(df_clean.count()))
关键说明:
- 使用 filter 剔除测试数据与空值借据,保证主键完整性。
- 逾期天数计算区分“已还清”与“未还清”两种场景,避免负值。
- 写入时采用 overwrite 模式,配合分区字段(如数据日期)实现增量覆盖。

4.6 数据接入清洗清单(Checklist)

在搭建贷后预警看板前,建议按以下清单逐项确认数据就绪状态:

  • ✅ 内部还款流水: 已接入至少 12 个月历史数据,包含借据状态变更记录。
  • ✅ 内部行为数据: 已接入客户 APP 登录、设备变更、客服交互等行为日志。
  • ✅ 外部征信数据: 已建立征信查询授权机制,字段映射表已完成。
  • ✅ 工商司法数据: 已配置每日增量更新任务,覆盖被执行人、行政处罚等关键事件。
  • ✅ 黑名单数据: 已对接至少 2 家行业反欺诈数据源,支持实时查询。
  • ✅ 质量监控: 已配置完整性、一致性、时效性告警规则,并设置通知渠道。
进阶建议: 对于外部数据(如征信、工商),建议建立“数据快照表”,每日保留全量快照,便于回溯历史状态变化,支撑贷后预警模型的时序特征计算。