版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/T_steve7/article/details/54412596
建模的时候,用到的是连续变量,对于本身是连续变量的变量,可通过主成分以及变量聚类来减少变量数量,对于本身是分类变量的变量,可通过重编码或WOE转换以减少建模的难度,不要把变量的压缩都放到建模后期,那样很耗时。
重编码
查看所有变量出现的次数,将那些出现次数过少的,例如0,1次的归为一类,以减少分类变量的数量。(这些数量为0的出现,在取后面WOE转换取对数的时候会出问题。)
accepts <- read.csv("accepts.csv")
table(accepts$vehicle_make,accepts$bad_ind)
#与目标变量求交叉表,查看数据是否存在似不完整性问题
library(sqldf)
freq<-data.frame(table(accepts$vehicle_make))
names(freq)<-c("vehicle_make","freq")
accepts1<-sqldf("select a.*,b.freq
from accepts as a
left join freq as b
on a.vehicle_make=b.vehicle_make")
accepts1$vehicle_make<-as.character(accepts1$vehicle_make)
accepts1[accepts1$freq<10,]$vehicle_make<-"other"
#将出现次数低于10次的都归为一类
WOE转换-证据权重转换
重编码可减少水平数量,但是仍然不是连续变量,只有在有监督模型中才可以进行WOE(Weight of Evidence)转换,例如分类模型。
WOE转换后然后就变成一个连续变量了,然后在用主成分或者变量聚类再次减少变量数量再建模。
基于目标变量的WOE转换
freq<-data.frame(table(accepts1$vehicle_make,accepts$bad_ind))
#把目标变量Var2修改成容易辨识的组,以便于后面cast
freq$Var2<-paste("group",freq$Var2,sep="")
library(reshape)
#将Var2按不同水平截取并纵向排列,如果~左右调换,则为横向排列,可试一下再定
freq_w<- cast(freq,Var1~Var2)
#分别计算cast后各类的频次之和
freq_sum<-sqldf("select sum(group0) as group0_sum,
sum(group1) as group1_sum
from freq_w as a")
#根据上面两个表计算cast后的不同水平的占比
freq_p<-sqldf("select a.*,
a.group0/(b.group0_sum+0.0) as group0_p,
a.group1/(b.group1_sum+0.0) as group1_p
from freq_w as a, freq_sum as b")
#增加一列只求其中一个的占比
freq_p$perc<-freq_p$group1/(freq_p$group0+freq_p$group1)
freq_p$woe<-log(freq_p$group1_p/freq_p$group0_p)
accepts2<-sqldf("select a.*,b.woe as vehicle_make_woe
from accepts1 as a
left join freq_p as b on a.vehicle_make=b.Var1")