0%

【联邦学习之旅】02 联邦金融评分卡

上一讲我们简单了解了联邦学习,这一讲我们来看看金融领域最常用的评分卡模型,以及如何通过联邦学习有效提高模型效果。

评分卡简介

不夸张的说,有风险控制的地方就有评分卡,一是效果好,二是可解释性强。评分卡按照使用阶段分为申请卡、行为卡、催收卡,也就是常说的 ABC 卡:

  1. A卡(Application scorecard)申请评分卡(贷前):给用户的质量评分,目标是排除信用不良客户和非目标客户
  2. B卡(Behavior score card)行为评分卡(贷中):给用户的未来的信贷评分,目标是发现更有潜力的客户
  3. C卡(Collection scorecard)催收评分卡(贷后):给用户是否会对特定催收方式反映评分,目标是找到最有效的催收方式

那么如何去开发评分卡模型呢,一般来说需要如下几个步骤:

  1. 数据获取:第一方数据 + 第三方数据
  2. 探索性数据分析:获取数据大致情况,如缺失值、异常值、平均值、中位数、最大值、最小值、分布情况等,为数据预处理方案提供数据支持
  3. 数据预处理:数据清洗 + 变量分箱 + WOE 编码
    1. 无监督分箱:等频、等距、聚类
    2. 有监督分箱:Split 分箱、Merge 分箱、Chimerge 分箱
    3. 特征分箱的优势
      1. 有效处理缺失值和异常值
      2. 数据和模型更加稳定
      3. 简化逻辑回归模型,降低过拟合,提高泛化能力
      4. 所有的特征统一转化为类别型变量
      5. 分箱后的变量才可以使用评分卡的模式
    4. WOE 编码的优势
      1. 提升模型的预测效果
      2. 将自变量规范到同一尺度
      3. 反应自变量取值的贡献情况
      4. 有利于对变量的每个分箱进行评分
      5. 转化为连续变量后,便于分析变量间的相关性
      6. 与 OneHot 相比,可以保证变量的完整性,同时避免稀疏矩阵和维度灾难
  4. 变量筛选:评分卡所用字段在 30 个以下
    1. 考虑因素
      1. 变量的预测能力
      2. 变量之间的线性相关性
      3. 变量的简单性(容易生成和使用)
      4. 变量的强壮性(不容易被绕过)
      5. 变量的可及时性
    2. 单变量的筛选基于变量的预测能力,常用方法:
      1. 基于 IV 值的变量筛选,IV 值越大,则预测能力越强
      2. 基于 stepwise 的变量筛选
        1. 前向选择 forward: 逐步将变量一个一个放入模型,并计算相应指标,符合则保留,不符合则丢掉
        2. 后向选择 backward: 一开始将全部变量纳入模型,然后不断移除不符合条件的变量
        3. 逐步选择 stepwise: 逐步放入最优的变量、移除最差的变量
      3. 基于特征重要度的变量筛选:就是基于 GBDT 构造树得到特征重要性(偏机器学习)
      4. 基于 LASSO 正则化的变量筛选
    3. 变量间如果有较强线性相关(皮尔森相关系数 0.7/0.4),则删除 IV 值较低的,或分箱严重不均衡的变量
    4. 意义
      1. 剔除跟目标变量不太相关的特征
      2. 消除线性相关变量,避免特征冗余
      3. 减轻后期验证、部署、监控的负担
      4. 保证变量的可解释性
  5. 模型开发:一般就用逻辑回归模型(简单稳定,可解释性强,技术成熟,易于监测和部署)
    1. 根据 p-value 进行筛选,阈值一般是 0.05,大于该值则删除此变量
    2. 检查各个变量的系数,如果都是正数则正常,如果有负数则说明有一些自变量的线性相关性较强,需要进一步筛选,具体方法为
      1. 综合考虑变量的 IV 值和业务的建议,按照优先级降序排列
      2. 选择优先级最高的 4-5 个基本变量
      3. 按照优先级从高到低逐渐添加,添加到系数为负的变量,则舍弃
    3. WOE 编码一定和结果成正比,所以理想情况下一定是正数
  6. 模型评估
    1. AUC、KS、Lift、Gain、PSI、VIS
  7. 生成评分卡

分箱这一步里有两个很重要的公式,一个是 WOE(Weight of Evidence),另一个是 IV(Information Value),其中 $B_i =第 i 组的坏客户数量, B_T=坏客户总数量$, $G_i =第 i 组的好客户数量, G_T =好客户总数量$ 具体如下:

$$WOE_i=ln ( \frac{B_i / B_T}{G_i / G_T})$$ $$IV = \sum_{i=1}^{N}IV_i \\ IV_i=(\frac{B_i}{B_T} - \frac{G_i}{G_T})*WOE_i$$

通过公式可知,WOE 越大,越能能区分好坏用户,而 IV 实际上是 WOE 的加权求和(消除掉各分组中数量差异带来的误差)。我们可以根据每个变量 IV 值的大小排序,越大的越应该保留。IV 值范围参考:

  • < 0.02: 没有预测能力
  • 0.02~0.1: 预测能力弱
  • 0.1~0.3: 预测能力中等
  • 0.3~0.5: 预测能力强

好了,前面说了那么多,大家可能也已经晕了,接下来直接来看一个经典的例子,就全都明白了。

非联邦评分卡

数据源来自 Kaggle: Give Me Some Credit,一共有 25 万条个人财务情况数据,我们的目标是构建一个模型,来预测用户违约的可能性。具体的代码在 这里 中。

我们可以通过 pandas 的 info 函数了解数据集的大致情况,这里我们有 15 万训练数据,10 万测试数据,具体的字段如下:

  • SeriousDlqin2yrs:好坏客户,1 是坏客户
  • RevolvingUtilization Of UnsecuredLines:具体的定义比较绕,简单来说就是纯信用额度/可用额度的比值,这里的纯信用指的是去掉不动产和车贷这类有抵押的贷款
  • age:借款人年龄
  • NumberOfTime30-59DaysPastDueNotWorse:30-59天逾期次数
  • DebtRatio:负债比例
  • MonthlyIncome:月收入
  • NumberOfOpenCreditLinesAndLoans:开放式信贷和贷款数量
  • NumberOfTimes90DaysLate:90天逾期次数:借款者有90天或更高逾期的次数
  • NumberRealEstateLoansOrLines:不动产贷款或额度数量:抵押贷款和不动产放款包括房屋净值信贷额度
  • NumberOfTime60-89DaysPastDueNotWorse:60-89天逾期次数
  • NumberOfDependents:家属数量,不包括本人在内的家属数量

缺失值处理

为了便于理解,我们在 replace_header 函数中将表头替换成中文,接着通过 data_overview 函数对数据有一个大致的了解,最后通过 missing_analysis 函数查看缺失比例。

不查不知道一查吓一跳,【月收入】缺失比: 19.82%,【家属数量】缺失比: 2.62%,所以我们需要处理一下。缺失值的类型一般分为完全随机缺失、随机缺失、非随机缺失(其实不太好判断),而对应的处理方法就简单很多,要么补,要么删。删除比较简单粗暴不提,补的话有如下几种方法:

  1. 均值插补
  2. 同类均值插补
  3. 极大似然估计
  4. 多重插补

代码中会在 missing_process 函数中通过不同 mode 来切换不同的插值方式,并在最后比较不同方法的不同效果。

异常值处理

现在我们的数据中没有缺失值了,下一步需要处理的是异常值,所谓异常值其实就是明显偏离数据分布的值,一般的评判标准是大于 3 倍标准差(基于正态分布)。也有一些统计值可以根据常识来进行判断(比如年龄,子女数量等)。我们先来看看基于标准差的过滤方法,具体公式如下:

$$x_i > Q3 + k(IQR) \ or \ x_i < Q1 - k(IQR) \\ where\ IQR = Q3 - Q1\ and\ k \ge 0$$

这里我们先用这个公式来过滤异常值,其他方法在代码中进行尝试,同样通过 mode 来切换,具体看函数 abnormal_process

另外比如年龄为 0 的值,也可以认为是异常,我们通常采用离群值检测的方法来进行(画出箱线图)

探索性分析

经过前面的处理,我们需要再次确认各个特征变量是否满足统计基本假设,分别绘制直方图进行查看,具体看函数 eda_process(中文无法显示可以参考 这里),总体来说就是简单验证一下。

变量选择

这里就要用到前面说的 IV 值和 WOE 了,WOE 是对原始自变量的一种编码形式,而需要进行 WOE 编码,就必须要对变量做分箱处理,即进行离散化的过程。分箱有很多种方式(前面有介绍),这里我们针对连续型变量采用最优分箱(Optimal Binning),是一种基于条件推断查找较佳分箱的方法;针对不能使用最优分段的变量采用等频分箱。具体参考函数 binning_op, qcut_opget_woe_iv

这里需要注意的是,各个变量分箱后 WOE 应该呈现一个单调的趋势,如果不是,则需要能够以常理解释(比如年龄)。

全部计算出来后,就可以对每个变量的 iv 值求和,最后输出图像进行观察,具体参考函数 get_woe_iv。最后我们打印出 iv 值小于 0.1 的变量,可以看情况进行过滤(因为本身维度就很低,这里暂时不处理),就可以进入模型训练的部分了。

模型训练

数据处理完成之后,模型训练就比较简单了,直接通过 scikit-learn 构建 LR 模型即可。具体参考 build_model 函数,我们在测试数据上验证,得到 0.85 的 auc 54 的 ks,说明模型是有效的(很多文章用的是 statsmodels 这个包,但是我不熟悉,就不用)。

构造评分卡

接下来我们需要根据 LR 模型的结果,来构造评分卡,这部分因为我之前没怎么接触过,所以会写得详细一些。

我们前面得到的 LR 模型预估的其实是一个用户违约的概率 p,我们构造一个 Odds 变量(称为比率),公式为 $Odds = \frac{p}{1-p}$,评分卡的得分公式定义为 Odds 对数的线性函数,其中 A 和 B 是常数,具体公式如下:

因为是减去基于违约概率的值,所以违约概率越高,总分数越低。所以现在的问题就是 Odds 的计算,具体公式如下:

$$log(Odds)=\beta_0+\beta_1x_1+···+\beta_px_p$$

这里的 $\beta$ 由 LR 模型拟合得到,那么剩下的问题就变成,A(补偿)和 B(刻度)要如何确定。通常我们的假设是:

  1. 在某个特定比率设定特定的预期分值 $P_0$
  2. 指定比率翻倍的分数(PDO, Point-to-Double Odds),每高 PDO 个分数,好坏高一倍

设比率为 $\theta_0$ 的时候分值为 $P_0$,比率为 $2\theta_0$(这就是翻倍) 的时候分值为 $P_0-PDO$,那么对应公式为:

$$P_0=A-B*log(\theta_0) \\ P_0 - PDO = A - B*log(2\theta_0)$$

解方程可得:

$$B = \frac{PDO}{log(2)} \\ A = P_0+B*log(\theta_0)$$

举个例子,假设我们想要让比率为 1:60(违约:正常) 时对应分支为 600 分,且 PDO = 20,那么带入上面的公式就可以得到 $B=\frac{20}{log(2)}=66.439$,以及 $A=600+66.439*log(1/60)=481.861$。最终评分卡的分值公式如下:

$$Score = A - B(\beta_0+\beta_1x_1+···+\beta_px_p)$$

这里的 x 对应各个自变量的 WOE,转化后公式可以记为

$$ \begin{aligned} & Score = (A-B\beta_0) \\ & -(B\beta_1\omega_{11})\delta_{11}-(B\beta_1\omega_{11})\delta_{12}-··· \\ & - ··· \\ & - (B\beta_p\omega_{p1})\delta_{p1}-(B\beta_p\omega_{p1})\delta_{p2}-··· \\ & \omega_{ij} 是第 i 个变量对应第 j 个类别上的 WOE \\ & \delta_{ij} 是二元变量,表示变量 i 是否取第 j 个值 \\ & A-B\beta_0 是基础得分,下面每一行是对应 x_1,...,x_p 的得分 \end{aligned} $$

有了这个公式,我们就可以去创建评分卡了,具体参考 generate_card 函数。

注:这里不贴代码就是希望大家能去看看代码,不然很难领会到精髓。

联邦评分卡

了解了如何在集中数据上构建评分卡之后,我们就可以通过联邦的方式来利用不同数据进一步提升评分卡的效果了。

在 FATE 1.5 中,已经包含了一个评分卡的例子,其中使用到的数据是 default_credit_hetero_guest,我们先来运行一下(需要配置 FATE 环境,不赘述),然后再看看和前面的非联邦评分卡有什么不同。

运行完成之后,我们可以在 FateBoard 上看到具体的结果,实际上和我们前面生成评分卡的步骤略有不同,是直接根据 LR 的概率来具体评分的,核心代码如下:

1
2
odds = (1 - predict_score) / predict_score
credit_score = offset + factor / np.log(factor_base) * np.log(odds)

变量含义:

  • offset 表示基础分值,也就是上面公式的 A,在这里默认为 500
  • factor 表示 PDO,即翻倍系数,在这里默认为 20
  • factor_base 表示取 log 的底数

这里我们可以看到代码中的公式和前面的有所不同,主要是因为这里的 odds 实际上分子分母取反,所以最后的分值公式变成了加号,核心逻辑是一样的。于是,我们就可以直接基于概率来得到评分,而不再需要查表得到。

但是这个例子里,缺少了两个重要的步骤,一个是特征工程(因为测试数据集已经完成了清洗和归一化),另一个是模型效果评估,这个是我们后期需要补充上去里的。

更加详细的说明我们会放到后面的系列文章中,这里主要是通过评分卡这一个简单的应用来对比联邦与非联邦的差别。

参考链接