登录
首页精彩阅读SAS信用评分九步曲之第一步数据清洗
SAS信用评分九步曲之第一步数据清洗
2017-04-02
收藏

SAS信用评分九步曲之第一步数据清洗

累积了一段时间的建模经验了,这次想把我在建模中用的代码分批分享出来,可能写的东西不是你能用到的,毕竟我们接触到的数据都不一样。但是譬如文本清洗之类的,看我之前的文章“正则式”还是可以找到解决方法的。我觉得数据面并不多,就是就我现有的数据做的数据处理。希望大神也可以指正我在建模中用的不恰当的处理数据的方式。那么就开始今天的分享啦。

今天主要想分享给大家的有三个代码:“缺失值填充”,“变量缺失值比例”“异常值检测”。

1、缺失值填充

缺失值补充这部分的代码是我在遇到譬如主表的数据是有的,但是left join的时候没有这个数据,但是他并不是缺失,只是客户真的没有。譬如房屋贷款笔数,假设客户没有房屋贷款,那么这个变量就是缺失的,但是他并不是缺失,他实际上没有,所以要填补一个零。这段代码是对数值的字符的整张数据集的变量的处理。

%macro missing(data);

data aa;

set &data;

array arr1{*} _NUMERIC_ ;

array arr2{*} _CHARACTER_ ;

do i = 1 to dim(arr1);

if missing(arr1(I)) then do;

arr1(i)=0;

/*这里的arr1(i)=0;根据自己的需要,要0就是0也可以是别的值*/

end;

if missing(arr1(i)) then do;

arr1(i)=0;

end;

end;

do i = 1 to dim(arr2);

if missing(arr2(I)) then do;

arr2(i)="0";

end;

end;

run;

%mend;

Data填入数据集

代码我都是调试好的,所以可以直接用。

2、变量缺失值比例

经过缺失值填补之后,但是还有些改缺失还是缺失的,这时候要对变量做变量缺失率的检查,我这边是对于变量缺失率达到70%的就去掉这个变量。具体缺失比率在多少就不要,还是要看自己的业务需求。那上代码吧。这部分的代码是参考另外这个公众号的妹纸写的代码公众号是:数据分析sas和r和python

data tmp11;

set raw.jxl_total_t;

array arr1{*} _NUMERIC_ ;

array arr2{*} _CHARACTER_ ;

length variable $50;

do i = 1 to dim(arr1);

if missing(arr1(i)) then do;

variable =vname(arr1(i));/*数值型缺失*/

output;

end;

end;

do j = 1to dim(arr2);

if missing(arr2(j)) then do;

variable = vname(arr2(j)); /*字符型缺失*/

output;

end;

end;

keep variable;

run;

proc sql noprint;

select count(*) into : N from raw.jxl_total_t;

create table miss as

select variable label = "缺失变量名",

count(*) as frequency label = "缺失频数",

input(compress(put(calculated frequency / &N.,percent10.2),'%'),best32.) as percent label = %nrstr("%缺失占比")

from tmp11

group by variable

having percent>70;

quit;

/*统计缺失频数和占比*/

3、异常值检测

剔掉缺失严重的变量,那么下一步就是做异常值的检查,不要让异常值坏了拟合结果,毕竟数据也是存在一颗老鼠屎坏了一锅粥。异常值我之前在前面的文章中有用到聚类,有3倍标准差聚类的话可能对于字符变量可能好些,3倍标准差的话需要要求数据呈正态分布,但是我的数据貌似很难达到这个需求。如果需要以上提及的聚类或者是3倍标准差可以点:路径查看啦。那么一下这段代码我用的箱形图来找出异常值,并且将在区域以外的数据集用上下界的值代替。分享的代码没有固定的iqr,写的条件譬如,异常值都在1.5倍iqr达到1%,那么就将这部分的值判断为异常值,假设现在是3iqr外的异常值达到1%或者小于1%,但是2.5iqr以外的数据已经达到了1.5%,那么就行选定3iqr以外的数据为异常值异常值检查只针对数值变量。我是不是废话很多,我很怕你们理解不了我的意思,如果不知道iqr是什么的,先百度下拉。接下来上代码。

%macro pub(data,var);

PROC UNIVARIATE DATA= &data.(where=(&var.^=.)) NOprint;

VAR &var.;

OUTPUT OUT=qdata  Q1=q1 Q3=q3 QRANGE=iqr STD=VSTD   Mean=VMean;

RUN;

DATA _null_;

SET qdata;

call symput('STD', VSTD);

call symput('Mean', VMean);

CALL SYMPUT("q1",q1);

CALL SYMPUT("q3",q3);

CALL SYMPUT("iqr",compress(iqr));

RUN;

%let qa=%sysevalf(&q1. -(1.5*&iqr.));

%let qb=%sysevalf(&q3. +(1.5*&iqr.));

%let qc=%sysevalf(&q1. -(2*&iqr.));

%let q4=%sysevalf(&q3. +(2*&iqr.));

%let q5=%sysevalf(&q1. -(2.5*&iqr.));

%let q6=%sysevalf(&q3. +(2.5*&iqr.));

%let q7=%sysevalf(&q1. -(3*&iqr.));

%let q8=%sysevalf(&q3. +(3*&iqr.));

%put &q1.&q8.;

DATA outliers;

SET  &data.(where=(&var.^=.));

LENGTH severity $2;

severity="";

IF &var. <= &qa. OR &var. >= &qb. THEN   severity="1";

else IF &var. <=  &qc. OR &var. >=  &q4. THEN  severity="2";

else IF &var. <= &q5. OR &var. >=  &q6. THEN  severity="3";

else IF &var. <= &q7. OR &var. >=  &q8. THEN severity="4";

IF severity in ("1","2","3","4") THEN OUTPUT outliers;

RUN;

proc sql;

%do f=1 %to 4;

select count(*) into:outliers_&f. from outliers where severity="&f.";

%end;

select count(*) into :n from  &data.;

quit;

%put &outliers_1. &outliers_2.;

%put &n.;

%let out_1=%sysevalf(&outliers_1./&n.);

%let out_2=%sysevalf(&outliers_2./&n.);

%let out_3=%sysevalf(&outliers_3./&n.);

%let out_4=%sysevalf(&outliers_4./&n.);

data &data.;

set &data.;

length &var._1 8.;

if &out_1.<0.01 and &var.^=. then do;

if &var. <=&qa.  then &var._1=0;

else if &var. >=&qb. then &var._1=&qb.;

else &var._1=&var.;

end;

if &out_2.<0.01 and &var.^=. then do;

if &var. <=&qc.  then &var._1=0;

else if &var. >=&q4. then &var._1=&q4.;

else &var._1=&var.;

end;

if &out_3.<0.01 and &var.^=. then do;

if &var. <=&q5.  then &var._1=0;

else if &var. >=&q6. then &var._1=&q6.;

else &var._1=&var.;

end;

if &out_4.<0.01 and &var.^=. then do;

if &var. <=&q7.  then &var._1=0;

else if &var. >=&q8. then &var._1=&q8.;

else &var._1=&var.;

end;

else do ;

&var._1=. ;

end;

drop &var. ;

rename &var._1=&var. ;

run;

%mend;

pub(data,var) data填入数据集,var填入你要检测的变量。

代码中有很多可以优化地方,譬如那些重复的东西就可以用循环的,你问我为什么不用,是因为我懒得改了,如果你想自己优化一下,就自己优化一下吧。如果我后续优化了,再分享给你们也可以。


数据分析咨询请扫描二维码

客服在线
立即咨询