【风控】稳定性指标CSI

一、从WOE分箱到评分卡赋分

1.1 WOE分箱原理回顾

WOE(Weight of Evidence)将类别或数值型变量按照对目标事件(如违约)的分布差异进行分箱:

WOE i = ln ⁡ 好样本比例 i 坏样本比例 i = ln ⁡ G o o d i G o o d T B a d i B a d T \text{WOE}_i = \ln\frac{\text{好样本比例}_i}{\text{坏样本比例}_i} = \ln\frac{\frac{Good_i}{Good_T}}{\frac{Bad_i}{Bad_T}} WOEi=ln坏样本比例i好样本比例i=lnBadTBadiGoodTGoodi

其中 i i i表示第 i i i个箱。良好的WOE分箱有助于线性模型更好地捕捉变量与目标间的关系。

1.2 评分卡分数标度校准

评分卡常定义三个参数:基准分数P0、对应Odds0、PDO(分数翻倍点)。

  • 基准Odds O d d s 0 = P ( D = 0 ) P ( D = 1 ) Odds_0 = \frac{P(D=0)}{P(D=1)} Odds0=P(D=1)P(D=0)(开发样本中好/坏的比值)
  • 基准分数 S c o r e 0 Score_0 Score0,如600分
  • PDO:分数每变化PDO,Odds翻倍(或减半)

由此,可推导:

A = S c o r e 0 + B × ln ⁡ O d d s 0 A = Score_0 + B \times \ln Odds_0 A=Score0+B×lnOdds0
B = − P D O ln ⁡ 2 B = -\frac{PDO}{\ln 2} B=ln2PDO

评分与log odds关联:

S c o r e = A + B × ln ⁡ p ( x ) 1 − p ( x ) Score = A + B \times \ln\frac{p(x)}{1-p(x)} Score=A+B×ln1p(x)p(x)

1.3 自变量区间赋分

在线性回归或逻辑回归中,变量贡献为系数 β \beta β与WOE乘积。因此,分箱 i i i的部分分数(partial score)为:

S c o r e i = − B × β × W O E i Score_i = -B\times\beta\times WOE_i Scorei=B×β×WOEi

将所有变量各箱得分相加并加上常数项 A A A,即可得到最终客户评分。

Python示例:计算单变量分箱WOE并生成部分分数
import numpy as np
import pandas as pd

def calc_woe(df, feature, target, bins):
    df['bin'] = pd.cut(df[feature], bins=bins)
    agg = df.groupby('bin')[target].agg(['count', 'sum'])
    agg.columns = ['total', 'bad']
    agg['good'] = agg['total'] - agg['bad']
    agg['dist_bad'] = agg['bad'] / agg['bad'].sum()
    agg['dist_good'] = agg['good'] / agg['good'].sum()
    agg['woe'] = np.log(agg['dist_good'] / agg['dist_bad'])
    return agg

# 示例:
aggr = calc_woe(df, 'age', 'is_bad', bins=[18,25,35,45,55,65,100])
aggr['part_score'] = -B * beta_age * aggr['woe']

二、特征稳定性指标CSI

2.1 CSI定义

CSI衡量当前样本与开发样本在分箱后的分数分布及其对最终总分影响:

CSI = ∑ i ( p i c u r r − p i d e v ) × S c o r e i \text{CSI} = \sum_i (p_i^{curr} - p_i^{dev}) \times Score_i CSI=i(picurrpidev)×Scorei

  • p i c u r r p_i^{curr} picurr:当前监控窗口第 i i i箱占比
  • p i d e v p_i^{dev} pidev:开发样本第 i i i箱占比
  • S c o r e i Score_i Scorei:第 i i i箱的部分分数

2.2 CSI计算步骤

  1. 对模型输入变量或模型输出分箱
  2. 计算开发样本与当前样本各箱占比
  3. 读取对应箱的部分分数
  4. 按公式累加计算

2.3 CSI的业务解读

  • 正负方向:正值表示当前客户群倾向更高分段,负值则向低分段漂移
  • 绝对值:值越大,表示该特征对总分偏移影响越显著

三、PSI与CSI的区别与联系

属性PSI(群体)CSI(特征)
分析层级模型得分层单个特征分数层
公式差异 ∑ ( p i c u r r − p i d e v ) ln ⁡ p i c u r r p i d e v \sum(p_i^{curr}-p_i^{dev}) \ln\frac{p_i^{curr}}{p_i^{dev}} (picurrpidev)lnpidevpicurr ∑ ( p i c u r r − p i d e v ) × S c o r e i \sum(p_i^{curr}-p_i^{dev}) \times Score_i (picurrpidev)×Scorei
阈值标准通用经验阈值(<0.1稳定,0.1~0.25轻度偏移,>0.25需关注)无统一阈值,需结合业务与得分尺度评估
作用范围宏观监控模型整体稳定性微观识别单变量波动来源

实践建议:优先以PSI判断模型得分稳定性,再结合CSI定位具体特征波动原因。

附:完整Python实现示例

import numpy as np, pandas as pd

def calc_psi(ods, exp, bins):
    ods['bin'] = pd.cut(ods['score'], bins=bins)
    exp['bin'] = pd.cut(exp['score'], bins=bins)
    odf = ods['bin'].value_counts(normalize=True).sort_index()
    edf = exp['bin'].value_counts(normalize=True).sort_index()
    psi = ((odf - edf) * np.log(odf/edf)).sum()
    return psi

def calc_csi(curr, dev, part_scores, bins):
    curr['bin'] = pd.cut(curr['score'], bins=bins)
    dev['bin'] = pd.cut(dev['score'], bins=bins)
    pc = curr['bin'].value_counts(normalize=True).sort_index()
    pdv = dev['bin'].value_counts(normalize=True).sort_index()
    return ((pc - pdv) * part_scores).sum()

# 示例调用:
bins = np.linspace(300,900,12)
psi_value = calc_psi(current_df, dev_df, bins)
csi_value = calc_csi(current_df, dev_df, part_scores, bins)
print(f"PSI={psi_value:.3f}, CSI={csi_value:.3f}")
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

油泼辣子多加

感谢大佬!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值