精华内容
下载资源
问答
  • 性能分析功能,在ggplot2中绘制ROC曲线,AUROC,IV,针对二进制分类模型的WOE计算(逻辑,判别分析,svm等)
  • 当前分组WOE的正负,由当前分组响应和未响应的比例,与样本整体响应和未响应的比例的大小关系决定,当前分组的比例小于样本整体比例时,WOE为负,当前分组的比例大于整体比例时,WOE为正,当前分组的比例和整体比例...

    1.IV的用途

    IV的全称是Information Value,中文意思是信息价值,或者信息量。
    我们在用逻辑回归、决策树等模型方法构建分类模型时,经常需要对自变量进行筛选。比如我们有200个候选自变量,通常情况下,不会直接把200个变量直接放到模型中去进行拟合训练,而是会用一些方法,从这200个自变量中挑选一些出来,放进模型,形成入模变量列表。那么我们怎么去挑选入模变量呢?
    挑选入模变量过程是个比较复杂的过程,需要考虑的因素很多,比如:变量的预测能力,变量之间的相关性,变量的简单性(容易生成和使用),变量的强壮性(不容易被绕过),变量在业务上的可解释性(被挑战时可以解释的通)等等。但是,其中最主要和最直接的衡量标准是变量的预测能力。
    “变量的预测能力”这个说法很笼统,很主观,非量化,在筛选变量的时候我们总不能说:“我觉得这个变量预测能力很强,所以他要进入模型”吧?我们需要一些具体的量化指标来衡量每自变量的预测能力,并根据这些量化指标的大小,来确定哪些变量进入模型。IV就是这样一种指标,他可以用来衡量自变量的预测能力。类似的指标还有信息增益、基尼系数等等。

    2.对IV的直观理解

    从直观逻辑上大体可以这样理解“用IV去衡量变量预测能力”这件事情:我们假设在一个分类问题中,目标变量的类别有两类:Y1,Y2。对于一个待预测的个体A,要判断A属于Y1还是Y2,我们是需要一定的信息的,假设这个信息总量是I,而这些所需要的信息,就蕴含在所有的自变量C1,C2,C3,……,Cn中,那么,对于其中的一个变量Ci来说,其蕴含的信息越多,那么它对于判断A属于Y1还是Y2的贡献就越大,Ci的信息价值就越大,Ci的IV就越大,它就越应该进入到入模变量列表中。

    3.IV的计算

    前面我们从感性角度和逻辑层面对IV进行了解释和描述,那么回到数学层面,对于一个待评估变量,他的IV值究竟如何计算呢?为了介绍IV的计算方法,我们首先需要认识和理解另一个概念——WOE,因为IV的计算是以WOE为基础的。

    3.1WOE

    WOE的全称是“Weight of Evidence”,即证据权重。WOE是对原始自变量的一种编码形式。
    要对一个变量进行WOE编码,需要首先把这个变量进行分组处理(也叫离散化、分箱等等,说的都是一个意思)。分组后,对于第i组,WOE的计算公式如下:

    从直观逻辑上大体可以这样理解“用IV去衡量变量预测能力”这件事情:我们假设在一个分类问题中,目标变量的类别有两类:Y1,Y2。对于一个待预测的个体A,要判断A属于Y1还是Y2,我们是需要一定的信息的,假设这个信息总量是I,而这些所需要的信息,就蕴含在所有的自变量C1,C2,C3,……,Cn中,那么,对于其中的一个变量Ci来说,其蕴含的信息越多,那么它对于判断A属于Y1还是Y2的贡献就越大,Ci的信息价值就越大,Ci的IV就越大,它就越应该进入到入模变量列表中。

    3.IV的计算

    前面我们从感性角度和逻辑层面对IV进行了解释和描述,那么回到数学层面,对于一个待评估变量,他的IV值究竟如何计算呢?为了介绍IV的计算方法,我们首先需要认识和理解另一个概念——WOE,因为IV的计算是以WOE为基础的。

    3.1WOE

    WOE的全称是“Weight of Evidence”,即证据权重。WOE是对原始自变量的一种编码形式。
    要对一个变量进行WOE编码,需要首先把这个变量进行分组处理(也叫离散化、分箱等等,说的都是一个意思)。分组后,对于第i组,WOE的计算公式如下:
    在这里插入图片描述
    其中,pyi是这个组中响应客户(风险模型中,对应的是违约客户,总之,指的是模型中预测变量取值为“是”或者说1的个体)占所有样本中所有响应客户的比例,pni是这个组中未响应客户占样本中所有未响应客户的比例,#yi是这个组中响应客户的数量,#ni是这个组中未响应客户的数量,#yT是样本中所有响应客户的数量,#nT是样本中所有未响应客户的数量。
    从这个公式中我们可以体会到,WOE表示的实际上是“当前分组中响应客户占所有响应客户的比例”和“当前分组中没有响应的客户占所有没有响应的客户的比例”的差异。
    对这个公式做一个简单变换,可以得到:

    在这里插入图片描述
    变换以后我们可以看出,WOE也可以这么理解,他表示的是当前这个组中响应的客户和未响应客户的比值,和所有样本中这个比值的差异。这个差异是用这两个比值的比值,再取对数来表示的。WOE越大,这种差异越大,这个分组里的样本响应的可能性就越大,WOE越小,差异越小,这个分组里的样本响应的可能性就越小。
    关于WOE编码所表示的意义,大家可以自己再好好体会一下。

    3.2 IV的计算公式

    有了前面的介绍,我们可以正式给出IV的计算公式。对于一个分组后的变量,第i 组的WOE前面已经介绍过,是这样计算的:

    在这里插入图片描述

    同样,对于分组i,也会有一个对应的IV值,计算公式如下:
    在这里插入图片描述
    有了一个变量各分组的IV值,我们就可以计算整个变量的IV值,方法很简单,就是把各分组的IV相加:

    在这里插入图片描述

    其中,n为变量分组个数。

    3.3.1 实例

    假设我们需要构建一个预测模型,这个模型是为了预测公司的客户集合中的每个客户对于我们的某项营销活动是否能够响应,或者说我们要预测的是客户对我们的这项营销活动响应的可能性有多大。假设我们已经从公司客户列表中随机抽取了100000个客户进行了营销活动测试,收集了这些客户的响应结果,作为我们的建模数据集,其中响应的客户有10000个。另外假设我们也已经提取到了这些客户的一些变量,作为我们模型的候选变量集,这些变量包括以下这些(实际情况中,我们拥有的变量可能比这些多得多,这里列出的变量仅仅是为了说明我们的问题):

    1. 最近一个月是否有购买;
    2. 最近一次购买金额;
    3. 最近一笔购买的商品类别;
    4. 是否是公司VIP客户;
      假设,我们已经对这些变量进行了离散化,统计的结果如下面几张表所示。
      (1) 最近一个月是否有过购买:
      在这里插入图片描述

    (2) 最近一次购买金额:
    在这里插入图片描述
    (3) 最近一笔购买的商品类别:

    在这里插入图片描述
    (4) 是否是公司VIP客户:

    在这里插入图片描述
    3.3.2 计算WOE和IV

    我们以其中的一个变量“最近一次购买金额”变量为例:
    在这里插入图片描述
    在这里插入图片描述

    我们把这个变量离散化为了4个分段:<100元,[100,200),[200,500),>=500元。首先,根据WOE计算公式,这四个分段的WOE分别为:

    在这里插入图片描述
    插播一段,从上面的计算结果中我们可以看一下WOE的基本特点:

    1. 当前分组中,响应的比例越大,WOE值越大;
    2. 当前分组WOE的正负,由当前分组响应和未响应的比例,与样本整体响应和未响应的比例的大小关系决定,当前分组的比例小于样本整体比例时,WOE为负,当前分组的比例大于整体比例时,WOE为正,当前分组的比例和整体比例相等时,WOE为0。
    3. WOE的取值范围是全体实数。

    我们进一步理解一下WOE,会发现,WOE其实描述了变量当前这个分组,对判断个体是否会响应(或者说属于哪个类)所起到影响方向和大小,当WOE为正时,变量当前取值对判断个体是否会响应起到的正向的影响,当WOE为负时,起到了负向影响。而WOE值的大小,则是这个影响的大小的体现。
    好,回到正题,计算完WOE,我们分别计算四个分组的IV值:
    在这里插入图片描述
    再插播一段,从上面IV的计算结果我们可以看出IV的以下特点:

    1. 对于变量的一个分组,这个分组的响应和未响应的比例与样本整体响应和未响应的比例相差越大,IV值越大,否则,IV值越小;
    2. 极端情况下,当前分组的响应和未响应的比例和样本整体的响应和未响应的比例相等时,IV值为0;
    3. IV值的取值范围是[0,+∞),且,当当前分组中只包含响应客户或者未响应客户时,IV = +∞。
      OK,再次回到正题。最后,我们计算变量总IV值:
      在这里插入图片描述

    3.3.3 IV值的比较和变量预测能力的排序

    我们已经计算了四个变量中其中一个的WOE和IV值。另外三个的计算过程我们不再详细的说明,直接给出IV结果。

    1. 最近一个月是否有过购买:0.250224725
    2. 最近一笔购买的商品类别:0.615275563
    3. 是否是公司VIP客户:1.56550367

    前面我们已经计算过,最近一次购买金额的IV为0.49270645
    这四个变量IV排序结果是这样的:是否是公司VIP客户 > 最近一笔购买的商品类别 > 最近一次购买金额 > 最近一个月是否有过购买。我们发现“是否是公司VIP客户”是预测能力最高的变量,“最近一个月是否有过购买”是预测能力最低的变量。如果我们需要在这四个变量中去挑选变量,就可以根据IV从高到低去挑选了。
    4.关于IV和WOE的进一步思考

    4.1 为什么用IV而不是直接用WOE

    从上面的内容来看,变量各分组的WOE和IV都隐含着这个分组对目标变量的预测能力这样的意义。那我们为什么不直接用WOE相加或者绝对值相加作为衡量一个变量整体预测能力的指标呢?
    并且,从计算公式来看,对于变量的一个分组,IV是WOE乘以这个分组响应占比和未响应占比的差。而一个变量的IV等于各分组IV的和。如果愿意,我们同样也能用WOE构造出一个这样的一个和出来,我们只需要把变量各个分组的WOE和取绝对值再相加,即(取绝对值是因为WOE可正可负,如果不取绝对值,则会把变量的区分度通过正负抵消的方式抵消掉):
    在这里插入图片描述
    其中n为变量分组个数。
    那么我们为什么不直接用这个WOE绝对值的加和来衡量一个变量整体预测能力的好坏,而是要用WOE处理后的IV呢。
    我们这里给出两个原因。IV和WOE的差别在于IV在WOE基础上乘以的那个在这里插入图片描述,我们暂且用pyn来代表这个值。
    第一个原因,当我们衡量一个变量的预测能力时,我们所使用的指标值不应该是负数,否则,说一个变量的预测能力的指标是-2.3,听起来很别扭。从这个角度讲,乘以pyn这个系数,保证了变量每个分组的结果都是非负数,你可以验证一下,当一个分组的WOE是正数时,pyn也是正数,当一个分组的WOE是负数时,pyn也是负数,而当一个分组的WOE=0时,pyn也是0。
    当然,上面的原因不是最主要的,因为其实我们上面提到的在这里插入图片描述这个指标也可以完全避免负数的出现。
    更主要的原因,也就是第二个原因是,乘以pyn后,体现出了变量当前分组中个体的数量占整体个体数量的比例,对变量预测能力的影响。怎么理解这句话呢?我们还是举个例子。
    假设我们上面所说的营销响应模型中,还有一个变量A,其取值只有两个:0,1,数据如下:
    在这里插入图片描述
    我们从上表可以看出,当变量A取值1时,其响应比例达到了90%,非常的高,但是我们能否说变量A的预测能力非常强呢?不能。为什么呢?原因就在于,A取1时,响应比例虽然很高,但这个分组的客户数太少了,占的比例太低了。虽然,如果一个客户在A这个变量上取1,那他有90%的响应可能性,但是一个客户变量A取1的可能性本身就非常的低。所以,对于样本整体来说,变量的预测能力并没有那么强。我们分别看一下变量各分组和整体的WOE,IV。

    在这里插入图片描述
    从这个表我们可以看到,变量取1时,响应比达到90%,对应的WOE很高,但对应的IV却很低,原因就在于IV在WOE的前面乘以了一个系数在这里插入图片描述,而这个系数很好的考虑了这个分组中样本占整体样本的比例,比例越低,这个分组对变量整体预测能力的贡献越低。相反,如果直接用WOE的绝对值加和,会得到一个很高的指标,这是不合理的。

    4.2 IV的极端情况以及处理方式

    IV依赖WOE,并且IV是一个很好的衡量自变量对目标变量影响程度的指标。但是,使用过程中应该注意一个问题:变量的任何分组中,不应该出现响应数=0或非响应数=0的情况。
    原因很简单,当变量一个分组中,响应数=0时,

    在这里插入图片描述

    此时对应的IVi为+∞。
    而当变量一个分组中,没有响应的数量 = 0时,
    在这里插入图片描述

    此时的IVi为+∞。

    IVi无论等于负无穷还是正无穷,都是没有意义的。
    由上述问题我们可以看到,使用IV其实有一个缺点,就是不能自动处理变量的分组中出现响应比例为0或100%的情况。那么,遇到响应比例为0或者100%的情况,我们应该怎么做呢?建议如下:

    (1)如果可能,直接把这个分组做成一个规则,作为模型的前置条件或补充条件;
    (2)重新对变量进行离散化或分组,使每个分组的响应比例都不为0且不为100%,尤其是当一个分组个体数很小时(比如小于100个),强烈建议这样做,因为本身把一个分组个体数弄得很小就不是太合理。
    (3)如果上面两种方法都无法使用,建议人工把该分组的响应数和非响应的数量进行一定的调整。如果响应数原本为0,可以人工调整响应数为1,如果非响应数原本为0,可以人工调整非响应数为1。

    注:原文出自:https://blog.csdn.net/kevin7658/article/details/50780391/

    展开全文
  • 【落地页优化】woe对变量的分析

    千次阅读 2015-06-11 20:44:02
    文本变量的分析: 每一个用户是通过不同的渠道(tid)、广告位(sid)、关键词(kw)来到站内的,渠道和广告位本身是文本的分类型变量,这里通过woe计算tid和sid的分类型变量对落地页(因变量)的影响,另外,还...

    最近在做落地页优化的项目,整理一下,最近的工作。欢迎大家批评指正!


    对于不同的人从百度搜索关键词,点击跳转后,系统因能够根据不同人的特征,跳转到不同的页面,以提高商品的转化率。


    由于平台的特殊性,我这部分工作是要是对用户浏览的URL进行分类,来判断用户的喜好。这部分工作主要是通过站内爬虫,爬取所有能够访问到的url,由于日志里只记录了服务器response的url,所以需要用requests.get(visitUrl).url得到反馈的url,另外由于url中的“#”只是标识页面的位置,需要去除,再去重。许多url是通过ajax动态生成的,需要selenium.webdriver这个包来模拟浏览器的渲染,关于破解登录问题,使用的是手动登录后,用程序解析保存在本地的cookie,这样爬虫就可以访问登录后的页面,非常有规则性的url是通过正则表达式进行cover,无规则型的url则是通过hash加快索引,会用到hadoop平台,以后再讲。关于url分类表记录了,用户输入的url,服务器反馈的url,该url父级url,正则表达式,是否需要登录才能访问,一级类别,二级类别等。


    IP定位问题用的是python的17Mon包,覆盖率93%以上,useragent同样使用python的user-agents包,可以提取的特征为:浏览器家族、浏览器版本、操作系统及其版本、设备(移动设备家族),是否是手机,是否是平板,是否是电脑,是否是爬虫。(老大讲微软曾经直接拿useragent做hash定位到人,不知到怎么做特征的)


    文本变量的分析:

    每一个用户是通过不同的渠道(tid)、广告位(sid)、关键词(kw)来到站内的,渠道和广告位本身是文本的分类型变量,这里通过woe计算tid和sid的分类型变量对落地页(因变量)的影响,另外,还对tid、sid和kw进行分词后计算影响。

    利用jiebaR对文本进行分词,吐嘲一下tm包中文支持的太烂了。接下来就是重头:利用woe评价每个变量对因变量的影响。

    woe原本是风控模型里常用的评价指标,用来计算特征对二分类变量的预测能力,woe的相关知识可以看着里:

    1、http://blog.csdn.net/goodhuajun/article/details/39582761

    2、http://www.r-bloggers.com/r-credit-scoring-woe-information-value-in-woe-package/

    3、http://bryannotes.blogspot.com/2014/10/r-woeiv.html

    他和Entropy、gini系数一样。但是可以通过woe计算特征的IV,关于IV有阀值,可以直接判定该变量的预测能力。请参考:

    http://ucanalytics.com/blogs/information-value-and-weight-of-evidencebanking-case/

    如下:

    Information Value Predictive Power
    < 0.02 useless for prediction
    0.02 to 0.1 Weak predictor
    0.1 to 0.3 Medium predictor
    0.3 to 0.5 Strong predictor
     >0.5 Suspicious or too good to be true

    由于我们这里的落地页优化是多分类型,所以将多分类转换成二分类,比如这里的N分类将转换成N个二分类,对于每一个特征变量,我们可以计算这个特征变量对N个二分类的影响,所以可以生成一张N*M的一个information value的二维表,M=特征变量数目。这样特征的预测能力就一目了然啦。

    PS:随机森林也可以计算变量的预测能力,代码如下:

    rf <- randomForest(extractFeatures(train), train$count, ntree=100, importance=TRUE)
    imp <- importance(rf, type=1)
    featureImportance <- data.frame(Feature=row.names(imp), Importance=imp[,1]);
    p <- ggplot(featureImportance, aes(x=reorder(Feature, Importance), y=Importance)) +
         geom_bar(stat="identity", fill="#53cfff") +
         coord_flip() + 
         theme_light(base_size=20) +
         xlab("Importance") +
         ylab("") + 
         ggtitle("Random Forest Feature Importance\n") +
         theme(plot.title=element_text(size=18))

    ggsave("2_feature_importance.png", p)

    参考:https://www.kaggle.com/benhamner/bike-sharing-demand/random-forest-benchmark

    后面有东西接着讲~



    展开全文
  • WOE:信用评分卡模型中的变量离散化方法 2016-03-21 生存分析 在做回归模型时,因临床需要常常需要对连续性的变量离散化,诸如年龄,分为老、中、青三组,一般的做法是ROC或者X-tile等等。今天介绍一种在信用卡...

    WOE:信用评分卡模型中的变量离散化方法

    2016-03-21 生存分析

    在做回归模型时,因临床需要常常需要对连续性的变量离散化,诸如年龄,分为老、中、青三组,一般的做法是ROC或者X-tile等等。今天介绍一种在信用卡评分系统中常用的连续变量离散化方法。目的是给大家在临床数据分析中提供一种借鉴思路。

           最初接触信用卡评分系统是在2013年SAS中国数据分析大赛总决赛上,题目是用历史数据建立一个信用卡评分系统,其中的变量离散化技术主要用到WOE(Weight of Evidence)翻译过来叫证据权重。

           信用评分卡模型在国外是一种成熟的预测方法,尤其在信用风险评估以及金融风险控制领域更是得到了比较广泛的使用,其原理是将模型变量WOE编码方式离散化之后运用logistic回归模型进行的一种二分类变量的广义线性模型。

            本文重点介绍模型变量WOE以及IV原理,为表述方便,本文将模型目标标量为1记为违约用户,对于目标变量为0记为正常用户;则WOE(weight of Evidence)其实就是自变量取某个值的时候对违约比例的一种影响,怎么理解这句话呢?我下面通过一个图标来进行说明。

    Woe公式如下:

     

    Age

    #bad

    #good

    Woe

    0-10

    50

    200

    =ln((50/100)/(200/1000))=ln((50/200)/(100/1000))

    10-18

    20

    200

    =ln((20/100)/(200/1000))=ln((20/200)/(100/1000))

    18-35

    5

    200

    =ln((5/100)/(200/1000))=ln((5/200)/(100/1000))

    35-50

    15

    200

    =ln((15/100)/(200/1000))=ln((15/200)/(100/1000))

    50以上

    10

    200

    =ln((10/100)/(200/1000))=ln((10/200)/(100/1000))

    汇总

    100

    1000

     

            表中以age年龄为某个自变量,由于年龄是连续型自变量,需要对其进行离散化处理,假设离散化分为5组(至于如何分组,会在以后专题中解释),#bad和#good表示在这五组中违约用户和正常用户的数量分布,最后一列是woe值的计算,通过后面变化之后的公式可以看出,woe反映的是在自变量每个分组下违约用户对正常用户占比和总体中违约用户对正常用户占比之间的差异;从而可以直观的认为woe蕴含了自变量取值对于目标变量(违约概率)的影响。再加上woe计算形式与logistic回归中目标变量的logistic转换(logist_p=ln(p/1-p))如此相似,因而可以将自变量woe值替代原先的自变量值;

    讲完WOE下面来说一下IV:

    IV公式如下:

            其实IV衡量的是某一个变量的信息量,从公式来看的话,相当于是自变量woe值的一个加权求和,其值的大小决定了自变量对于目标变量的影响程度;从另一个角度来看的话,IV公式与信息熵的公式极其相似。

           事实上,为了理解WOE的意义,需要考虑对评分模型效果的评价。因为我们在建模时对模型自变量的所有处理工作,本质上都是为了提升模型的效果。在之前的一些学习中,我也总结了这种二分类模型效果的评价方法,尤其是其中的ROC曲线。为了描述WOE的意义,还真的需要从ROC说起。

          仍旧是先画个表格:

    数据来自于著名的German credit dataset,取了其中一个自变量来说明问题。第一列是自变量的取值,N表示对应每个取值的样本数,n1和n0分别表示了违约样本数与正常样本数,p1和p0分别表示了违约样本与正常样本占各自总体的比例,cump1和cump0分别表示了p1和p0的累计和,woe是对应自变量每个取值的WOE(ln(p1/p0)),iv是woe*(p1-p0)。对iv求和(可以看成是对WOE的加权求和),就得到IV(information value信息值),是衡量自变量对目标变量影响的指标之一(类似于gini,entropy那些),此处是0.666,貌似有点太大了,囧。

            上述过程研究了一个自变量对目标变量的影响,事实上也可以看成是单个自变量的评分模型,更进一步地,可以直接将自变量的取值当做是某种信用评分的得分,此时需要假设自变量是某种有序变量,也就是仅仅根据这个有序的自变量直接对目标变量进行预测。

           正是基于这种视角,我们可以将“模型效果的评价”与“自变量筛选及编码”这两个过程统一起来。筛选合适的自变量,并进行适当的编码,事实上就是挑选并构造出对目标变量有较高预测力(predictive power)的自变量,同时也可以认为,由这些自变量分别建立的单变量评分模型,其模型效果也是比较好的。

           就以上面这个表格为例,其中的cump1和cump0,从某种角度看就是我们做ROC曲线时候的TPR与FPR。例如,此时的评分排序为A12,A11,A14,A13,若以A14为cutoff,则此时的TPR=cumsum(p1)[3]/(sum(p1)),FPR=cumsum(p0)[3]/(sum(p0)),就是cump1[3]和cump0[3]。于是我们可以画出相应的ROC曲线。



             可以看得出来这个ROC不怎么好看。之前也学习过了,ROC曲线有可以量化的指标AUC,指的就是曲线下方的面积。这种面积其实衡量了TPR与FPR之间的距离。根据上面的描述,从另一个角度看TPR与FPR,可以理解为这个自变量(也就是某种评分规则的得分)关于0/1目标变量的条件分布,例如TPR,即cump1,也就是当目标变量取1时,自变量(评分得分)的一个累积分布。当这两个条件分布距离较远时,说明这个自变量对目标变量有较好的辨识度。  

             既然条件分布函数能够描述这种辨识能力,那么条件密度函数行不行呢?这就引出了IV和WOE的概念。事实上,我们同样可以衡量两个条件密度函数的距离,这就是IV。这从IV的计算公式里面可以看出来,IV=sum((p1-p0)*log(p1/p0)),其中的p1和p0就是相应的密度值。IV这个定义是从相对熵演化过来的,里面仍然可以看到x*lnx的影子。

           至此应该已经可以总结到:评价评分模型的效果可以从“条件分布函数距离”与“条件密度函数距离”这两个角度出发进行考虑,从而分别得到AUC和IV这两个指标。这两个指标当然也可以用来作为筛选自变量的指标,IV似乎更加常用一些。而WOE就是IV的一个主要成分。 

           那么,到底为什么要用WOE来对自变量做编码呢?主要的两个考虑是:提升模型的预测效果,提高模型的可理解性。 

           首先,对已经存在的一个评分规则,例如上述的A12,A11,A14,A13,对其做各种函数变化,可以得到不同的ROC结果。但是,如果这种函数变化是单调的,那么ROC曲线事实上是不发生变化的。因此,想要提高ROC,必须寄希望于对评分规则做非单调的变换。传说中的NP引理证明了,使得ROC达到最优的变换就是计算现有评分的一个WOE,这似乎叫做“条件似然比”变换。

          用上述例子,我们根据计算出的WOE值,对评分规则(也就是第一列的value)做排序,得到新的一个评分规则。

       此处按照WOE做了逆序排列(因为WOE越大则违约概率越大),照例可以画出ROC线。

           可以看出来,经过WOE的变化之后,模型的效果好多了。事实上,WOE也可以用违约概率来代替,两者没有本质的区别。用WOE来对自变量做编码的一大目的就是实现这种“条件似然比”变换,极大化辨识度。 

           同时,WOE与违约概率具有某种线性关系,从而通过这种WOE编码可以发现自变量与目标变量之间的非线性关系(例如U型或者倒U型关系)。在此基础上,我们可以预料到模型拟合出来的自变量系数应该都是正数,如果结果中出现了负数,应当考虑是否是来自自变量多重共线性的影响。

           另外,WOE编码之后,自变量其实具备了某种标准化的性质,也就是说,自变量内部的各个取值之间都可以直接进行比较(WOE之间的比较),而不同自变量之间的各种取值也可以通过WOE进行直接的比较。进一步地,可以研究自变量内部WOE值的变异(波动)情况,结合模型拟合出的系数,构造出各个自变量的贡献率及相对重要性。一般地,系数越大,woe的方差越大,则自变量的贡献率越大(类似于某种方差贡献率),这也能够很直观地理解。 

          总结起来就是,做信用评分模型时,自变量的处理过程(包括编码与筛选)很大程度上是基于对单变量模型效果的评价。而在这个评价过程中,ROC与IV是从不同角度考察自变量对目标变量的影响力,基于这种考察,我们用WOE值对分类自变量进行编码,从而能够更直观地理解自变量对目标变量的作用效果及方向,同时提升预测效果。

    参考文献:

    1. http://support.sas.com/resources/papers/proceedings13/095-2013.pdf (内有SAS程序);

    2. http://ucanalytics.com/blogs/information-value-and-weight-of-evidencebanking-case/

     

    附SAS宏程序:

    %macro WOEANDIV;

    %do i=1 %to &varnum;/*循环计算每个变量的WOE和IV*/

    data sasuser.woeiv;

    set sasuser.woeiv;

    if x&i=. then x&i=-1000000000;

    run;

    proc sql;

    select sum(case when target=1 then 1 else 0 end), sum(case when target=0 then 1 else 0 end), count(*) into :tot_bad, :tot_good, :tot_both

    from sasuser.woeiv;

    quit;

    proc sql;

    select count(*) into :nonmiss

    from sasuser.woeiv

    where x&i ne -1000000000;

    quit;

    /*计算WOE*/

    proc sql;

    create table woe&i as

    (select "x&i" as variable,

    x&i as tier,

    count(*) as cnt,

    count(*)/&tot_both as cnt_pct,

    sum(case when target=0 then 1 else 0 end) as sum_good,

    sum(case when target=0 then 1 else 0 end)/&tot_good as dist_good,

    sum(case when target=1 then 1 else 0 end) as sum_bad,

    sum(case when target=1 then 1 else 0 end)/&tot_bad as dist_bad,

    log((sum(case when target=0 then 1 else 0 end)/&tot_good)/(sum(case when

    target=1 then 1 else 0 end)/&tot_bad))*100 as woe,

    ((sum(case when target=0 then 1 else 0 end)/&tot_good)-(sum(case when

    target=1 then 1 else 0 end)/&tot_bad))

    *log((sum(case when target=0 then 1 else 0

    end)/&tot_good)/(sum(case when target=1 then 1 else 0 end)/&tot_bad)) as pre_iv,

    sum(case when target=1 then 1 else 0 end)/count(*) as outcome

    from sasuser.woeiv

    group by x&i

    )

    order by x&i;

    quit;

    /*计算IV*/

    proc sql;

    create table iv&i as select "x&i" as variable,

    sum(pre_iv) as iv,

    (1-&nonmiss/&tot_both) as pct_missing

    from woe&i; quit;

    %end;

    %mend;

    %WOEANDIV;

     

    /*合并IV结果*/

    data iv;

    length variable $5.;

    set iv1-iv&varnum;

    run;

     

    /*根据IV值排序*/

    proc sort data=iv out=iv;

    by decending iv;

    quit;

     

    R语言程序详见R论坛。

     


     


    版权声明:本公众号的内容部分来自互联网,转载请注明原文链接和作者,如有侵权或出处有误请联系我们。

    官方邮箱:survival_analysis@126.com

    官方微信:生存分析(survival-analysis)



    本公众号精彩历史文章:

    04:如何在R软件中求一致性指数( Harrell'concordance index:C-index)?

    05:Nomogram 绘制原理及R&SAS实现.

    06  : Lasso方法简要介绍及其在回归分析中的应用

    07  : 最优模型选择中的交叉验证(Cross validation)方法

    08  : 用R语言进行分位数回归(Quantile Regression)

    09  : 样本数据中异常值(Outliers)检测方法及SPSS & R实现

    10  : 原始数据中几类缺失值(Missing Data)的SPSS及R处理方法

    11  :  [Survival analysis] Kaplan-Meier法之SPSS实现

    12  :  [Survival analysis] COX比例风险回归模型在SPSS中的实现

    13  :  用R绘制地图:以疾病流行趋势为例

    14  :  数据挖掘方法:聚类分析简要介绍 及SPSS&R实现

    15  :  医学研究中的Logistic回归分析及R实现

    16  :  常用的非参数检验(Nonparametric Tests)总结

    17  :  高中生都能看懂的最小二乘法原理

    18  :  R语言中可实现的常用统计假设检验总结(侧重时间序列)

    19  :  如何根据样本例数、均数、标准差进行T-Test和ANOVA

    20  :  统计学中自由度的理解和应用

    21  :  ROC和AUC介绍以及如何计算AUC

    22  :  支持向量机SVM介绍及R实现

    23  :  SPSS如何做主成分分析?

    24  : Bootstrap再抽样方法简介

    回复文章前代码数字如“04”即可查看或直接查看历史文章。

    公众号:survival-analysis

    展开全文
  • WOE信用评分卡--R语言实例

    万次阅读 2017-03-28 10:41:34
    信用卡评分一数据准备二数据处理三变量分析四切分数据集五Logistic回归六WOE转换七评分卡的创建和实施 转载自:http://blog.csdn.net/csqazwsxedc/article/details/51225156 信用卡评分 2016年1月10日 ...
    
    

    转载自:http://blog.csdn.net/csqazwsxedc/article/details/51225156

    信用卡评分

    2016年1月10日

    一、数据准备

    1、 问题的准备

    •            目标:要完成一个评分卡,通过预测某人在未来两年内将会经历财务危机的可能性来提高信用评分的效果,帮助贷款人做出最好的决策。

    •            背景:

    –            银行在市场经济中起到至关重要的作用。他们决定谁在什么条件下可以得到融资,并且可以创造或打破投资决策。而市场、社会,以及个人和企业都需要获得贷款。

    –            信用评分算法,对默认可能性进行猜测,这是银行用来判断贷款是否应该被授予的方法。

    •            准备:

    –            首先是基于个人借贷的场景,确定“违约”的定义: 根据新的Basel II Capital Accord(巴塞尔二资本协议),一般逾期90天算作违约。

    –            在判别指标上,选择使用历史最大违约天数。

     

    2、数据的获取与整合

    •            数据来源:数据来自Kaggle,cs-training.csv是有15万条的样本数据,下图可以看到这份数据的大致情况。下载地址为:https://www.kaggle.com/c/GiveMeSomeCredit/data

    •            数据描述:数据属于个人消费类贷款,只考虑评分卡最终实施时能够使用到的数据应从如下一些方面获取数据:

    –            基本属性:包括了借款人当时的年龄。

    –            偿债能力:包括了借款人的月收入、负债比率。

    –            信用往来:两年内35-59天逾期次数、两年内60-89天逾期次数、两年内90天或高于90天逾期的次数。

    –            财产状况:包括了开放式信贷和贷款数量、不动产贷款或额度数量。

    –            贷款属性:暂无。

    –            其他因素:包括了借款人的家属数量(不包括本人在内)。

    •            原始变量:

    变量名

    变量类型

    变量描述

    SeriousDlqin2yrs

    Y/N

    超过90天或更糟的逾期拖欠

    RevolvingUtilizationOf

    UnsecuredLines

    percentage

    无担保放款的循环利用:除了不动产和像车贷那样除以信用额度总和的无分期付款债务的信用卡和个人信用额度总额

    age

    integer

    借款人当时的年龄

    NumberOfTime30-59DaysPastDueNotWorse

    integer

    35-59天逾期但不糟糕次数

    DebtRatio

    percentage

    负债比率

    MonthlyIncome

    real

    月收入

    NumberOf

    OpenCreditLinesAndLoans

    integer

    开放式信贷和贷款数量,开放式贷款(分期付款如汽车贷款或抵押贷款)和信贷(如信用卡)的数量

    NumberOfTimes90DaysLate

    integer

    90天逾期次数:借款者有90天或更高逾期的次数

    NumberRealEstateLoans

    OrLines

    integer

    不动产贷款或额度数量:抵押贷款和不动产放款包括房屋净值信贷额度

    NumberOfTime60-89DaysPastDueNotWorse

    integer

    60-89天逾期但不糟糕次数:借款人在在过去两年内有60-89天逾期还款但不糟糕的次数

    NumberOfDependents

    integer

    家属数量:不包括本人在内的家属数量

    •            时间窗口:自变量的观察窗口为过去两年,因变量表现窗口为未来两年。

    二、数据处理

    首先去掉原数据中的顺序变量,即第一列的id变量。由于要预测的是SeriousDlqin2yrs变量,因此将其设为响应变量y,其他分别设为x1~x10变量。

    1、缺失值分析及处理

    在得到数据集后,我们需要观察数据的分布情况,因为很多的模型对缺失值敏感,因此观察是否有缺失值是其中很重要的一个步骤。在正式分析前,我们先通过图形进行对观测字段的缺失情况有一个直观的感受。

      matrixplot(traindata)

    
    

      md.pattern(traindata)
    ##        y x1 x2 x3 x4 x6 x7 x8 x9  x10    x5      
    ## 120269 1  1  1  1  1  1  1  1  1    1     1     0
    ##  25807 1  1  1  1  1  1  1  1  1    1     0     1
    ##   3924 1  1  1  1  1  1  1  1  1    0     0     2
    ##        0  0  0  0  0  0  0  0  0 3924 29731 33655

    
    

    利用matrixplot函数对缺失值部分进行可视化展示,上图中浅色表示值小,深色表示值大,而默认缺失值为红色。因此可以看到x5变量和x10变量,即MonthlyIncome变量和NumberOfDependents两个变量存在缺失值,具体确实情况可以见上表,monthlyincome列共有缺失值29731个,numberofdependents有3924个。

    对于缺失值的处理方法非常多,例如基于聚类的方法,基于回归的方法,基于均值的方法,其中最简单的方法是直接移除,但是在本文中因为缺失值所占比例较高,直接移除会损失大量观测,因此并不是最合适的方法。在这里,我们使用KNN方法对缺失值进行填补。

    traindata<-knnImputation(traindata,k=10,meth = "weighAvg")
    

    2、异常值分析及处理

    关于异常值的检测,这里简单介绍以下一些检测方法:

    •       单变量异常值检测:在R语言中使用函数boxplot.stats()可以实现单变量检测,该函数根据返回的统计数据生成箱线图。在上述函数的返回结果中,有一个参数out,它是异常值组成的列表。更明确的说就是里面列出了箱线图中箱须线外面的数据点。比如我们可以查看月收入分布,第一幅图为没有删除异常值的箱线图。第二幅箱线图删除异常值后,可以发现月收入主要集中分布在3000-8000之间。但是在这份分析报告中,因为我们对业务尚不熟悉,不好将大于8000的数据直接归为异常值,因此对该变量未做处理。


    •       使用LOF(局部异常因子)检测异常值:LOF(局部异常因子)是一种基于密度识别异常值的算法。算法实现是:将一个点的局部密度与分布在它周围的点的密度相比较,如果前者明显的比后者小,那么这个点相对于周围的点来说就处于一个相对比较稀疏的区域,这就表明该点事一个异常值。LOF算法的缺点是它只对数值型数据有效。包‘DMwR’和包‘dprep’中的lofactor()可以计算LOF算法中的局部异常因子。

    •       通过聚类检测异常值:检测异常值的另外一种方式就是聚类。先把数据聚成不同的类,选择不属于任何类的数据作为异常值。例如,基于密度的聚类DBSCAN算法的实就是将与数据稠密区域紧密相连的数据对象划分为一个类,因此与其他对象分离的数据就会作为异常值。也可以使用K均值算法实现异常值的检测。首先通过把数据划分k组,划分方式是选择距离各自簇中心最近的点为一组;然后计算每个对象和对应的簇中心的距离(或者相似度),并挑出拥有最大的距离的点作为异常值。

    首先对于x2变量,即客户的年龄,我们可以定量分析,发现有以下值:

    unique(traindata$x2)
    ##  [1]  45  40  38  30  49  74  57  39  27  51  46  76  64  78  53  43  25
    ## [18]  32  58  50  69  24  28  62  42  75  26  52  41  81  31  68  70  73
    ## [35]  29  55  35  72  60  67  36  56  37  66  83  34  44  48  61  80  47
    ## [52]  59  77  63  54  33  79  65  86  92  23  87  71  22  90  97  84  82
    ## [69]  91  89  85  88  21  93  96  99  94  95 101  98 103 102 107 105   0
    ## [86] 109

    
    

    可以看到年龄中存在0值,显然是异常值,予以剔除。

    traindata<-traindata[-which(traindata$x2==0),] 

    而对于x3,x7,x9三个变量,由下面的箱线图可以看出,均存在异常值,且由unique函数可以得知均存在96、98两个异常值,因此予以剔除。同时会发现剔除其中一个变量的96、98值,其他变量的96、98两个值也会相应被剔除

    ##  [1]  2  0  1  3  4  5  7 10  6 98 12  8  9 96 13 11
    ##  [1]  0  1  3  2  5  4 98 10  9  6  7  8 15 96 11 13 14 17 12
    ##  [1]  0  1  2  5  3 98  4  6  7  8 96 11  9

    
    

    其它变量占不作处理。

    三、变量分析

    1、单变量分析

    我们可以简单地看下部分变量的分布,比如对于age变量,如下图:

    ggplot(traindata, aes(x = x2, y = ..density..)) + geom_histogram(fill = "blue", colour = "grey60", size = 0.2, alpha = 0.2) + geom_density()

    可以看到年龄变量大致呈正态分布,符合统计分析的假设。再比如月收入变量,也可以做图观察观察,如下:

    ggplot(traindata, aes(x = x5, y = ..density..)) + geom_histogram(fill = "blue", colour = "grey60", size = 0.2, alpha = 0.2) + geom_density() + xlim(1, 20000)

    月收入也大致呈正态分布,符合统计分析的需要。

     

    2、变量之间的相关性

    建模之前首先得检验变量之间的相关性,如果变量之间相关性显著,会影响模型的预测效果。下面通过corrplot函数,画出各变量之间,包括响应变量与自变量的相关性。

    cor1<-cor(traindata[,1:11])
    corrplot(cor1)

    corrplot(cor1,method = "number")

    由上图可以看出,各变量之间的相关性是非常小的。其实Logistic回归同样需要检验多重共线性问题,不过此处由于各变量之间的相关性较小,可以初步判断不存在多重共线性问题,当然我们在建模后还可以用VIF(方差膨胀因子)来检验多重共线性问题。如果存在多重共线性,即有可能存在两个变量高度相关,需要降维或剔除处理。

    四、切分数据集

    table(traindata$y)
    ## 
    ##      0      1 
    ## 139851   9879

    
    

    由上表看出,对于响应变量SeriousDlqin2yrs,存在明显的类失衡问题,SeriousDlqin2yrs等于1的观测为9879,仅为所有观测值的6.6%。因此我们需要对非平衡数据进行处理,在这里可以采用SMOTE算法,用R对稀有事件进行超级采样。

    我们利用caret包中的createDataPartition(数据分割功能)函数将数据随机分成相同的两份。

    set.seed(1234) 
    splitIndex<-createDataPartition(traindata$y,time=1,p=0.5,list=FALSE) 
    train<-traindata[splitIndex,] 
    test<-traindata[-splitIndex,] 

    
    

    对于分割后的训练集和测试集均有74865个数据,分类结果的平衡性如下:

    prop.table(table(train$y)) 

    ## 
    ##          0          1 
    ## 0.93314633 0.06685367

    prop.table(table(test$y)) 
    ## 
    ##          0          1 
    ## 0.93489615 0.06510385

    两者的分类结果是平衡的,仍然有6.6%左右的代表,我们仍然处于良好的水平。因此可以采用这份切割的数据进行建模及预测。

    五、Logistic回归

    Logistic回归在信用评分卡开发中起到核心作用。由于其特点,以及对自变量进行了证据权重转换(WOE),Logistic回归的结果可以直接转换为一个汇总表,即所谓的标准评分卡格式。


    2、建立模型

    首先利用glm函数对所有变量进行Logistic回归建模,模型如下

    fit<-glm(y~.,train,family = "binomial")
    summary(fit)
    ## 
    ## Call:
    ## glm(formula = y ~ ., family = "binomial", data = train)
    ## 
    ## Deviance Residuals: 
    ##     Min       1Q   Median       3Q      Max  
    ## -4.6144  -0.3399  -0.2772  -0.2240   3.6997  
    ## 
    ## Coefficients:
    ##               Estimate Std. Error z value Pr(>|z|)    
    ## (Intercept) -1.812e+00  6.411e-02 -28.268  < 2e-16 ***
    ## x1          -1.846e-05  8.972e-05  -0.206 0.836948    
    ## x2          -2.861e-02  1.276e-03 -22.428  < 2e-16 ***
    ## x3           5.767e-01  1.564e-02  36.867  < 2e-16 ***
    ## x4          -2.321e-05  1.538e-05  -1.509 0.131224    
    ## x5          -1.355e-05  3.845e-06  -3.524 0.000425 ***
    ## x6          -2.769e-03  3.798e-03  -0.729 0.466051    
    ## x7           8.468e-01  2.429e-02  34.855  < 2e-16 ***
    ## x8           8.620e-02  1.599e-02   5.393 6.94e-08 ***
    ## x9           8.294e-01  3.338e-02  24.848  < 2e-16 ***
    ## x10          5.126e-02  1.388e-02   3.694 0.000221 ***
    ## ---
    ## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
    ## 
    ## (Dispersion parameter for binomial family taken to be 1)
    ## 
    ##     Null deviance: 36747  on 74864  degrees of freedom
    ## Residual deviance: 29793  on 74854  degrees of freedom
    ## AIC: 29815
    ## 
    ## Number of Fisher Scoring iterations: 6

    
    

              可以看出,利用全变量进行回归,模型拟合效果并不是很好,其中x1,x4,x6三个变量的p值未能通过检验,在此直接剔除这三个变量,利用剩余的变量对y进行回归。

    fit2<-glm(y~x2+x3+x5+x7+x8+x9+x10,train,family = "binomial")
    summary(fit2)
    ## 
    ## Call:
    ## glm(formula = y ~ x2 + x3 + x5 + x7 + x8 + x9 + x10, family = "binomial", 
    ##     data = train)
    ## 
    ## Deviance Residuals: 
    ##     Min       1Q   Median       3Q      Max  
    ## -4.6223  -0.3402  -0.2777  -0.2239   3.5868  
    ## 
    ## Coefficients:
    ##               Estimate Std. Error z value Pr(>|z|)    
    ## (Intercept) -1.825e+00  6.320e-02 -28.873  < 2e-16 ***
    ## x2          -2.894e-02  1.252e-03 -23.120  < 2e-16 ***
    ## x3           5.742e-01  1.544e-02  37.187  < 2e-16 ***
    ## x5          -1.185e-05  3.513e-06  -3.373 0.000744 ***
    ## x7           8.500e-01  2.401e-02  35.397  < 2e-16 ***
    ## x8           7.494e-02  1.420e-02   5.276 1.32e-07 ***
    ## x9           8.306e-01  3.338e-02  24.883  < 2e-16 ***
    ## x10          5.169e-02  1.386e-02   3.730 0.000192 ***
    ## ---
    ## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
    ## 
    ## (Dispersion parameter for binomial family taken to be 1)
    ## 
    ##     Null deviance: 36747  on 74864  degrees of freedom
    ## Residual deviance: 29797  on 74857  degrees of freedom
    ## AIC: 29813
    ## 
    ## Number of Fisher Scoring iterations: 6

    
    

          第二个回归模型所有变量都通过了检验,甚至AIC值(赤池信息准则)更小,所有模型的拟合效果更好些。

     

    3、模型评估

    通常一个二值分类器可以通过ROC(Receiver Operating Characteristic)曲线和AUC值来评价优劣。

    很多二元分类器会产生一个概率预测值,而非仅仅是0-1预测值。我们可以使用某个临界点(例如0.5),以划分哪些预测为1,哪些预测为0。得到二元预测值后,可以构建一个混淆矩阵来评价二元分类器的预测效果。所有的训练数据都会落入这个矩阵中,而对角线上的数字代表了预测正确的数目,即true positive + true nagetive。同时可以相应算出TPR(真正率或称为灵敏度)和TNR(真负率或称为特异度)。我们主观上希望这两个指标越大越好,但可惜二者是一个此消彼涨的关系。除了分类器的训练参数,临界点的选择,也会大大的影响TPR和TNR。有时可以根据具体问题和需要,来选择具体的临界点。

    如果我们选择一系列的临界点,就会得到一系列的TPR和TNR,将这些值对应的点连接起来,就构成了ROC曲线。ROC曲线可以帮助我们清楚的了解到这个分类器的性能表现,还能方便比较不同分类器的性能。在绘制ROC曲线的时候,习惯上是使用1-TNR作为横坐标即FPR(false positive rate),TPR作为纵坐标。这是就形成了ROC曲线。

    AUCArea Under Curve)被定义为ROC曲线下的面积,显然这个面积的数值不会大于1。又由于ROC曲线一般都处于y=x这条直线的上方,所以AUC的取值范围在0.51之间。使用AUC值作为评价标准是因为很多时候ROC曲线并不能清晰的说明哪个分类器的效果更好,而作为一个数值,对应AUC更大的分类器效果更好。

    下面首先利用模型对test数据进行预测,生成概率预测值

    pre <- predict(fit2,test)
    
    

    在R中,可以利用pROC包,它能方便比较两个分类器,还能自动标注出最优的临界点,图看起来也比较漂亮。在下图中最优点FPR=1-TNR=0.845,TPR=0.638,AUC值为0.8102,说明该模型的预测效果还是不错的,正确较高。

    modelroc <- roc(test$y,pre)
    plot(modelroc, print.auc=TRUE, auc.polygon=TRUE, grid=c(0.1, 0.2),
         grid.col=c("green", "red"), max.auc.polygon=TRUE,
         auc.polygon.col="skyblue", print.thres=TRUE)

    
    

    ## 
    ## Call:
    ## roc.default(response = test$y, predictor = pre)
    ## 
    ## Data: pre in 69991 controls (test$y 0) < 4874 cases (test$y 1).
    ## Area under the curve: 0.8102

    六、WOE转换

    证据权重(Weight of Evidence,WOE)转换可以将Logistic回归模型转变为标准评分卡格式。引入WOE转换的目的并不是为了提高模型质量,只是一些变量不应该被纳入模型,这或者是因为它们不能增加模型值,或者是因为与其模型相关系数有关的误差较大,其实建立标准信用评分卡也可以不采用WOE转换。这种情况下,Logistic回归模型需要处理更大数量的自变量。尽管这样会增加建模程序的复杂性,但最终得到的评分卡都是一样的。

    用WOE(x)替换变量x。WOE()=ln[(违约/总违约)/(正常/总正常)]。

    通过上述的Logistic回归,剔除x1,x4,x6三个变量,对剩下的变量进行WOE转换。

     

    1、进行分箱

    age变量(x2):

       cutx2= c(-Inf,30,35,40,45,50,55,60,65,75,Inf)
       plot(cut(train$x2,cutx2))

    
    
    

    NumberOfTime30-59DaysPastDueNotWorse变量(x3):

       cutx3 = c(-Inf,0,1,3,5,Inf)
       plot(cut(train$x3,cutx3))


    
    
    

    MonthlyIncome变量(x5):

       cutx5 = c(-Inf,1000,2000,3000,4000,5000,6000,7500,9500,12000,Inf)
       plot(cut(train$x5,cutx5))


    
    

    NumberOfTimes90DaysLate变量(x7):

       cutx7 = c(-Inf,0,1,3,5,10,Inf)
       plot(cut(train$x7,cutx7))


    NumberRealEstateLoansOrLines变量(x8):

       cutx8= c(-Inf,0,1,2,3,5,Inf)
       plot(cut(train$x8,cutx8))
    
    

    NumberOfTime60-89DaysPastDueNotWorse变量(x9):

       cutx9 = c(-Inf,0,1,3,5,Inf)
       plot(cut(train$x9,cutx9))
    
    

    NumberOfDependents变量(x10):

       cutx10 = c(-Inf,0,1,2,3,5,Inf)
       plot(cut(train$x10,cutx10))

    
    

    2、计算WOE值

    计算WOE的函数

       totalgood = as.numeric(table(train$y))[1]
       totalbad = as.numeric(table(train$y))[2]
       getWOE <- function(a,p,q)
       {
          Good <- as.numeric(table(train$y[a > p & a <= q]))[1]
          Bad <- as.numeric(table(train$y[a > p & a <= q]))[2]
          WOE <- log((Bad/totalbad)/(Good/totalgood),base = exp(1))
          return(WOE)
      }

    比如age变量(x2)

       Agelessthan30.WOE=getWOE(train$x2,-Inf,30)
       Age30to35.WOE=getWOE(train$x2,30,35)
       Age35to40.WOE=getWOE(train$x2,35,40)
       Age40to45.WOE=getWOE(train$x2,40,45)
       Age45to50.WOE=getWOE(train$x2,45,50)
       Age50to55.WOE=getWOE(train$x2,50,55)
       Age55to60.WOE=getWOE(train$x2,55,60)
       Age60to65.WOE=getWOE(train$x2,60,65)
       Age65to75.WOE=getWOE(train$x2,65,75)
       Agemorethan.WOE=getWOE(train$x2,75,Inf)
       age.WOE=c(Agelessthan30.WOE,Age30to35.WOE,Age35to40.WOE,Age40to45.WOE,Age45to50.WOE,
                Age50to55.WOE,Age55to60.WOE,Age60to65.WOE,Age65to75.WOE,Agemorethan.WOE)
       age.WOE
    ##  [1]  0.57432879  0.52063157  0.34283924  0.24251193  0.22039521
    ##  [6]  0.07194294 -0.25643603 -0.55868003 -0.94144504 -1.28914527

    NumberOfTime30-59DaysPastDueNotWorse变量(x3)

    ## [1] -0.5324915  0.9106018  1.7645290  2.4432903  2.5682332

    MonthlyIncome变量(x5)

    ##  [1] -1.128862326  0.448960482  0.312423080  0.350846777  0.247782295
    ##  [6]  0.114417168 -0.001808106 -0.237224039 -0.389158800 -0.462438653

    NumberOfTimes90DaysLate变量(x7)

    ## [1] -0.3694044  1.9400973  2.7294448  3.3090003  3.3852925  2.3483738

    NumberRealEstateLoansOrLines变量(x8)

    ## [1]  0.21490691 -0.24386987 -0.15568385  0.02906876  0.41685234  1.12192809

    NumberOfTime60-89DaysPastDueNotWorse变量(x9)

    ## [1] -0.2784605  1.8329078  2.7775343  3.5805174  3.4469860

    NumberOfDependents变量(x10)

    ## [1] -0.15525081  0.08669961  0.19618098  0.33162486  0.40469824  0.76425365
    
    

    3、对变量进行WOE变换

    如age变量(x2)

    如age变量(x2)

        tmp.age <- 0
        for(i in 1:nrow(train)) {
          if(train$x2[i] <= 30)
            tmp.age[i] <- Agelessthan30.WOE
          else if(train$x2[i] <= 35)
            tmp.age[i] <- Age30to35.WOE
          else if(train$x2[i] <= 40)
            tmp.age[i] <- Age35to40.WOE
          else if(train$x2[i] <= 45)
            tmp.age[i] <- Age40to45.WOE
          else if(train$x2[i] <= 50)
            tmp.age[i] <- Age45to50.WOE
          else if(train$x2[i] <= 55)
            tmp.age[i] <- Age50to55.WOE
          else if(train$x2[i] <= 60)
            tmp.age[i] <- Age55to60.WOE
          else if(train$x2[i] <= 65)
            tmp.age[i] <- Age60to65.WOE
          else if(train$x2[i] <= 75)
            tmp.age[i] <- Age65to75.WOE
          else
            tmp.age[i] <- Agemorethan.WOE
        }
        
        table(tmp.age)
    ## tmp.age
    ##   -1.2891452711972 -0.941445039519045 -0.558680027962495 
    ##               5063               9196               8180 
    ## -0.256436029353835 0.0719429392949312  0.220395209955515 
    ##               8472               9009               9465 
    ##  0.242511934081286  0.342839240194068   0.52063156705216 
    ##               8008               6784               5390 
    ##  0.574328792863984 
    ##               5298
        tmp.age[1:10]
    ##  [1] 0.34283924 0.57432879 0.34283924 0.57432879 0.07194294 0.22039521
    ##  [7] 0.07194294 0.24251193 0.34283924 0.52063157
        train$x2[1:10]
    ##  [1] 38 30 39 30 51 46 53 43 39 32

    NumberOfTime30-59DaysPastDueNotWorse变量(x3)

    ## tmp.NumberOfTime30.59DaysPastDueNotWorse
    ## -0.53249146131578 0.910601840444591  1.76452904024992  2.44329031065646 
    ##             62948              8077              3160               562 
    ##  2.56823323027274 
    ##               118
    ##  [1]  0.9106018 -0.5324915 -0.5324915 -0.5324915 -0.5324915 -0.5324915
    ##  [7] -0.5324915 -0.5324915 -0.5324915 -0.5324915
    ##  [1] 1 0 0 0 0 0 0 0 0 0

    MonthIncome变量(x5)

    ## tmp.MonthlyIncome
    ##    -1.12886232582259   -0.462438653207328   -0.389158799506996 
    ##                10201                 5490                 5486 
    ##   -0.237224038650003 -0.00180810632297072    0.114417167554772 
    ##                 7048                 8076                 7249 
    ##    0.247782294610166    0.312423079500641    0.350846777249291 
    ##                 9147                 8118                 9680 
    ##    0.448960482499888 
    ##                 4370
    ##  [1]  0.350846777  0.350846777  0.350846777  0.312423080 -0.001808106
    ##  [6] -0.462438653 -0.237224039  0.350846777  0.312423080 -0.237224039
    ##  [1]  3042  3300  3500  2500  6501 12454  8800  3280  2500  7916

    NumberOfTime90DaysPastDueNotWorse变量(x7)

    ## tmp.NumberOfTimes90DaysLate
    ## -0.369404425455224   1.94009728631401   2.34837375415972 
    ##              70793               2669                  7 
    ##   2.72944477623793   3.30900029985393   3.38529247382249 
    ##               1093                222                 81
    ##  [1]  1.9400973 -0.3694044 -0.3694044 -0.3694044 -0.3694044 -0.3694044
    ##  [7] -0.3694044 -0.3694044 -0.3694044 -0.3694044
    ##  [1] 1 0 0 0 0 0 0 0 0 0

    NumberRealEstateLoansOrLines变量(x8)

    ## tmp.NumberRealEstateLoansOrLines
    ## -0.243869874062293 -0.155683851792327 0.0290687559545721 
    ##              26150              15890               3130 
    ##  0.214906905417014   1.12192809398173 
    ##              27901               1794
    ##  [1]  0.2149069  0.2149069  0.2149069  0.2149069 -0.1556839 -0.1556839
    ##  [7]  0.2149069 -0.2438699  0.2149069  0.2149069
    ##  [1] 0 0 0 0 2 2 0 1 0 0

    NumberOfTime60.89DaysPastDueNotWorse变量(x9)

    ## tmp.NumberOfTime60.89DaysPastDueNotWorse
    ## -0.278460464730538   1.83290775083723   2.77753428092856 
    ##              71150               2919                708 
    ##   3.44698604282783   3.58051743545235 
    ##                 13                 75
    ##  [1] -0.2784605 -0.2784605 -0.2784605 -0.2784605 -0.2784605 -0.2784605
    ##  [7] -0.2784605 -0.2784605 -0.2784605 -0.2784605
    ##  [1] 0 0 0 0 0 0 0 0 0 0

    NumberOfDependents变量(x10)

    ## tmp.NumberOfDependents
    ## -0.155250809857344 0.0866996065110081  0.196180980387687 
    ##              43498              14544              10102 
    ##  0.331624863227172  0.404698242905824   0.76425364970991 
    ##               4771               1815                135
    ##  [1] -0.1552508 -0.1552508 -0.1552508 -0.1552508  0.1961810  0.1961810
    ##  [7] -0.1552508  0.1961810 -0.1552508 -0.1552508
    ##  [1] 0 0 0 0 2 2 0 2 0 0

    
    

    4、WOE DataFrame构建:

       trainWOE =cbind.data.frame(tmp.age,tmp.NumberOfTime30.59DaysPastDueNotWorse,tmp.MonthlyIncome,tmp.NumberOfTime60.89DaysPastDueNotWorse,tmp.NumberOfTimes90DaysLate,tmp.NumberRealEstateLoansOrLines,tmp.NumberOfDependents)

    七、评分卡的创建和实施

    标准评分卡采用的格式是评分卡中的每一个变量都遵循一系列IF-THEN法则,变量的值决定了该变量所分配的分值,总分就是各变量分值的和。


    知道线性表达式的两个参数A,B后就可以求每条记录(申请人)的分值。为了求得A,B,需要设定两个假设(分数的给定,很主观)。

    以上就是推断,实际代码中,习惯用了q、p来代表A、B.

    通俗来说就是,评分需要自己预设一个阀值,比如:

    这个人预测出来“不发生违约”的几率为0.8,设定这个人为500分;

    另一个人预测出来“不发生违约”的几率为0.9,设定这个人为600分。

    阀值的设定需根据行业经验不断跟踪调整,下面的分数设定仅代表个人经验。

    下面开始设立评分,假设按好坏比15为600分,每高20分好坏比翻一倍算出P,Q。如果后期结果不明显,可以高30-50分好坏比才翻一倍。

    Score = q - p * log(odds)

    即有方程:

    620 = q - p * log(15)

    600 = q - p * log(15/2)

    逻辑回归建模:

    #因为数据中“1”代表的是违约,直接建模预测,求的是“发生违约的概率”,log(odds)即为“坏好比”。为了符合常规理解,分数越高,信用越好,所有就调换“0”和“1”,使建模预测结果为“不发生违约的概率”,最后log(odds)即表示为“好坏比”。
    
    trainWOE$y = 1-train$y
    glm.fit = glm(y~.,data = trainWOE,family = binomial(link = logit))
    summary(glm.fit)
    coe = (glm.fit$coefficients)
    p <- 20/log(2)
    q <- 600-20*log(15)/log(2)
    Score=q + p*{as.numeric(coe[1])+as.numeric(coe[2])*tmp.age +as.numeric(coe[3])*tmp.NumberOfTime30.59DaysPastDueNotWorse+p*as.numeric(coe[4])*tmp.MonthlyIncome+p*as.numeric(coe[5])*tmp.NumberOfTime60.89DaysPastDueNotWorse+p*as.numeric(coe[6])*tmp.NumberOfTimes90DaysLate+p*as.numeric(coe[7])*tmp.NumberRealEstateLoansOrLines+p*as.numeric(coe[8])*tmp.NumberOfDependents
    个人总评分=基础分+各部分得分
    基础分为:
       base <- q + p*as.numeric(coe[1])
       base
    ## [1] 446.2841

    1、对各变量进行打分

    比如age变量(x2)

        Agelessthan30.SCORE = p*as.numeric(coe[2])*Agelessthan30.WOE
        Age30to35.SCORE = p*as.numeric(coe[2])*Age30to35.WOE
        Age35to40.SCORE = p*as.numeric(coe[2])*Age35to40.WOE
        Age40to45.SCORE = p*as.numeric(coe[2])*Age40to45.WOE
        Age45to50.SCORE = p*as.numeric(coe[2])*Age45to50.WOE
        Age50to55.SCORE = p*as.numeric(coe[2])*Age50to55.WOE
        Age55to60.SCORE = p*as.numeric(coe[2])*Age55to60.WOE
        Age60to65.SCORE = p*as.numeric(coe[2])*Age60to65.WOE
        Age65to75.SCORE = p*as.numeric(coe[2])*Age65to75.WOE
        Agemorethan.SCORE=p*as.numeric(coe[2])*Agemorethan.WOE
        Age.SCORE =c(Age30to35.SCORE,Age35to40.SCORE,Age40to45.SCORE,Age45to50.SCORE,Age50to55.SCORE,Age55to60.SCORE,Age60to65.SCORE,Age65to75.SCORE,Agemorethan.SCORE)
        Age.SCORE
    ## [1]  10.498828   6.913546   4.890389   4.444393   1.450770  -5.171176
    ## [7] -11.266096 -18.984767 -25.996338

    NumberOfTime30-59DaysPastDueNotWorse变量(x3)

    ## [1] -10.29843  17.61112  34.12614  47.25344  49.66985

    MonthlyIncome变量(x5)

    ##  [1] -24.92797904   9.91412083   6.89904854   7.74753565   5.47162546
    ##  [6]   2.52660461  -0.03992731  -5.23847393  -8.59355669 -10.21175106

    NumberOfTimes90DaysLate变量(x7)

    ## [1] -5.19482 27.28299 38.38333 46.53344 47.60632 33.02445

    NumberRealEstateLoansOrLine变量(x8)

    ## [1]  4.022310 -4.564396 -2.913860  0.544066  7.802025 20.998590

    NumberOfTime60-89DaysPastDueNotWorse变量(x9)

    ## [1] -4.820833 31.732126 48.085927 61.987533 59.675778

    NumberOfDependents变量(x10)

    ## [1] -1.5734012  0.8786638  1.9882112  3.3608775  4.1014453  7.7453871

    构造计算分值函数:

       getscore<-function(i,x){
       score = round(p*as.numeric(coe[i])*x,0)
       return(score)
    }

    2、计算各变量分箱得分:

    age变量(x2)

        Agelessthan30.SCORE = getscore(2,Agelessthan30.WOE)
        Age30to35.SCORE = getscore(2,Age30to35.WOE)
        Age35to40.SCORE = getscore(2,Age35to40.WOE)
        Age40to45.SCORE = getscore(2,Age40to45.WOE)
        Age45to50.SCORE = getscore(2,Age45to50.WOE)
        Age50to55.SCORE = getscore(2,Age50to55.WOE)
        Age55to60.SCORE = getscore(2,Age55to60.WOE)
        Age60to65.SCORE = getscore(2,Age60to65.WOE)
        Age65to75.SCORE = getscore(2,Age65to75.WOE)
        Agemorethan.SCORE = getscore(2,Agemorethan.WOE)
        Age.SCORE = c(Agelessthan30.SCORE,Age30to35.SCORE,Age35to40.SCORE,Age40to45.SCORE,Age45to50.SCORE,Age50to55.SCORE,Age55to60.SCORE,Age60to65.SCORE,Age65to75.SCORE,Agemorethan.SCORE)
        Age.SCORE
    ##  [1]  12  10   7   5   4   1  -5 -11 -19 -26

    NumberOfTime30-59DaysPastDueNotWorse变量(x3)

    ## [1] -10  18  34  47  50

    MonthlyIncome变量(x5)

    ##  [1] -25  10   7   8   5   3   0   0  -9 -10

    NumberOfTimes90DaysLate变量(x7)

    ## [1] -5 27 38 47 48 33

    NumberRealEstateLoansOrLine变量(x8)

    ## [1]  4 -5 -3  1  8 21

    NumberOfTime60-89DaysPastDueNotWorse变量(x9)

    ## [1] -5 32 48 62 60

    NumberOfDependents变量(x10)

    ## [1] -2  1  2  3  4  8

    3、最终生成的评分卡如下:

    age X2 <=30 (30,35] (35,40] (40,45] (45,50] (50,55] (55,60] (60,65] (65,75] (75,100]
    Score 12 10 7 5 4 1 -5 -11 -19 -26
    NumberOfTime30-59DaysPastDueNotWorse X3 <=0 (0,1] (1,3] (3,5] >5
    Score -10 18 34 47 50
    MonthlyIncome X5 <=1000 (1000,2000] (2000,3000] (3000,4000] (4000,5000] (5000,6000] (6000,7500] (7500,9500] (9500,12000] >12000
    Score -25 10 7 8 6 3 0 0 -9 -10
    NumberOfTimes90DaysLate X7 <=0 (0,1] (1,3] (3,5] (5,10] >10
    Score -5 27 38 47 48 33
    NumberRealEstateLoansOrLines X8 <=0 (0,1] (1,2] (2,3] (3,5] >5
    Score 4 -5 -3 1 8 21
    NumberOfTime60-89DaysPastDueNotWorse X9 <=0 (0,1] (1,3] (3,5] >5
    Score -5 32 48 62 60
    NumberOfDependents X10 <=0 (0,1] (1,2] (2,3] (3,5] >5
    Score -2 1 2 3 4 8

     个人评分计算案例:

    特征 数据 分数
    Age 38 7
    NumberOfTime30-59DaysPastDueNotWorse 4 47
    MonthlyIncome 1500 10
    NumberOfTimes90DaysLate 2 38
    NumberRealEstateLoansOrLines 1.5 -3
    NumberOfTime60-89DaysPastDueNotWorse 4 62
    NumberOfDependents 1.5 2

    所以这个人的总评分=基础分(base)+各特征分数

    总评分=446.2841+7+47+10+38-3+62+2=609.2841

    展开全文
  • 变量分析 首先,需要确定变量之间是否存在共线性,若存在高度相关性,只需保存最稳定、预测能力最高的那个。需要通过 VIF(variance inflation factor)也就是 方差膨胀因子进行检验。 变量分为连续变量和分类...
  • 评分卡介绍评分卡的种类——ABC卡FICO信用分1、FICO信用分简介2、FICO信用分的评判因素数据准备1、需要排除异常行为2、解释指标的选择3、目标变量的确立变量分箱——WOE转换评分的计算与分值分配模型的评价——模型...
  • 信用评分卡(WOE和IV值)_补

    千次阅读 2019-05-16 18:41:48
    客户信息:用于客户分析, 客户分析的目的是找到一个准确视角来制定策略,从而最优化的获取和保留客户,定义高价值客户 描述信息:客户的基本属性信息,如性别,年龄, 地理位置和收入等 行为信息:客户行...
  • 关于Hellobi Live | 1小时学会建立信用评分卡(金融数据的小分析-Python)中PyWoE包调用问题 anaconda中并没有PyWoE包,需要手动将PyWoE放在anaconda文件下。由于PyWoE源代码中 cuts, bins = pd.qcut(df["X"], self...
  • 单调WOE绑定算法 由John Stephen Joseph Arul Selvam开发和记录 ...评估预测变量强度的证据权重(WOE)方法在分析领域被低估了。 尽管它是信用风险建模中的标准收费,但其制定方式使其通用性足以在其
  • 变量分析 首先,需要确定变量之间是否存在共线性,若存在高度相关性,只需保存最稳定、预测能力最高的那个。需要通过 VIF(variance inflation factor)也就是 方差膨胀因子进行检验。 变量分为连续变量和分类变量。...
  • 基于Python的信用评分卡模型分析(一) 一、项目流程 二、数据获取 三、数据预处理 3.1 缺失值处理 3.2 异常值处理 3.3 数据切分 四、探索性分析 五、变量选择 5.1 分箱处理 5.2 WOE 5.3 相关性分析和IV筛选 如果不...
  • 数据分析入门全目录

    2018-08-15 12:02:33
    Python数据分析入门 ROC和AUC介绍以及如何计算AUC 机器学习之分类性能度量指标 : ROC曲线、AUC值、正确率、召回率 评分卡模型剖析之一(woe、IV、ROC、信息熵) 评分卡的建立方法——分箱、WOE、IV、分值分配 ...
  • 数据分析方法归结

    2020-10-10 14:26:28
    数据管理 输入 — 文件输入、HIVE表输入、kafka输入、关系数据库输入等 输出 — 文件输出、HIVE表输出、kafka输出、...数据交叉、属性生成、特征编码、主成分分析、因子分析、分箱、变量选择、高级特征交叉、WOE编码、
  • 完整数据分析流程

    2019-10-27 22:17:43
    1、binning_woe binning def get_interval(df,label,split_func,bins_num=None,self_thres=None): """ df : the need process dataframe data label : the column name of label data split_func :...
  • (1)TPR:指从真的情况里面,预测为真FPR:指从假的情况里面,预测为真TNR:指从假的情况里面,预测为假FNR:指从真的情况里面,预测为假(2)离散化并进行WOE的过程假如一个DataFrame有A,B,C三个自变量;...
  • 信用评分卡模型在国外是一种成熟的预测方法,尤其在信用风险评估以及金融风险控制领域更是得到了比较广泛的使用,其原理是将模型变量WOE编码方式离散化之后运用logistic回归模型进行的一种二分类变量的广义线性模型...
  • 文章目录 申请评分卡中的数据预处理和特征衍生 构建信用风险类型的特征 数据预处理 特征的分箱 Best-KS ChiMerge 卡方分箱法 ... WOE编码 ... WOE编码的意义 ... 单变量分析和多变量分析 单变量分析 ...
  • 同理有一些变量在WOE编码前不相关性,但是WOE编码后相关了,所以做变量相关性分析,在WOE编码过后,带入模型之前合适 IV值是越高越好吗? 一帮来说,变量IV小于0.02就不要带入模型了,但是IV&gt;1.2过高,这....
  • 数据标准化处理

    2019-09-03 23:20:56
    关注公众号“番茄风控大数据”,获取更多数据分析与风控大数据的实用干货。  今天这篇文章介绍下数据标准化,也算是模型里一个很重要的内容。 WOE 先来介绍WOE,是信贷评分模型里经常会用到的一种编码转换...
  • 评分卡模型python实现

    千次阅读 2019-06-19 10:32:50
    评分卡模型 首先来介绍几个名词 变量分析:确定变量之间是否存在共线性,如存在高度相关,只保存最稳定、预测能力最高的那个。...单因子分析:检测各变量的强度,常用方法为:WOE、IV。 单因子分析 WOE(We...
  • (一)python-申请评分卡模型

    千次阅读 2019-03-29 23:03:55
    本文通过使用LendingClub的数据,采用卡方分箱(ChiMerge)、WOE编码、计算IV值、单变量和多变量(VIF)分析,然后使用逻辑回归模型进行训练,在变量筛选时也可尝试添加L1约束或通过随机森林筛选变量,最后进行模型...
  • 评分卡模型

    2019-06-20 15:24:16
    变量分析: ---变量一般分为连续变量与分类变量(数值与类别) WOE(证据权重): ---good为好用户 bad为坏用户 ---好用户概率p(good),坏用户概率p(bad) WOE = ln(p(good)/p(bad)) = ln((该组中为good的...
  • 申请评分卡模型 数据的预处理与特征构建(续) 课程简介:逻辑回归模型的特征需要是数值型,因此类别型变量不能直接放入模型中去,需要对其进行编码。...WOE与特征信息值 单变量分析与多变量分析 特征的分箱...
  • 过程主要包括变量分箱、变量的WOE(证据权重)变换和变量选择(IV值)、逻辑回归估算。 一个完整的评分卡流程主要包括以下几个步骤: 数据准备 数据探索性分析 数据预处理,包括缺失值、异常值、数据切分 特征分箱...
  • 信用评分模型概述

    2018-11-06 15:40:04
    依发展母体区分 通用性评分 征信机构评分 客制化评分 依使用时机区分 进件评分 行为评分 催收评分 评分模型开发 ... 变量分析 ...WOE迹象全数,ln(正常件占比/违约件占比),违约件占比高时WO...
  • 申请评分卡中的数据预处理和特征衍生(下) 在上一遍申请评分卡中的数据预处理和特征衍生(上),我们主要讲解了 ... 信用风险中的单变量分析和多变量分析 特征信息度的计算和意义 在申请评分卡这一块...
  • 信用评分卡模型在国外是一种成熟的预测方法,尤其在信用风险评估以及金融风险控制领域更是得到了比较广泛的使用,其原理是将模型变量WOE编码方式离散化之后运用logistic回归模型进行的一种二分类变量的广义线性模型...
  • 在计算woe以及相关的iv值的时候,需要首先对数据进行分箱,分箱一般采用qcut,即等频分组。 下面希望验证qcut(等频分组)-相同的值会在一组,即如果一组数据一半都是0,这些会被分在一组。 同时计算iv值并进行相关...
  • 数据科学 14 银行客户渠道使用偏好洞察案例(概念)13.1 客户画像与标签体系13.1.1 概念...基于目标变量的转换-WOE(基于证据的权重调整)13.3 连续变量的压缩13.3.1 主成分分析的思路13.3.2 变量聚类思路 13.1 客户...

空空如也

空空如也

1 2
收藏数 38
精华内容 15
关键字:

woe分析