基于R语言的用户征信行为分类预测模型搭建总结

来源:互联网 发布:打字淘宝兼职是真的吗 编辑:程序博客网 时间:2024/04/29 13:04

数据集:15万行数据量,11个数据维度。目标变量为是否有重大违约倾向(定义为超过90天没有还贷)


建模流程:

1. 缺失值处理

发现数据集的数据缺失主要集中在亲属数量和月收入两个属性。其中,亲属数量却缺失属性为3000多条,且这3000多条记录中,月收入属性也同时缺失,故直接删除。

对于有1万多条缺失记录的月收入,采用线性回归和多重插补填补缺失值。

进行线性回归时,可能由于其他自变量与月收入的相关关系不大,所以尽管拟合指标非常好,真实的拟合值还是有非常大的误差。

对于线性回归而言,数据分布符合基本假设是很重要的。在这里,主要采取了如下三个方法:

(1)检验同方差性

library(car)

ncvTest(mymodel)

可根据提示的Suggested power transformation值,对响应变量进行幂次变换,经过变换,非恒定的误差方差变得平稳。这一改进举措,使R-square从0.7上升到0.9。

(2)检验因变量与自变量间的线性关系

library(car)

crPlots(mymodel)

开始,图形显示非线性。在非线性的属性“age”中,我对比了添加年龄的二次项和log项,结果发现添加二次项后的模型中,年龄与因变量完美符合线性关系。同时,添加对数项的模型也比单纯的age线性项效果更好。这一举措,使R-square从0.9提升到0.97。
(3)去除噪声值

这一项举措也是影响很大,但是没有前两者的改变那么根本和激动人心。噪声值的处理非常艺术,在大数据量中,可能会有很多噪声值,但是最好不要全部都去掉。删不删除,删除几个,都是要拿捏的。我认为,这里主要还是要考虑一个性价比的问题。比如,当我删除前三个cook值最大的离群点时,模型的提升非常显著(当时拟合优度还比较低),但当继续删除时,发现模型的提升并没有那么显著了。那么这时,我认为就应当适可而止。

如果在噪声值处理这部分,有相关的数据处理包可以将“适可而止”转化为定量地处理噪声值时,还请各位同行告知。


2.异常值处理

首先,利用箱线图删除明显异常点。

boxplot(mymodel$my_attr)

或根据业务情况经过summary数据,查看数据异常值,选择删除。

接下来的量化筛选,个人比较喜欢用的方法是使用线性回归模型的cook值。

这个数据集的异常值非常的多。仅Debt_ratio一项,大于1的数据项就超过了20%(这里是用 quantile()定位查看的)。由于无从得知异常原因和数据来源,也由于时间关系,直接选择删除。其实如果时间充裕,可以考虑线性回归替换,或是均值替换等等,同缺失值处理方式类似。

另外,对于月收入一项,更多的是从业务角度考虑。运用箱线图删除明显异常数据点后,再利用线性回归查看强影响点。这里我又删除掉了1000多行。

这个样本数据有点问题,异常值处理这步感觉有点粗放了,直接将数据集从15万条样本,删除到11万条左右。理论上这样并不太好,但是更粗放的还在后面= =


3.样本平衡

需要处理的问题是还贷异常行为。这是一个典型的样本不平衡问题。具有还贷异常行为的样本只是少数,具体到这个数据集,在删除异常数据之前,0:1的比率达到67:1,删除异常值后,这个比率达到了87:1。也就是说,只有不到2000行的欺诈样本。此时我的内心是崩溃的,不过这可以理解。从常理(即粗浅的业务角度)来判断,在信用出现异常的样本中,更有可能因为这样那样的原因出现异常值,如信息采集不正确(主观或客观),或数据项本身异于常人等。

没有办法,必须要对样本进行样本平衡处理。这里采用了过采样与欠采样结合的抽样方法。其实还有很多其他解决样本不平衡问题的方法,比如调整小样本权值,代价敏感,人为生成数据等。这里为了简便,采用过采样+欠采样,调整后,比例为1:1。

orgData3<-orgData2[sample(c(a0,a1)),]

过采样+欠采样的样本数值得考量。对于小样本来说,我保守地没有复制太多。原因是重复样本太多,可能会过大地改变数据分布,影响模型准确率。这点需要验证。有一个说法是,1:14,是常见的“好”比例之一。我这里调节为1:1,其实是极大地改变了数据的分布,这就造成一个影响,后面构建的模型预测真实数据时,有很多把“0”分为“1”的误判,换句话说,我构造的是数个非常严格的分类器,宁可错杀三千,绝不放过一个。但是带来的好处则是,将欺诈行为判别为良民的概率比较小。而对于欺诈行为预测来说,将坏人判为好人,比将好人判为坏人的代价大得多。具体应用时,需要看业务场景,再来调整样本比例。

还有sample这个函数。在这里,sample是必要的,打乱正负样本出场的顺序。否则有可能另一类样本还没出场,算法就收敛了。所以要混合均匀。


4. 模型构建

这里选用了CART决策树。神经网络。SVM。逻辑回归和我最喜欢的随机森林,分别构建了五个模型。这里分别说一下。

(1)随机森林

先说我最喜欢的随机森林。强壮,稳健,鲁棒,性能高,效果好。不需要处理缺失值(虽然前面为了其他的算法还是处理了),噪声值不敏感(同上),不需要数据标准化,可以说是最不挑食的一个分类算法,更为难得的是速度快(nlogn),分类效果好且稳定。具体到这个数据集,构建了10棵子树(小森林),在测试集上的Accuracy达到了0.95,AUC值达到了0.995!我简直怀疑是不是有什么bug。整个五个模型中,只有基于高斯径向基的SVM胜过了它,但是随机森林的算法运行效率和适用范围完胜啊!

非常友好的算法。还可以帮助进行高维数据筛选,

(2)SVM

既然说到了SVM,就顺势说说它。SVM作为一种非线性方法,需要进行标准化,要求小样本量,异常缺失敏感,最关键的是!

速度慢,速度慢,速度慢。慢死了啊啊啊。

对于只有n=11,m = 16000的数据集,一次运行大概20分钟。(R语言,python或c++会更高效。)更别说,在这之前还用tune.svm()寻找了一遍最优参数,大概45个模型,运行了一夜多。深刻地理解了SVM调优是个巨大的问题。不过预测速度比建模速度要快很多,但相较于其他算法也是挺慢的。

最优参数gamma=16,cost=4。进行建模。

好处在于,这个样本相当于一个小样本,虽然运行时间有点长,但对于采用高斯径向基的SVM,效果真是好的没的说。得到了0.998的AUC值,我简直。。心情难以言说。

但二者相比,我可能还是会采用随机森林。因为怎么说呢,必须要衡量性价比嘛。只有0.003的差距,而且在性能方面胜出这么多,而且适用数据范围更广,随机森林应该是不错的。

说到这里,再简单谈一下数据量和方法的选择。

n relatively > m:  for example, n = 10000, m = 10-1000,不建议选用复杂模型,尤其是容易过拟合的神经网络。可选择逻辑回归或不带核的SVM。(笔者注:仔细进行变量筛选再选用合适方法。)

relatively proper: for example, n=1-1000, m=10-10000,选用带高斯核函数的SVM,效果远胜于logistic回归和线性SVM。

n relatively < m: for example, n=1-1000, m>50000,使用SVM会非常慢,解决方法是创造增加更多维度,然后使用logistic回归或不带核函数的SVM。(笔者注:可以试着使用一些复杂模型,如神经网络,随机森林等。)

注:以上资料来自Coursera上的Machine learning from Stanford】

(3)CART决策树

tree-based算法。不需处理缺失值和异常值,不需要标准化。但是很遗憾,作为一个简单分类器,CART决策树在这个数据集上的表现并不好。共11个维度,真正划分只用到了4个维度,maxdepth = 3,且测试集上的AUC只有0.836,有种欠拟合的倾向。我完全没有剪枝,网上资料都是解决过拟合比较多,欠拟合的资料比较少。或许应该试一下C4.5算法。总之,这个模型PASS。

(4)神经网络

由于神经网络具有过拟合倾向,是一个比较复杂的模型,所以变量筛选极度重要。在建模前,我删除了相关度>0.6且统计显著的自变量。这里发现一个现象,样本平衡后的数据集(相对小样本)中,数据的相关性要高于平衡前的大样本。换句话说,随样本量的减小,数据之间的关联程度降低了。这点比较好理解,但是否具有普适性,仍有待验证。

需要确定转换函数、隐藏节点数、最大迭代数,最大允许误差,学习效率。还要注意,这个算法是需要数据标准化滴。

转换函数为sigmoid,值得考量的是隐藏节点数。本着n = sqrt(ninput*noutput)的原则,先确定为3。然而结果并不好。设定为6之后表现好了许多,经综合考虑,最终确定节点数为4。耐人寻味的是,随着隐藏节点数的进一步增大,模型的表现反而略有所下降。节点数太多,会增加了过拟合的风险,运行速度也变慢了。

(5)逻辑回归

没啥好说的,经典的统计建模方法,注意变量筛选。这个方法在该数据集上也表现出了比较好的效果,AUC值为0.917。同时注意模型的可解释性,这点是明显优于随机森林的,随机森林是黑盒算法,可解释性弱。同时,逻辑回归的效率非常高,适于处理大样本。这里模型的选择可能要trade-off一下。


最后,统一说一下标准化。tree-based算法不需要标准化。神经网络、SVM需要标准化,逻辑回归最好标准化。但在本次建模中,经过对比,发现标准化建模结果与未标准化建模结果AUC值等同。但这只是小测试集上预测的结果。

最后的最后,所有的模型的结果汇总如下。



如图所示。各个模型在各数据集上的AUC值。
testdata是4000行样本量的小样本测试集。orgData是110000行样本量的大样本数据集。
可以看到,随机森林和SVM无论在哪个数据集上都完胜,SVM在大样本上更是出现了0.999这种逆天的AUC值,真是效果拔群。这意味着,在11万个样本量中,只有720个样本被分错,并且没有将欺诈行为判别为好行为的误判,所有的异常行为都被识别,几乎杜绝了损失。
但是有几个神奇之处。
神奇之处一:除了神经网络,标准化对SVM和逻辑回归几乎没有效果,小样本的AUC值维持不变,大样本上的AUC值反而还降低了。SVM标准化模型在大数据集上的AUC居然还下降到了0.755,把所有的样本都标记为好行为,根本不能使用。如此不稳定,真是匪夷所思。
神奇之处二:可以看到,有些模型,如随机森林,CART,SVM,nnet,logistic,总之就是没有标准化建模的模型,在大数据集上反而表现出了更好的效果。而剩余标准化建模的模型,在大样本数据集上效果都有所下降。
原因分析:由于标准化模型是根据样本平衡后的训练集(16000条样本)构建,这个小数据集的数据分布与大样本的数据分布有差异,使得构建的模型不能完全映射到大样本的数据分布上。尤其是那个标准化的SVM模型,有过度拟合大样本的严重嫌疑。
解决方法:调整样本类别比例,适当扩大良民比例,这是为了扩大用于构建模型数据集的样本量,使得数据集尽可能反映原始样本数据分布。重新建模。再来比较看是哪种抽样方法效果好。

#----------------------------------我是怀疑的分割线---------------------------------------
由于有些模型的效果实在是太好了,使得我对他们充满了怀疑。
原来的训练/测试集划分方法是,从20000条样本中4:1划分。但有一个问题,这2万条样本中,有1万条标记为欺诈的样本是由原始数据的2000条欺诈样本过抽样采集的。这意味着,在用于构建模型的16000条样本中,有8000欺诈样本,很可能全部覆盖了原来的2000条欺诈样本,也就是说,在构建分类器时,它已经遇到过所有的欺诈样本了。那么当它再预测大数据集时,由于所有的欺诈样本它都遇见过,那么在欺诈样本上出错的概率也不会提高。

于是我想出了一种新的构建测试集的方法。
对原始的2K条欺诈样本,采用4:1比例划分为两个样本集,对这两个样本集分别进行过采样。再按照比例,对良民样本进行欠采样,再将采样过后的良民样本和欺诈样本合并成训练集和测试集。

训练集=过采样(1600欺诈)+欠采样(良民样本1)

测试集=过采样(400欺诈)+欠采样(良民样本2)


0 0
原创粉丝点击