4. 数据准备与预处理:交易数据清洗、客户信息标准化、缺失值处理、异常值检测

在反洗钱监测模型的生命周期中,数据准备与预处理是决定模型成败的基石。原始交易数据与客户信息通常来自多个异构系统,包含大量噪声、重复、缺失与异常。本章聚焦于将原始数据转化为高质量、标准化、可供模型直接使用的特征矩阵,涵盖四大核心环节:交易数据清洗、客户信息标准化、缺失值处理与异常值检测。

4.1 交易数据清洗

交易数据清洗的目标是消除因系统故障、人工录入错误或接口传输问题导致的脏数据。常见清洗任务包括:

  • 去重:基于交易流水号、交易时间、金额、对手方等关键字段的组合,识别并移除完全重复或高度相似的记录。
  • 格式统一:将日期时间字段统一为 YYYY-MM-DD HH:MM:SS 格式;金额字段统一为两位小数,并去除货币符号与千分位分隔符。
  • 逻辑校验:剔除交易时间早于开户时间、交易金额为负数或零(除特定冲正交易外)、交易币种与账户币种不匹配等逻辑矛盾记录。
  • 字段拆分与合并:将“交易附言”中的结构化信息(如对手方账号、用途代码)拆分至独立字段;将分散在多张表中的交易关联信息合并至宽表。
实践要点:清洗规则应记录在数据质量规则库中,每次清洗后生成数据质量报告,统计清洗记录数、清洗原因分布,便于后续审计与规则迭代。

4.2 客户信息标准化

客户信息标准化旨在将来自不同业务系统(如核心银行、信用卡、财富管理)的客户数据映射到统一的数据模型,消除实体歧义。标准化流程通常包括:

  1. 身份标识统一:以客户唯一标识(如身份证号、统一社会信用代码)为主键,合并多系统客户档案。
  2. 名称清洗:去除全角/半角混乱、多余空格、特殊符号;对个人客户统一姓名大小写格式;对机构客户统一名称缩写规则。
  3. 地址与联系方式标准化:将地址拆分为省、市、区、详细地址;手机号统一为11位数字,去除国家代码前缀。
  4. 风险等级映射:将各系统不同的风险等级编码(如“高/中/低”、“1/2/3”、“A/B/C”)映射为统一的风险等级标签。
字段 原始格式示例 标准化后格式
客户姓名 张三 (含空格) 张三
身份证号 110101199001011234 110101199001011234
手机号 +86-13800138000 13800138000
风险等级 High 高风险

4.3 缺失值处理

缺失值在反洗钱数据中普遍存在,处理策略需结合字段的业务含义与缺失机制。常用方法包括:

  • 删除:当缺失比例极低(<1%)且为随机缺失时,直接删除缺失记录;当关键字段(如交易对手方)缺失导致无法建模时,整条记录删除。
  • 填充:
    • 统计填充:连续变量使用均值、中位数填充;分类变量使用众数填充。
    • 业务填充:如“交易渠道”缺失,可根据交易时间、金额、设备指纹等推断为“线上”或“柜面”。
    • 模型填充:使用KNN、回归或随机森林预测缺失值,适用于缺失比例较高(5%-20%)且字段间相关性较强的场景。
  • 标记:将缺失作为一种独立状态,新增“是否缺失”标志位,保留缺失信息对模型的可解释性。
注意:在反洗钱场景中,部分字段的缺失本身可能具有异常含义(如“职业”字段缺失可能暗示客户信息不完整),建议优先采用标记法或模型填充法,避免直接删除导致信息损失。

4.4 异常值检测

异常值检测用于识别与正常交易模式显著偏离的数据点,这些点可能是欺诈、洗钱行为或数据录入错误的信号。检测方法分为统计方法与机器学习方法两大类:

方法类别 具体方法 适用场景
统计方法 Z-Score、IQR(四分位距) 单变量、近似正态分布的数据
距离方法 KNN、LOF(局部异常因子) 多变量、密度分布不均的数据
聚类方法 DBSCAN、孤立森林 高维数据、无标签场景
时间序列方法 移动平均、STL分解 交易频率、金额的时间序列数据

以下SVG图展示了从原始数据到预处理后数据的完整流程,以及各环节之间的依赖关系:

数据准备与预处理流程 原始交易与客户数据 交易数据清洗 客户信息标准化 清洗后 合并为统一宽表 缺失值处理 异常值检测与处理 高质量预处理数据 说明:各环节可迭代执行,异常值检测结果可能反馈至清洗与缺失值处理环节

4.5 异常值处理策略

检测到异常值后,需根据业务场景选择处理方式:

  • 修正:对于因系统故障导致的明显错误(如金额多一个零),根据业务规则或历史均值修正。
  • 截尾:对极端值进行截尾处理(如将超过99.9%分位数的值替换为该分位数),减少对模型的影响。
  • 保留并标记:对于疑似洗钱行为的异常交易,保留原始值并新增“异常标志”字段,供模型学习异常模式。
  • 单独建模:将异常值单独提取,构建专门的异常交易预警模型,与主模型并行运行。
最佳实践:建议建立异常值处理日志,记录每条异常记录的检测方法、处理方式、处理前后值及审批人,确保数据处理的透明性与可追溯性。

以下SVG图对比了三种常见异常值检测方法在二维空间中的检测效果差异:

三种异常值检测方法对比(二维示意) Z-Score 方法 假设数据服从正态分布 IQR 方法 基于四分位距,不受极端值影响 孤立森林 通过随机切割快速孤立异常点 正常点 异常点

4.6 数据预处理代码示例

以下Python代码片段展示了使用Pandas进行交易数据清洗与缺失值处理的典型流程:

import pandas as pd
import numpy as np

# 加载原始交易数据
df = pd.read_csv('transactions_raw.csv')

# 1. 交易数据清洗
# 去重
df = df.drop_duplicates(subset=['txn_id', 'txn_time', 'amount', 'counterparty'])

# 格式统一
df['txn_time'] = pd.to_datetime(df['txn_time'], format='%Y-%m-%d %H:%M:%S')
df['amount'] = df['amount'].str.replace(',', '').str.replace('¥', '').astype(float)

# 逻辑校验:剔除金额为负或零的记录(冲正交易除外)
df = df[~((df['amount'] <= 0) & (df['txn_type'] != 'REVERSAL'))]

# 2. 缺失值处理
# 统计缺失比例
missing_ratio = df.isnull().mean()

# 对'channel'字段使用众数填充
df['channel'].fillna(df['channel'].mode()[0], inplace=True)

# 对'customer_occupation'字段新增缺失标志
df['occupation_missing'] = df['customer_occupation'].isnull().astype(int)
df['customer_occupation'].fillna('未知', inplace=True)

# 3. 异常值检测(IQR方法)
Q1 = df['amount'].quantile(0.25)
Q3 = df['amount'].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR

# 标记异常交易
df['amount_anomaly'] = ((df['amount'] < lower_bound) | (df['amount'] > upper_bound)).astype(int)

print(f"预处理完成,最终数据量: {len(df)} 条")
print(f"异常交易占比: {df['amount_anomaly'].mean():.2%}")

4.7 数据质量评估指标

完成预处理后,需从以下维度评估数据质量,确保数据满足建模要求:

维度 指标 目标阈值
完整性 各字段缺失率 < 5%
唯一性 重复记录占比 < 1%
准确性 逻辑校验通过率 > 99%
一致性 字段格式统一率 100%
时效性 数据延迟时间 < 24小时
关键提醒:数据预处理不是一次性工作。在模型迭代过程中,每次新增数据源或调整业务规则时,都应重新执行预处理流程,并对比数据质量指标的变化。建议将预处理逻辑封装为可复用的ETL管道,配合版本控制,确保模型训练与线上评分使用相同的数据处理逻辑。