4. PSI计算前置准备:数据采集要求、时间窗口定义与数据质量检查
PSI(群体稳定性指标)的计算并非简单的公式套用,其结果的可靠性高度依赖于前置数据准备的质量。本章将系统讲解PSI计算前的三项核心准备工作:明确数据采集要求、严格定义时间窗口、执行数据质量检查与清洗。只有打好这些基础,后续的PSI计算与告警才有实际意义。
核心原则: PSI衡量的是两个样本群体在评分分布上的差异。如果用于对比的两个样本本身存在数据质量问题或时间窗口定义混乱,PSI将失去对模型稳定性的真实反映能力。
4.1 数据采集要求
PSI计算所需的数据主要来源于信用评分模型在生产环境中的实际应用记录。数据采集需满足以下核心要求:
| 维度 | 具体要求 | 说明 |
|---|---|---|
| 数据来源 | 生产环境评分引擎输出的评分结果 | 确保与模型部署版本一致,避免使用测试或预发环境数据 |
| 字段完整性 | 必须包含:客户ID、评分日期、评分值、模型版本号 | 可选字段:决策结果、逾期标签、特征快照 |
| 数据粒度 | 每笔申请或每个客户每次评分记录 | 避免聚合或汇总数据,保留原始评分记录 |
| 时间跨度 | 覆盖完整的监控周期,至少包含一个完整自然月 | 建议保留历史全量数据,便于回溯分析 |
| 数据量级 | 每个时间窗口内样本量 ≥ 1000 条 | 样本量过小会导致PSI波动剧烈,失去统计意义 |
常见陷阱: 部分团队仅采集评分值而忽略评分日期和模型版本号,导致无法准确划分时间窗口或追溯模型变更历史。建议在数据采集阶段就建立完整的评分日志表。
4.2 时间窗口定义
PSI计算涉及三个关键时间窗口:开发样本期、观察期和监控期。每个窗口的定义直接影响PSI的对比基准和告警阈值设定。
4.2.1 开发样本期
指模型开发阶段用于训练和验证的数据所覆盖的时间范围。该时期的评分分布通常作为模型设计的理论基准,但在PSI监控中,开发样本期一般不直接参与计算,而是作为参考基线。
4.2.2 观察期
PSI计算中的基准分布窗口。通常选择模型上线后第一个完整自然月或季度作为观察期。观察期的评分分布被视为“稳定状态”的基准,后续所有监控期的分布都将与之对比。
4.2.3 监控期
当前需要评估稳定性的时间窗口。监控期可以是月度、季度或自定义周期。PSI即计算监控期评分分布与观察期评分分布之间的差异程度。
| 窗口类型 | 典型长度 | 用途 | 注意事项 |
|---|---|---|---|
| 开发样本期 | 6~12个月 | 模型训练基准 | 不直接用于PSI计算 |
| 观察期 | 1~3个月 | PSI基准分布 | 需确保样本量充足且业务稳定 |
| 监控期 | 1个月 | 当前分布对比 | 滚动计算,每次向前推进一个窗口 |
实践建议: 观察期一旦选定,不建议频繁更换。如果业务发生重大变化(如客群结构调整、政策变更),可考虑重新设定观察期,但需在监控报告中明确标注。
4.3 数据质量检查与清洗
数据质量是PSI计算的“生命线”。脏数据会直接导致PSI值失真,引发误告警或漏告警。数据质量检查应覆盖以下维度:
4.3.1 完整性检查
- 缺失值检测: 检查评分值、评分日期、客户ID等关键字段是否存在空值
- 重复记录: 同一客户同一评分日期是否存在多条记录
- 版本一致性: 确认所有记录对应的模型版本号是否与当前部署版本一致
4.3.2 合理性检查
- 评分范围: 评分值是否在模型定义的合理区间内(如300~850)
- 时间顺序: 评分日期是否在合理时间范围内,是否存在未来日期
- 分布形态: 初步检查评分分布是否出现极端异常值或断层
4.3.3 一致性检查
- 跨窗口一致性: 观察期与监控期的数据采集逻辑是否一致
- 字段映射: 评分字段名称、数据类型是否统一
- 业务规则: 是否排除了测试用户、内部员工等非真实业务数据
4.3.4 数据清洗规则
基于上述检查结果,执行以下清洗操作:
# 数据清洗示例代码(Python)
import pandas as pd
import numpy as np
def clean_psi_data(df):
"""
PSI计算数据清洗函数
"""
# 1. 移除缺失值
df_clean = df.dropna(subset=['score', 'score_date', 'customer_id'])
# 2. 移除重复记录(保留最新一条)
df_clean = df_clean.sort_values('score_date').drop_duplicates(
subset=['customer_id', 'score_date'], keep='last'
)
# 3. 过滤评分范围
df_clean = df_clean[(df_clean['score'] >= 300) & (df_clean['score'] <= 850)]
# 4. 过滤异常日期
df_clean = df_clean[df_clean['score_date'] <= pd.Timestamp.today()]
# 5. 排除测试用户(假设测试用户ID以 'TEST' 开头)
df_clean = df_clean[~df_clean['customer_id'].str.startswith('TEST')]
return df_clean
# 使用示例
raw_data = pd.read_csv('score_log.csv')
cleaned_data = clean_psi_data(raw_data)
print(f"清洗前样本量: {len(raw_data)}, 清洗后样本量: {len(cleaned_data)}")
最佳实践: 建议将数据质量检查结果记录为日志,包括:检查时间、原始样本量、清洗后样本量、各类异常数量。这些日志可用于追溯PSI异常是否由数据质量问题引起。
4.4 本章小结
PSI计算的前置准备工作可归纳为以下清单:
| 步骤 | 关键动作 | 交付物 |
|---|---|---|
| 1 | 确认数据采集字段完整,包含评分值、日期、客户ID、版本号 | 数据采集规范文档 |
| 2 | 定义观察期和监控期的时间范围 | 时间窗口定义表 |
| 3 | 执行完整性、合理性、一致性检查 | 数据质量检查报告 |
| 4 | 执行数据清洗,生成可用于PSI计算的干净数据集 | 清洗后数据集 |
完成上述准备工作后,即可进入下一阶段:评分分箱与PSI指标的实际计算。