PSI 是金融风控和信用评分卡建模中常用的一个指标,用于衡量两个数据集(通常是基准数据和当前数据)之间某个变量分布的变化程度。
目录
1. PSI 的概念与应用
1.1 什么是 PSI?
人口稳定指数(Population Stability Index,PSI) 是衡量两个不同样本(通常是基准数据和当前数据)之间分布变化的一种指标。它广泛应用于金融风控、信用评分卡建模和模型监控中,用于检测变量分布的稳定性。
1.2 PSI 的应用场景
- 模型监控:在模型上线后,定期计算 PSI 以监控变量分布是否发生显著变化,从而判断模型是否需要重新校准或更新。
- 特征稳定性评估:在特征工程过程中,评估特征在不同时间段或不同数据集上的稳定性。
- 数据质量监控:检测数据集中的变量是否存在漂移或异常变化。
1.3 PSI 的解释
- PSI < 0.1:变量分布稳定,变化不大。
- 0.1 ≤ PSI < 0.25:变量分布有一定变化,需要关注。
- PSI ≥ 0.25:变量分布变化显著,可能需要重新建模或调整。
2. toad.metrics.PSI
函数概述
toad.metrics.PSI
是 toad
库中用于计算人口稳定指数(PSI) 的函数。它通过比较基准数据和测试数据中某个变量的分布,计算出 PSI 值,并可选择返回详细的分箱比例信息。
3. 函数签名与参数详解
函数签名
toad.metrics.PSI(test, base, combiner=None, return_frame=False)
参数说明
-
test
(array-like
):- 描述:用于测试 PSI 的数据集,通常是最新的数据集中的某个特征列。
- 类型:可以是 Pandas 的 Series、列表、Numpy 数组等。
-
base
(array-like
):- 描述:基准数据集,用于计算 PSI 的参考分布,通常是模型训练时的特征数据。
- 类型:同
test
。
-
combiner
(Combiner
|list
|dict
, 可选):- 描述:用于分箱的工具或分箱边界。可以使用
toad
提供的Combiner
对象,也可以传递自定义的分箱边界列表或字典。 - 类型:
toad
的Combiner
类实例、列表或字典。 - 默认值:
None
,表示使用默认的分箱策略。
- 描述:用于分箱的工具或分箱边界。可以使用
-
return_frame
(bool
, 可选):- 描述:是否返回每个分箱的比例数据框。
- 类型:布尔值。
- 默认值:
False
,仅返回 PSI 值。
4. 返回值说明
-
如果
return_frame=False
,函数返回计算得到的 PSI 值。 -
如果
return_frame=True
,函数返回一个元组,包含两个数据。第一个是计算得到的 PSI 值;第二个是每个分箱的比例信息,通常是一个 Pandas 的 DataFrame,包含基准数据和测试数据在每个分箱中的比例。
5. 使用示例
示例背景
假设我们有一个信用评分模型,其中包含一个名为 income
的特征。我们希望监控 income
变量在基准数据(训练集)和当前数据(最新数据)中的分布变化,以计算其 PSI 值。
示例代码
import pandas as pd
import toad as td
# 生成示例数据
# 基准数据(训练集)
base_data = pd.Series([30, 40, 35, 50, 45, 60, 55, 65, 70, 75, 80, 85, 90, 95, 100])
# 当前数据(最新数据)
current_data = pd.Series([32, 42, 38, 52, 48, 62, 58, 68, 72, 78, 82, 88, 92, 98, 105])
# 计算 PSI
psi_value, psi_detail = td.metrics.PSI(
test=current_data,
base=base_data,
combiner = [38, 48, 68, 88],
return_frame=True
)
print(f'PSI 值: {psi_value}')
print('分箱详细信息:')
print(psi_detail)
解释
-
数据准备:
- 基准数据:
base_data
表示训练集中的income
数据。 - 当前数据:
current_data
表示最新的数据集中的income
数据。
- 基准数据:
-
计算 PSI:
- 使用
toad.metrics.PSI
函数计算 PSI 值。 - 分箱策略:手动指定了分箱的边界。
- 返回详细信息:设置
return_frame=True
,返回每个分箱的比例信息。
- 使用
-
输出结果:
- PSI 值:输出总的 PSI 值。
- 分箱详细信息:输出每个分箱的基准数据比例和当前数据比例。
示例输出
假设输出如下:
PSI 值: 0.0653886168674484
分箱详细信息:
value test base
0 00.[-inf ~ 38) 0.066667 0.133333
1 01.[38 ~ 48) 0.133333 0.133333
2 02.[48 ~ 68) 0.266667 0.266667
3 03.[68 ~ 88) 0.266667 0.266667
4 04.[88 ~ inf) 0.266667 0.200000
- PSI 值为 0.06538,小于 0.1,表示
income
变量的分布在基准数据和当前数据之间相对稳定。 - 分箱详细信息 显示了每个分箱的范围、基准数据和当前数据的样本数占比。
6. 工作原理
toad.metrics.PSI
函数通过以下步骤计算 PSI:
-
分箱(Binning):
- 将基准数据和测试数据按照相同的分箱策略进行分箱。可以使用自动分箱或自定义分箱边界。
-
计算比例(Proportion):
- 计算每个分箱在基准数据和测试数据中的比例(基准比例和当前比例)。
-
计算 PSI:
-
对于每个分箱,计算 PSI 值:
P S I = ∑ i = 1 n ( P i − Q i ) × ln ( P i Q i ) PSI = \sum_{i=1}^{n} (P_i - Q_i) \times \ln\left(\frac{P_i}{Q_i}\right) PSI=i=1∑n(Pi−Qi)×ln(QiPi)其中, P i P_i Pi 是基准数据在第 i i i 个分箱中的比例, Q i Q_i Qi 是测试数据在第 i i i 个分箱中的比例。
-
-
汇总结果:
- 总 PSI 值为各分箱 PSI 值的总和。
- 如果
return_frame=True
,还会返回每个分箱的详细比例信息。
7. 注意事项与建议
-
分箱策略选择:
- 不同的分箱策略(等宽、等频、自定义)会影响 PSI 的计算结果。根据变量的分布情况和业务需求选择合适的分箱方法。
-
分箱数量控制:
- 分箱数量过多可能导致每个分箱样本量过少,影响 PSI 的稳定性;分箱数量过少可能无法充分反映变量分布的变化。通常建议分箱数量在 5 到 20 之间。
-
处理异常值:
- 在进行分箱前,建议对变量进行异常值处理,确保分箱边界的合理性,避免极端值对 PSI 计算产生过大影响。
-
样本量要求:
- 每个分箱内的样本量应足够大,以保证 PSI 计算的可靠性。避免某些分箱内样本过少导致 PSI 不稳定。
-
定期监控:
- PSI 是用于监控模型和变量稳定性的指标,应定期计算并跟踪,及时发现模型性能的潜在问题。
-
结合业务知识:
- 虽然 PSI 提供了量化的分布变化指标,但结合业务知识进行解释和决策更为有效。例如,了解变量的业务含义,有助于判断 PSI 变化是否对模型有实际影响。
-
处理缺失值:
- 在进行 PSI 计算前,确保对缺失值进行适当处理,如填充或剔除,以提高计算的准确性。
-
多变量 PSI 计算:
- 在实际项目中,通常需要对多个变量进行 PSI 计算。可以通过循环或封装函数,实现批量处理,提高效率。
8. 常见问题与解决方案
8.1 PSI 计算结果异常
- 问题:PSI 值远高于预期,显示变量分布变化显著。
- 可能原因:
- 数据中存在数据漂移或异常变化。
- 分箱策略不合理,导致某些分箱样本量过少。
- 解决方案:
- 检查数据是否存在异常变化或数据质量问题。
- 调整分箱策略或分箱数量,确保每个分箱样本量足够。
8.2 分箱样本量过少
- 问题:某些分箱内的样本量过少,导致 PSI 计算不稳定。
- 解决方案:
- 增加分箱数量,使每个分箱的样本量合理。
- 使用等频分箱(Equal Frequency Binning)方法,确保每个分箱的样本量相对均衡。
8.3 分类变量 PSI 计算
- 问题:对于分类变量,如何进行 PSI 计算?
- 解决方案:
- 对分类变量进行编码(如独热编码或标签编码),然后进行 PSI 计算。
- 或者基于类别频率进行分箱,直接计算各类别的比例变化。
8.4 自定义分箱边界
- 问题:需要基于业务需求自定义分箱边界,但不知道如何实现。
- 解决方案:
- 使用列表或字典形式传递自定义的分箱边界给
combiner
参数。 - 例如,将分箱边界设置为
[0, 30, 50, 70, 100]
。
- 使用列表或字典形式传递自定义的分箱边界给
9. 总结
toad.metrics.PSI
是一个强大且易用的工具,用于计算变量在不同数据集之间的分布变化程度。通过合理使用 PSI,可以有效监控模型和数据的稳定性,及时发现并应对潜在的数据漂移问题,确保模型在实际应用中的可靠性和一致性。
关键点回顾
- PSI 的意义:衡量变量在基准数据和当前数据之间的分布变化,常用于模型监控和特征稳定性评估。
- 使用方法:通过
toad.metrics.PSI
计算 PSI 值,并分析每个分箱的详细比例信息。 - 参数设置:合理选择分箱策略和数量,确保每个分箱内样本量足够。
- 实际应用:定期监控 PSI,结合业务需求和其他指标,提升模型的稳定性和可解释性。
高级应用
- 批量计算多个变量的 PSI:通过循环或封装函数,实现对多个变量的批量 PSI 计算。
- 与其他指标结合使用:PSI 可与 KS、AUC 等指标结合使用,全面评估模型和变量的稳定性与性能。
- 自动化监控流程:将 PSI 计算集成到数据流水线或自动化监控系统中,实时监控变量分布变化,触发报警或重新训练模型。
示例:批量计算多个变量的 PSI
import pandas as pd
import toad as td
# 示例数据框
base_data_df = pd.DataFrame({
'age': [30, 40, 35, 50, 45, 60, 55, 65, 70, 75, 80, 85, 90, 95, 100],
'income': [3000, 4000, 3500, 5000, 4500, 6000, 5500, 6500, 7000, 7500, 8000, 8500, 9000, 9500, 10000],
'credit_score': [600, 650, 620, 700, 680, 720, 710, 730, 750, 760, 780, 790, 800, 810, 820],
'label': [1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0]
})
current_data_df = pd.DataFrame({
'age': [32, 42, 38, 52, 48, 62, 58, 68, 72, 78, 82, 88, 92, 98, 105],
'income': [3200, 4200, 3800, 5200, 4800, 6200, 5800, 6800, 7200, 7800, 8200, 8800, 9200, 9800, 10500],
'credit_score': [610, 660, 630, 710, 690, 730, 720, 740, 760, 770, 790, 800, 810, 820, 830]
})
features = ['age', 'income', 'credit_score']
psi_results = {}
psi_details = {}
combiner = td.transform.Combiner()
for feature in features:
psi, detail = td.metrics.PSI(
test=current_data_df[feature],
base=base_data_df[feature],
combiner=combiner.fit(base_data_df[feature], y=base_data_df['label']), # 自动分箱
return_frame=True
)
psi_results[feature] = psi
psi_details[feature] = detail
print(f'PSI for {feature}: {psi}')
# 输出所有变量的 PSI 值
print('所有变量的 PSI 值:', psi_results)
输出示例
PSI for age: 0.0
PSI for income: 0.0
PSI for credit_score: 0.11945063128187033
所有变量的 PSI 值: {'age': 0.0, 'income': 0.0, 'credit_score': 0.11945063128187033}
通过上述步骤,你可以高效地计算和分析多个变量的 PSI 值,监控模型和数据的稳定性,确保模型在实际应用中的可靠性和有效性。