风控模型指标PSI详细理解

文章介绍了在风控模型中,PSI作为衡量模型稳定性的重要指标,以及其计算方法。PSI通过比较历史样本分布与未来样本分布的偏差来评估稳定性。同时,文章还讨论了与PSI密切相关的KL散度,它是衡量两个概率分布差异的非对称性度量。在代码实现部分,展示了如何计算PSI值,并给出了模型稳定性的一般判断标准。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.模型稳定性

在风控模型领域,PSI(Population Stability Index)是个常见的指标,用来描述模型/特征的稳定性。因为在金融领域,稳定是个特别重要的要求,模型/特征的更新频率,比起搜广推这种业务场景来也慢很多很多。像风控模型这种,更新频率至少是按季度起算,按年算也非常常见。因此,模型上线前后的稳定性就是个特别重要的指标。

我们在建模时,模型/特征的稳定性一般可以这么衡量:
模型或特征稳定性 == 历史样本分布与未来样本分布的偏差大小。

如果历史样本分布与未来样本分布偏差小,我们就可以认为模型的稳定性较好没有比较大的偏差,反制亦然。

当然在实际情况中,未来样本的分布,总是在不断变化的。互联网各种场景中,用户的变化都非常快。举个很实际的例子,大部分做贷款业务的互金公司,包括传统的银行,在20年用户都发生了重大变化,大家的逾期率普遍都提升了很多,原因大家也都清楚,就是因为疫情的黑天鹅事件。

2.PSI的计算方法

训练模型的时候,我们一般可以把训练数据作为历史样本(actual),验证数据作为未来样本(expected),那么PSI的计算公式如下:
P S I = ∑ i = 1 n ( A i − E i ) ∗ l n A i E i PSI = \sum_{i=1} ^n (A_i - E_i) * ln \frac{A_i}{E_i} PSI=i=1n(AiEi)lnEiAi

参考文献1种提到PSI值可以这样理解:
PSI = SUM( (实际占比 - 预期占比)* ln(实际占比 / 预期占比) )

这么理解就更为直观,是一种加深理解的好方法。

3.KL散度(相对熵)

说到PSI,一般都会提到KL散度,因为这两长得就很像,各种藕断丝连的关系。
KL散度(Kullback-Leibler divergence,简称KLD),在讯息系统中称为相对熵(relative entropy),在连续时间序列中称为随机性(randomness),在统计模型推断中称为讯息增益(information gain)。也称讯息散度(information divergence)。

KL散度是两个几率分布P和Q差别的非对称性的度量。 KL散度是用来度量使用基于Q的分布来编码服从P的分布的样本所需的额外的平均比特数。典型情况下,P表示数据的真实分布,Q表示数据的理论分布、估计的模型分布、或P的近似分布。(参考文献2)

D K L ( P ∣ ∣ Q ) = − ∑ p i l n q i p i D_{KL}(P||Q) = -\sum p_i ln\frac{q_i}{p_i} DKL(P∣∣Q)=pilnpiqi

也可以等价于
D K L ( P ∣ ∣ Q ) = ∑ p i l n p i q i D_{KL}(P||Q) = \sum p_i ln\frac{p_i}{q_i} DKL(P∣∣Q)=pilnqipi

如果是连续随机变量,概率分布P和Q可按积分方式定义为
D K L ( P ∣ ∣ Q ) = ∫ − ∞ ∞ p ( x ) l n p ( x ) q ( x ) d ( x ) D_{KL}(P||Q) = \int _{-\infty} ^{\infty} p(x) ln\frac{p(x)}{q(x)} d(x) DKL(P∣∣Q)=p(x)lnq(x)p(x)d(x)

可以对KL散度进行简单进行推导
随机变量X的熵可以表示为:
H ( X ) = − ∑ i p ( x i ) l o g p ( x i ) H(X) = -\sum_i p(x_i) log p(x_i) H(X)=ip(xi)logp(xi)
而对于两个随机变量P, Q,概率分布分别为p(x), q(x),则p与q的交叉熵定义为:
H ( p , q ) = ∑ p ( x ) l o g 1 q ( x ) = − ∑ p ( x ) l o g q ( x ) H(p, q) = \sum p(x) log \frac{1}{q(x)} = -\sum p(x)logq(x) H(p,q)=p(x)logq(x)1=p(x)logq(x)

在信息论中,交叉熵可认为是对预测分布q(x)用真实分布p(x)来进行编码时所需要的信息量大小。

因此,KL散度(相对熵)为:
D K L ( P ∣ ∣ Q ) = H ( p , q ) − H ( p ) = − ∑ p ( x ) l o g q ( x ) − ( − ∑ p ( x ) l o g p ( x ) ) = ∑ p ( x ) l o g p ( x ) q ( x ) \begin{aligned} D_{KL}(P||Q) &= H(p, q) - H(p) \\ &= -\sum p(x)logq(x) - (-\sum p(x)logp(x)) \\ & = \sum p(x) log \frac{p(x)}{q(x)} \end{aligned} DKL(P∣∣Q)=H(p,q)H(p)=p(x)logq(x)(p(x)logp(x))=p(x)logq(x)p(x)

注意KL散度并不是一个真正的度量或者距离,因为它不具有对称性
D K L ( P ∣ ∣ Q ) ≠ D K L ( Q ∣ ∣ P ) D_{KL}(P||Q) \neq D_{KL}(Q||P) DKL(P∣∣Q)=DKL(Q∣∣P)

4.PSI与散度的关系

我们再来看PSI的公式

P S I = ∑ i = 1 n ( A i − E i ) ∗ l n A i E i PSI = \sum_{i=1} ^n (A_i - E_i) * ln \frac{A_i}{E_i} PSI=i=1n(AiEi)lnEiAi

拆开一下
P S I = ∑ i = 1 n A i ∗ l n A i E i + E i ∗ l n E i A i PSI = \sum_{i=1} ^n A_i * ln \frac{A_i}{E_i} + E_i * ln \frac{E_i}{A_i} PSI=i=1nAilnEiAi+EilnAiEi

所以拆开一下,很容易看出来,PSI其实是将A(actual)与E(expected)的KL散度做了一个对称化操作,将两个KL散度进行了相加。

P S I = D K L ( A ∣ ∣ E ) + D K L ( E ∣ ∣ A ) PSI = D_{KL}(A||E) + D_{KL}(E||A) PSI=DKL(A∣∣E)+DKL(E∣∣A)

5.代码实现

上头已经解释了很长时间的理论,下面我们看看具体代码如何实现。

import math

def genData():
    ages = ['<18', '[18,25)', '[25,30)', '[30,40)', '[40,50)', '>50']
    train_all = [190, 370, 550, 140, 160, 130]
    train_target = [90, 70, 50, 40, 60, 80]
    train_target_num = sum(train_target)
    ai_list = [round(ele / train_target_num, 4) for ele in train_target]
    print(ai_list)

    predict_all = [1912, 3705, 5507, 1408, 1603, 1311]
    predict_target = [800, 827, 548, 446, 660, 846]
    predict_target_num = sum(predict_target)
    ei_list = [round(ele / predict_target_num, 4) for ele in predict_target]
    print(ei_list)

    psi_list = [round((ai - ei) * math.log(ai / ei), 6) for ai, ei in zip(ai_list, ei_list)]
    print(psi_list)
    print(sum(psi_list))


genData()

上面的代码,我们模拟一个场景:
将用户的年龄段分为六段,train_target, predict_target分别为响应人群,最后计算PSI值。

最后代码输出

[0.2308, 0.1795, 0.1282, 0.1026, 0.1538, 0.2051]
[0.1938, 0.2004, 0.1328, 0.1081, 0.1599, 0.205]
[0.006465, 0.002302, 0.000162, 0.000287, 0.000237, 0.0]
0.009453000000000001

一般如果PSI值<0.1,我们认为模型/特征稳定性很好,变化不大,可以使用。
如果PSI值>0.25,则认为模型/特征稳定性不行,需要进行更新。

参考文献

1.https://zhuanlan.zhihu.com/p/79682292
2.https://zh.wikipedia.org/wiki/%E7%9B%B8%E5%AF%B9%E7%86%B5
3.https://hsinjhao.github.io/2019/05/22/KL-DivergenceIntroduction/

### 模型评估指标 #### 准确率 准确率是指预测正确的比例,即被正确分类的数据占总数据的比例。对于模型而言,高准确率意味着能够更有效地识别潜在的险事件[^1]。 #### 召回率 召回率衡量的是实际发生的险事件中有多少被成功检测出来。这一比率越高说明漏报的情况越少,在金融领域减少损失至关重要[^2]。 #### F1分数 F1分数综合考量了精确(Precision)和召回率(Recall),它提供了两者之间平衡的一个单一数值表示方法。当面对不平衡类别分布时尤其有用,因为此时单纯依靠准确率可能无法全面反映模型表现[^3]。 #### AUC-ROC曲线下的面积 AUC (Area Under Curve)-ROC (Receiver Operating Characteristic curve) 是一种广泛应用于二元分类器性能评测的方法。该值范围介于0至1之间,理想情况下接近1表明具有良好的区分能力;而靠近0.5则暗示着几乎没有任何判别力[^4]。 ```python from sklearn.metrics import roc_auc_score, f1_score, accuracy_score, recall_score def evaluate_model(y_true, y_pred_proba): auc = roc_auc_score(y_true, y_pred_proba) predictions = [round(value) for value in y_pred_proba] acc = accuracy_score(y_true, predictions) rec = recall_score(y_true, predictions) f1 = f1_score(y_true, predictions) results = { 'Accuracy': round(acc * 100, 2), 'Recall': round(rec * 100, 2), 'F1 Score': round(f1 * 100, 2), 'AUC ROC': round(auc * 100, 2) } return results ``` #### KS统计量 KS 统计量用于测量累积分布函数之间的最大差异,通常用来比较不同评分卡或者概率估计的效果好坏。较高的KS值代表更好的分离效果,有助于判断正负样本间的区别程. #### PSI指数 PSI (Population Stability Index) 主要关注随着时间推移目标群体特征的变化情况。通过计算新旧两期数据间各区间占比变化绝对值得加权求和来量化稳定性水平。较低的PSI得分意味着人群属性较为稳定,反之则提示可能存在漂移现象需要引起重视并采取相应措施调整模型参数或重新训练新的版本以适应最新市场环境特点.
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值