特征漂移指标 PSI

本文介绍了特征漂移指标PSI,用于衡量训练数据与生产数据在分箱分布上的稳定性,以评估模型在新数据环境中的表现。通过计算期望生产和实际数据的分布差异,PSI可用于早期发现模型是否需要重新训练。文章还展示了如何在工程中使用PSI和CSI进行模型稳定性检查,并通过实例演示了ElasticNet回归算法的应用。
摘要由CSDN通过智能技术生成

特征漂移指标 PSI

背景描述

稳定性指的是参与对比两者相同指标差异性很小。机器学习使用训练数据(训练集和验证集)建模,使用测试数据模拟生产环境数据测试模型结果,其建模的假设是:训练数据涵盖了该问题所有的案例数据,即训练数据和测试(生产)数据之间的差异是很小的。

但实际上这个假设是很难成立的,原因:

  1. 受限于数据收集方法,不可能收集到该问题的所有案例数据。
  2. 模型投产后,生产环境的数据随时间会受到自然环境、政策环境、市场环境等影响而发生变化并且不可预知。

模型的输出很可能是决策的依据,如果模型不能适应新数据,这是很大的风险点。因此,监控数据的稳定性并且及时更新模型是一件很重要的事情。

群体稳定性指标

群体稳定指标(Population Stability Index,PSI)反映了验证样本在各分箱段的分布与建模样本分布的稳定性,通常被用来筛选特征变量、评估模型稳定性。计算方法如下所示:

在这里插入图片描述

这里就先遵循拿来主义,“这个公式为什么就能表示稳定性”在此不做深究。下面对公式说一些说明:

A (actual)表示实际分布,即生产数据,E(expected)表示期望分布,即训练数据。期望生产数据尽可能和训练数据的分布一样。i 表示每个分箱。这个公式的意思是:将每个分箱下的生产数据和期望数据做数学计算后再将结果求和

PSI稳定性
0~0.1稳定性很好
0.1~0.2稍微有点不稳定
大于 0.2不稳定,分析生产数据并判断是否要重新训练模型

PSI 代码实现

1.创建模拟数据

size = 5000
# 期望数据
p2 = np.random.normal(loc = 3, scale = 1, size = size)
# 实际数据
a2 = np.random.normal(loc = 3.5, scale = 0.75, size = size)
  1. 计算每个分箱的边界,推荐分箱数位 10-20,此处设置 10 个分箱
num_bins = 10
eps = 1e-4

min_val = min(min(p2), min(a2))
max_val = max(max(a2), max(p2))
bins = [min_val + (max_val - min_val)*(i)/num_bins for i in range(num_bins+1)]
bins[0] = min_val - eps # 修正下界
bins[-1] = max_val + eps # 修正上界

print(bins)
# [-0.4810252475657688, 0.229173950184835, 0.9392731479354388, 1.649372345686043, 2.3594715434366464, 3.0695707411872504, 3.7796699389378547, 4.489769136688458, 5.199868334439062, 5.909967532189666, 6.620166729940269]
  1. 将实际数据和期望数据分箱
# 计算数组总的元素属于哪个分箱
bins_p2 = pd.cut(p2, bins = bins, labels = range(1,num_bins+1))
# 将元素和封箱号对齐
df_p2 = pd.DataFrame({'p2': p2, 'bin': bins_p2})
# 统计每个封箱中的元素数量
grp_p2 = df_p2.groupby('bin').count()
# 计算每个分箱中元素数量占总数的百分比
grp_p2['percent_p2'] = grp_p2['p2'] / sum(grp_p2['p2'])

# 对实际数据也进行分享操作
bins_a2 = pd.cut(a2, bins = bins, labels = range(1,num_bins+1))
df_a2 = pd.DataFrame({'a2': a2, 'bin': bins_a2})
grp_a2 = df_a2.groupby('bin').count()
grp_a2['percent_a2'] = grp_a2['a2'] / sum(grp_a2['a2'])

# 比较 p2 和 a2 的分箱数据
psi_df = grp_p2.join(grp_a2, on = "bin", how = "inner")
print(psi_df)
binp2percent_p2a2percent_a2
1120.00240000.0000
2750.01500330.0006
33380.067614360.0072
49190.1838373090.0618
512970.25945210610.2122
612930.25865218830.3766
77040.14082812230.2446
82780.0556114300.0860
9700.014003540.0108
10130.00260110.0002
  1. 计算各分箱的 psi
# 当 percent_p* 是 0 时,给其加上 eps。防止 0 参与运算抛异常。
psi_df['percent_p2'] = psi_df['percent_p2'].apply(lambda x: eps if x == 0 else x)
psi_df['percent_a2'] = psi_df['percent_a2'].apply(lambda x: eps if x == 0 else x)
# 计算每行的 psi
psi_df['psi'] = (psi_df['percent_p2'] - psi_df['percent_a2']) * np.log(psi_df['percent_p2'] / psi_df['percent_a2'])

print(psi_df)
binp2percent_p2a2percent_a2psi
1120.00240000.00000.007312
2750.01500330.00060.046364
33380.067614360.00720.135310
49190.1838373090.06180.133038
512970.25945210610.21220.009500
612930.25865218830.37660.044313
77040.14082812230.24460.057291
82780.0556114300.08600.013248
9700.014003540.01080.000832
10130.00260110.00020.006158
  1. 各分箱的 psi 求和
psi = psi_df['psi'].sum()

print(psi)
# 0.4533650280982507

通过上述代码实现可以看出:特征漂移实际是在计算预期数据和实际数据的分布差异情况。。

工程中的实际应用:PSI 和 CSI

PSI

以回归算法 ElasticNet() 拟合 y = a1*x1 + a2*x2 + a3*x3 + b 函数为例演示 psi 在工程中的使用。

size = 5000
# 合成训练需要的数据
x1 = np.random.normal(loc = 0, scale = 2, size = size)
x2 = np.random.normal(loc = 3, scale = 1, size = size)
x3 = np.random.normal(loc = 5, scale = 2, size = size)
y = [-2*x1 + 3.1415*x2 + 2.7183*x3 + 1.6180 for (x1, x2, x3) in zip(x1,x2,x3)]

# 划分训练集和验证集
X = pd.DataFrame({'x1': x1, 'x2': x2, 'x3': x3})
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2)

# 训练模型(该模型尽可能拟合出 y = a1*x1 + a2*x2 + a3*x3 + b 表达式)
model = ElasticNet()
model.fit(X_train, y_train)

# 验证结果(模型线下的评测结果)
y_pred = model.predict(X_test)

# 再合成生产环境(线上)数据
z1 = np.random.normal(loc = 0, scale = 2, size = size)  
z2 = np.random.normal(loc = 3.5, scale = 0.75, size = size)  
z3 = np.random.normal(loc = 8, scale = 3, size = size)
# 计算模型的线上推理结果
Z = pd.DataFrame({'x1': z1, 'x2': z2, 'x3': z3})
z_pred = model.predict(Z)

"""
此时线下模型效果 y_pred 和线上模型效果 z_pred 都是一维的,令 p2 = y_pred, a2 = z_pred。
套用“PSI 代码实现部分”就可以计算出群体性稳定指标 PSI,最终判定出模型稳定性处于什么程度。
"""

通过计算 训练模型时的推理结果 和 线上模型的推理结果 的 psi 就能初步得出模型的稳定程度。

CSI

psi 只能宏观判断出模型的稳定程度,如果不稳定,到底是哪些特征引起的不稳定?此时就需要使用特征稳定性指标(CSI)进行判断。计算方式没有什么变化,只是用的数据不一样而已。

上述代码中训练数据特征 x1、x2、x3,线上数据特征 z1、z2、z3。

令 p2 = x1, a2 = z1, 计算出 psi1;
令 p2 = x2, a2 = z2, 计算出 psi2;
令 p2 = x3, a2 = z3, 计算出 psi3;
通过 psi* 就能看出是哪个特征引起的不稳定。

名词解释

  1. 在机器学习中,回归和分类分别适用什么场景?

    归回使用预测值连续的场景。回归问题的目标是找到输入特征与输出值之间的关系,以便能够对未知数据进行预测。房价预测就是个典型的回归问题。分类问题适用于样本划分不同类型的场景。当目标变量是离散的、具有预定义类别的数据时,分类算法被用来预测样本的类别。分类任务的目标是构建一个模型,该模型根据输入特征将样本划分到正确的类型中。垃圾邮件分类就是分类问题。

  2. 模型评价指标已经能判断模型效果了,为什么还要用 psi 判断要不要重新训练模型?

    两种评价的目的不一样,模型指标是判断模型训练的好不好,准确率有多高,能不能投产使用。psi 是模型已经上线了,受环境影响生产中的数据时刻在变化,psi 判断当前模型能不能适应这些变化的数据。psi 还有个作用是用来筛选特征。

参考资料

https://towardsdatascience.com/checking-model-stability-and-population-shift-with-psi-and-csi-6d12af008783

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
机器学习中,漂移指标(Drift Metrics)用于评估模型在不同时间段或不同数据分布上的性能变化。它可以帮助我们监测模型在生产环境中是否存在数据漂移或模型性能的变化。 在 Python 中,你可以使用一些常见的漂移指标来评估模型的性能变化。下面是一些常用的漂移指标: 1. 准确率(Accuracy):用于度量模型在新数据上的分类准确性。当数据分布发生漂移时,准确率可能会下降。 2. AUC-ROC:用于度量二分类模型的性能,计算真正例率(True Positive Rate)和假正例率(False Positive Rate)之间的面积。当数据分布发生漂移时,AUC-ROC 值可能会发生变化。 3. F1 Score:综合考虑了模型的精确率和召回率。当数据分布发生漂移时,F1 Score 可能会发生变化。 4. KL 散度(Kullback-Leibler Divergence):用于衡量两个概率分布之间的差异。当数据分布发生漂移时,KL 散度可能会增加。 5. JS 散度(Jensen-Shannon Divergence):由 KL 散度改进而来,于衡量两个概率分布之间的差异。当数据分布发生漂移时,JS 散度可能会增加。 这些指标可以通过比较模型在不同时间段或数据分布上的性能来检测漂移。你可以使用 Python 中的机器学习库(如 scikit-learn)来计算这些指标。具体的实现方法会根据你的具体问题和数据而有所不同。 希望这些信息对你有帮助!如果你还有其他问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值