使用PySpark计算AUC,KS与PSI

这篇具有很好参考价值的文章主要介绍了使用PySpark计算AUC,KS与PSI。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

当特征数量或者模型数量很多的时候,使用PySpark去计算相关风控指标会节省很多的时间。网上关于使用PySpark计算相关风控指标的资料较少,尤其是PSI计算不管是国内还是国外相关的代码都没有正确的,这里抛砖引玉,写了三个风控常用的指标AUC,KS和PSI相关的计算方法,供参考。

AUC

AUC的相关概念网上已经有很多的很好的文章,这里不在赘述,AUC使用的到的计算公式如下:

\[AUC=\frac{\sum_{i\in positiveClass}rank_i-{\displaystyle\frac{M(1+M)}2}}{M\times N} \]

其中M为负类样本的数目,N为正类样本的数目

使用PySpark计算代码如下:文章来源地址https://www.toymoban.com/news/detail-659816.html

from pyspark.sql import functions as F
from pyspark.sql.window import Window

true_y_col = 'y'
pred_y_col = 'pred_y'
date_col = 'day'


auc_df = df.filter(F.col(true_y_col)>=0).filter(F.col(pred_y_col)>=0)\
           .select(true_y_col, pred_y_col, date_col, 'model_name')\
           .withColumn('totalbad', F.sum(F.col(true_y_col)).over(Window.patitonBy(date_col, 'model_name').orderBy(F.lit(1))))\
           .withColumn('totalgood', F.sum(1-F.col(true_y_col)).over(Window.patitonBy(date_col, 'model_name').orderBy(F.lit(1))))\
           .withColumn('rnk2', F.row_number().over(Window.partitionBy(date_col, 'model_name').orderBy(F.col(pred_y_col).asc())))\
           .filter(F.col(true_y_col)==1)\
           .groupBy(date_col, 'model_name')\
           .agg(((F.sum(F.col('rnk2'))-0.5*(F.max(F.col('totalbad')))*(1+F.max(F.col('totalbad'))))/(F.max(F.col('totalbad'))*F.max(F.col('totalgood')))).alias('AUC'))\
           .orderBy('model_name', date_col)

KS

KS统计量是基于经验累积分布函数(Empirical Cumulative Distribution Function,ECDF)
建立的,一般定义为:

\[KS=\max\left\{\left|cum\left(bad\_rate\right)-cum\left(good\_rate\right)\right|\right\} \]

即为TPRFPR差值绝对值的最大值。

\[KS=max\left(\left|TPR-FPR\right|\right) \]

KS计算方法有很多种,这里使用的是分箱法分别计算TPRFPR,然后得到KS。
使用PySpark计算代码如下:

from pyspark.sql import functions as F
from pyspark.sql.window import Window

true_y_col = 'y'
pred_y_col = 'pred_y'
date_col = 'day'
nBins = 10

ks_df = df.filter(F.col(true_y_col)>=0).filter(F.col(pred_y_col)>=0)\
          .select(true_y_col, pred_y_col, date_col, 'model_name')\
          .withColumn('Bin', F.ntile(nBins).over(Window.partitionBy(date_col, 'model_name').orderBy(pred_y_col)))\
          .groupBy(date_col, 'model_name', 'Bin').agg(F.sum(true_y_col).alias('N_1'), F.sum(1-F.col(true_y_col)).alias('N-0'))\
          .withColumn('ALL_1', F.sum('N_1').over(Window.partitionBy(date_col, 'model_name')))\
          .withColumn('ALL_0', F.sum('N_0').over(Window.partitionBy(date_col, 'model_name')))\
          .withColumn('SUM_1', F.sum('N_1').over(Window.partitionBy(date_col, 'model_name').orderBy('Bin')))\
          .withColumn('ALL_0', F.sum('N_0').over(Window.partitionBy(date_col, 'model_name').orderBy('Bin')))\
          .withColumn('KSn', F.expr('round(abs(SUM_1/ALL_1-SUM_0/ALL_0),6)'))\
          .withColumn('KS', F.round(F.max('KSn').over(Window.partitionBy(date_col, 'model_name')),6))

ks_df = ks_df.select(date_col, 'model_name', 'KS').filter(col('KS').isNotNull()).dropDuplicates()

PSI

群体稳定性指标(Population Stability Index,PSI)是风控场景常用的验证样本在各分数段的分布与建模样本分布的稳定性。在建模中,常用来筛选特征变量、评估模型稳定性

计算公式如下:

\[psi=\sum_{i=1}^n\left(A_i-E_i\right)\ast\ln\left(A_i/E_i\right) \]

其中\(A_i\)代表的是第i个分箱中实际分布(actual)样本占比,同理\(E_i\)代表的是第i个分箱中预期分布(excepted)样本占比

使用PySpark计算代码如下:

from pyspark.sql import functions as F
from pyspark.sql.window import Window
from pyspark.sql.functions import when


date_col = 'day'
nBins = 10
feature_list = ['fea_1', 'fea_2', 'fea_3']

df = df.withColumn('flag', when(F.col(date_col) == 'actual_date', 0).when(F.col(date_col) == 'excepted_date', 1).otherwise(None)

quantitles = df.filter(F.col('flag') == 0)\
               .approxQuantile(feature_list, [i/nBins for i in range(1, nBins)], 0.001) # 基准样本分箱

quantitles_dict = {col: quantitles[idx] for idx, col in enumerate(feature_list)}
f_quantitles_dict = F.create_map([F.lit(x) if isinstance(x, str) else F.array(*[F.lit(xx) for xx in x]) for i in quantitles_dict.items() for x in i])

unpivotExpr = "stack(3, 'fea_1', fea_1, 'fea_2', fea_2, 'fea_3', fea_3)"

psi_df = df.filter(F.col('flag').isNotNull()).select('flag', F.expr(unpivotExpr))\
           .withColumn('Bin', when(F.col('value').isNull(), 'Missing').otherwise(
            when(F.col('value') < f_quantitles_dict[F.col('varname')][0], 'bin_0')
            .when(F.col('value') < f_quantitles_dict[F.col('varname')][1], 'bin_1')
            .when(F.col('value') < f_quantitles_dict[F.col('varname')][2], 'bin_2')
            .when(F.col('value') < f_quantitles_dict[F.col('varname')][3], 'bin_3')
            .when(F.col('value') < f_quantitles_dict[F.col('varname')][4], 'bin_4')
            .when(F.col('value') < f_quantitles_dict[F.col('varname')][5], 'bin_5')
            .when(F.col('value') < f_quantitles_dict[F.col('varname')][6], 'bin_6')
            .when(F.col('value') < f_quantitles_dict[F.col('varname')][7], 'bin_7')
            .when(F.col('value') < f_quantitles_dict[F.col('varname')][8], 'bin_8')
            .when(F.col('value') < f_quantitles_dict[F.col('varname')][8], 'bin_9')))\
           .groupBy('varname', 'Bin').agg(F.sum('flag').alias('N_1'), F.sum(1-F.col('flag')).alias('N_0'))\
           .withColumn('ALL_1', F.sum('N_1').over(Window.partitionBy('varname')))\
           .withColumn('ALL_0', F.sum('N_0').over(Window.partitionBy('varname')))\
           .withColumn('actual', F.expr('round(N_0/ALL_0, 6)'))\
           .withColumn('excepted', F.expr('round(N_1/ALL_1, 6)'))\
           .withColumn('PSIn', F.expr('round((actual-excepted)*ln(actual/excepted), 6'))\
           .withColumn('PSI', F.round(F.sum('PSIn').over(Window.partitionBy('varname')), 6))

Reference

  • 【风控算法】二、SQL->Python->PySpark计算KS,AUC及PSI
  • 风控模型—区分度评估指标(KS)深入理解应用
  • 风控模型—群体稳定性指标(PSI)深入理解应用

到了这里,关于使用PySpark计算AUC,KS与PSI的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • pyspark 使用udf 进行预测,发现只起了一个计算节点

    PySpark UDF 只使用一个计算节点的问题 原因分析 默认的并行度设置 PySpark在执行UDF(用户定义函数)时,默认可能不会利用所有可用的计算节点。这是因为UDF通常在单个节点上执行,并且如果没有正确设置分区,可能会导致数据倾斜或不平衡的分布。 数据分区不足 如果你的数

    2024年02月01日
    浏览(58)
  • 【论文】模型大小计算方式(或者叫做权重大小/体积?)单位是MB

    搞不懂,论文里面的 模型大小(Modelsize) 到底是啥?感觉各有各的说法 就单纯的网络结构的大小? 那就可以说成是:网络结构定义好了就是一个模型,可用于训练 还是整个权重(网络结构+参数)的大小? 可以说成:整个权重文件包含了网络结构和参数,那么这个训练好的权

    2024年02月05日
    浏览(39)
  • AUC及其意义、判断标准和计算方法 - Python

    AUC及其意义、判断标准和计算方法 - Python 在机器学习中,AUC(Area Under the ROC Curve)是一种常用的评估二元分类器性能的指标,ROC全称为Receiver Operating Characteristic,用于描述敏感性和特异性之间的关系。本文将介绍AUC的意义、判断标准、计算方法以及使用Python进行计算的实现。

    2024年04月11日
    浏览(40)
  • 国内的程序员数量是否已经饱和或者过剩?

    首先,国内程序员数量确实在逐年增加,特别是近年来互联网行业迅猛发展,促进了技术人员需求的增长。然而,要判断程序员是否饱和并不是简单地看人数。下面我们细分几个角度来看看这个问题。 1、合格的程序员数量不够 国内的IT领域和互联网行业发展很快,这也促使

    2024年02月06日
    浏览(50)
  • tf和pytorch每轮epoch显示输出的auc是如何计算的

    tf和pytorch每轮epoch显示输出的auc是如何计算的? 近似 ROC 或 PR 曲线的 AUC(曲线下面积)。 tf1 通过计算真阳性,假阳性,假阴性,真阴性值的计算策略。 tensorflow AUC streaming_auc_我爱写报告的博客-CSDN博客 Tf2通过黎曼和进行计算的。 torcheval.metrics.AUC — TorchEval main documentation (

    2024年02月10日
    浏览(43)
  • 【计算机视觉】特征融合12种经典魔改方法汇总,附配套模型和代码

    特征融合(Feature Fusion)是深度学习中的一种重要技术,它可以帮助模型更好地理解数据的内在结构和规律,提高模型的性能和泛化能力。另外,特征融合还可以提高模型的分类准确率,减少过拟合风险,帮助我们更好地利用数据集。 目前已有的特征融合方法已经取得了显著

    2024年02月03日
    浏览(61)
  • 分类模型评估指标——准确率、精准率、召回率、F1、ROC曲线、AUC曲线

    机器学习模型需要有量化的评估指标来评估哪些模型的效果更好。 本文将用通俗易懂的方式讲解分类问题的混淆矩阵和各种评估指标的计算公式。将要给大家介绍的评估指标有:准确率、精准率、召回率、F1、ROC曲线、AUC曲线。 所有事情都需要评估好坏,尤其是量化的评估指

    2024年02月11日
    浏览(61)
  • 模型构建——使用逻辑回归构建模型,lightGBM进行特征筛选

    新的模型要跟原有方案对比,而且是通过实验证明,特别注意模型和策略不能同时调整。一般实验设计包含以下流程: 问题:业务稳定后,可以去掉人工审核吗? 答 :不可以,一般模型上线后,高分段和低分段的表现较好,但中间段还是需要人工审核;而且即使模型完善后

    2024年02月15日
    浏览(47)
  • 使用TimeSformer预训练模型提取视频特征

    github:GitHub - facebookresearch/TimeSformer: The official pytorch implementation of our paper \\\"Is Space-Time Attention All You Need for Video Understanding?\\\"  直接按照官方步骤安装即可,torchvision在安装pytorch时就一起安装好了,我这里选择安装1.8版本的pytorch,可以根据自己的cuda版本自行选择 pytorch安装:Previ

    2023年04月15日
    浏览(78)
  • Python使用PyQt5实现计算平方或者立方

    此源码为直播时讲解的源码,我加了注释

    2024年02月11日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包