白话评分卡 - 开发、验证 与 跨时间验证 以及 模型的应用

针对网友的一些问题,有了这篇文章。主要理一理以下的问题:

1、为什么要把建模数据样本分成 开发、验证 与 跨时间验证 ?

2、开发样本分箱后,如何验证和应用 ?

3、模型的结果如何应用到实际 ?

为什么建模数据样本要分成 开发、验证 与 跨时间验证 ?

评分卡最大的假设是“历史会重演”,也就是过去发现的规律在未来仍然会起作用。所以评分卡主要在研究历史数据,总结历史经验。

如果只是单纯的相信历史会重演,其实就没有必要把建模样本分成3份,直接全部样本数据建模即可。

但是免不了会担心几个问题(人类就是这样创造了某些事情之后,还是充满了怀疑)

1、历史会重演,算法靠谱吗?

2、算法靠谱,历史情况发生改变了,模型还能用吗?

所以针对以上两个最重要的问题,就设置了验证样本和跨时间验证样本。

  • 验证样本的主要作用是验证在开发样本上开发的模型的有效性
  • 跨时间验证样本的作用是经过一段时间后,模型是否仍然有效?

在实际操作中,样本搜集好了之后:

  • 把相对靠近当前时间的样本归入跨时间验证样本;
  • 把剩下的样本按照7:3或者6:4随机分为开发样本以及验证样本。

开发样本分箱后,如何验证和应用 ?
当你开发好了模型/评分卡之后,就要开始验证。为了便于说明,先贴个图:

这个变量分成4组,习惯上缺失值单独一组,其他的按照卡方或者等频或者等宽等方法分出来3组,观察1-3组的Event Rate呈单调性下降,还有,童鞋们一定要问自己一个问题:这种单调性是否符合常识理解或者业务理解。

单调性是否符合常识理解或者业务理解的意思大白话举例:

  • 是不是用户历史购买次数越多,未来复购的可能性越大?
  • 是不是用户越有钱,不还钱的概率越小?
  • ...

如果变量呈现的逻辑和业务常识不一致,只有两种可能:
1、你发现了真理(因为真理掌握在少数人手里);
2、你发现的规律是错误的,即便数据表现如此。

而绝大概率的可能就是第2种:发现真理的确是少数人,但不是你。

好了,言归正传。上面图里面重要的部分就是黄色的部分,代表了同样的分箱规则应用到开发、验证、跨时间样本上的分布情况,也就是每组在不同样本里的占比情况。
如何知道这样的分箱是否可用,必不可少的要验证稳定性。
稳定性一般通过计算PSI来量化确定:

这个公式通过excel翻译一下会更明白:

验证样本与开发样本比较:

跨时间样本与开发样本比较:

计算出来的加总值就是PSI,怎么看:

  • PSI <= 0.1,无差异;
  • 0.1< PSI <= 0.25,需进一步判断;
  • PSI > 0.25,有显著位移,模型需调整。

也就是说,看上面两张图,不管是验证样本还是跨时间样本的分箱的PSI(<0.1)都说明变量稳定,分箱可用。

有童鞋问说每份样本是不是要重复进行分箱的算法操作?答案是不需要。
分箱算法只需要在建模样本上做一次,验证、跨时间样本应用同样分箱规则观察稳定性。文章开头说的:

  • 验证样本的主要作用是验证在开发样本上开发的模型的有效性
  • 跨时间验证样本的作用是经过一段时间后,模型是否仍然有效?

因此,分箱的算法只需要在开发样本上做一次,验证和跨时间样本应用分箱结果就可以了,观察稳定性以及不同样本上的表现。

说白了,各种验证通过之后,上线的也是这个分箱结果的模型。如果新数据都需要重新分箱做一遍,是没有办法用同样口径进行检验的

回到开头的那张图:

不管用什么算法得到的分箱,最后在不同样本的应用规则都是一致的,用伪代码翻译一下:

if 变量A = Missing then do; grp_变量A = '0'; woe_变量A = 0.20027; score_变量A = 83; end;
else if 变量A <= 1 then do; grp_变量A = '1'; woe_变量A = -0.41408; score_变量A = 60; end;
else if 变量A <= 2 then do; grp_变量A = '2'; woe_变量A = -0.0327; score_变量A = 74; end;
else if 变量A > 2 then do; grp_变量A = '3'; woe_变量A = 0.662776; score_变量A = 101; end;

除了验证分箱的变量稳定性外,还可以看看分箱组内的Event Rate的情况和开发时是否一致,不赘述。

模型的结果如何应用到实际 ?

模型开发完,验证通过之后,就涉及到模型应用投产了。咱们一直说的模型,或者大多数的模型,其实最后都是预测概率的体现,不管是以概率本身还是转换成分数的形式。

因为咱们预测的目标变量是0或1的二值型变量,所以概率的意思就是预测0或1的预测概率。

有些童鞋直接套用网上介绍得最多的混淆矩阵 (Confusion Matrix) 方式,直接将预测概率大于0.5的作为预测为1,小于等于0.5的预测为0,和实际表现为0、1做交叉得出预测精度......

这种方式过于简单粗暴,也不实用,更多是在数据竞赛里用简单方式进行了模型评价。

实际上模型做出来之后,更实战的应用方式如下表:

具体的计算公式如下:

什么意思呢?就是把预测概率/分数排序后等频(每组的总人数一样)划分10档(或者划20档、5档都行)。然后看每档的情况:

  • #% 是指组内人数占总体的占比;
    这个好理解,比如全部样本5000人,每组500人,每组占比就是10%

  • non-Event % 是指组内非目标人数占全部非目标人数的占比;

    全部样本5000人,其中非目标人数4500人,某一组中非目标人数900,那么#non-Event % =900 / 4500

  • Event % 是指组内目标人数占全部目标人数的占比;

    全部样本5000人,其中目标人数500人,某一组中目标人数100,那么#Event % =100 / 500

  • KS:MAX ( 每组绝对值 ( 累计非目标#% - 累计目标#%) )
    反映的是模型的区分能力,一般来说这个值越大说明区分效果越好。(最好还是看ROC/AUC,后续有机会再说)

  • KS < 0.2 模型区分能力很弱,越小代表几乎没有

  • 0.2 <= KS < 0.3 有一定区分能力

  • 0.3 <= KS <0.5 区分能力较好

  • 0.5 <= KS <0.75 区分能力强

  • KS > 0.75 一般表示模型异常

这么做的好处是显而易见的:

  • 如果目标变量是市场活动响应人数,那么可以将分数切到市场成本投产比可以接受的格子:
    比如按照上图,可以接受2%以上的响应率,那么格子9、10的用户可以拒绝促动,也就是将来做类似活动的时候不促动9、10格子的用户
  • 如果目标变量是信贷用户坏账人数,那么可以将分数切到坏账成本/对应通过率都可以接受的格子:
    比如按照上图,可以接受5%以内的人数坏账率,那么格子1、2、3的用户可以拒绝掉。

本次内容就这些。谢谢收看。

如果童鞋们有什么问题,请在评论区留言。我会抽时间回复,这样其他童鞋有类似问题也可以看到。

PS:

  • 怎么处理缺失值?
    网上有许多教程是说用众数或者平均数等方式处理缺失值...
    我个人的做法是单独分一类,原因是保证数据的真实有效,因为缺失本身也是一种信息,用各种模拟的方式来处理个人觉得不妥,因为无法验证处理方式好坏。
  • 一定需要跨时间验证样本?
    严格上需要。如果数据样本本身很少,请至少保证有开发样本、验证样本。
  • 数据样本少有什么方法提升?
    常用的有K-fold来解决。
  • 实在是少到没有办法有验证样本?
    额...那么建议不要做模型了,积累好数据才做吧。实在要做?请要做好模型容易失效的准备。另外可以看看模型建立后变量的分布情况和目前的情况是否稳定,如果稳定,那么只能假设(就是猜)说模型可用。