《信用风险评分卡研究——基于SAS的开发与实施》学习笔记(2)

注:该系列文章都是学习马姆杜 雷法特著的《信用风险评分卡研究——基于SAS的开发与实施》一书时的学习记录和练手,供以后自己查看。如有不准确或不清楚的地方,请查找原著。

4.计算不同变量的WOE

  • 代码如下

<span style="font-size:12px;">%macro CalcWOE(Dsin,Invar,Dcvar,WOEvar,Dsout);
/*频率表*/
proc freq data=&Dsin noprint;
	tables &Invar*&Dcvar/out=Temp_Freqs;
run;

proc sort Temp_Freqs;
	by &Invar &Dcvar;
run;

/*by分组统计*/
data Freq_Invar;
set Temp_Freqs;
retain c0 c1 c0t 0 c1t 0;
by &Invar &Dcvar;
if first.&Invar then do;
	c0=Count;
	c0t=c0t+c0;
	end;
if last.&Invar then do;
	c1=Count;
	c1t=c1t+c1;
	end;
if last.&Invar then output;
drop &Dcvar Count Percent;
call symput("c0t",c0t);
call symput("c1t",c1t);
run;

/*计算WOE*/
data WOEds;
set Freq_Invar;
GoodList=c0/&c0t;
BadList=c1/&c1t;
if(GoodList>0 and BadList>0) then WOE=log(BadList/GoodList);
else WOE=.;
run;

/*输出数据集*/
proc sql noprint;
	create table &Dsout as
	select a.*,b.WOE as &WOEvar from &Dsin a,WOEds b where a.&Invar=b.&Invar;
quit;

%mend;

%CalcWOE(Ccmodel.Cc6,CustAge_b,Status,CustAge_WOE,Ccmodel.Cc7);

run;</span>

  • out

        过程步一般以某一个关键字开头,如tables,by等,而选型则在斜杠之后。

  • by, first, last

        在使用带有by语句的过程步时,一定要用sort语句对数据集进行排序;

        by语句根据变量对数据集进行分组;

        假设原数据example为:

id_1
id_2
num
1
1
5
3
03
2
0
6
2
1
4
3
1
7
1
1
5

      

<span style="font-size:12px;">/*读入数据*/</span>
<span style="font-size:12px;">data example;
input id_1 id_2 num;
datalines;
1 0 5
3 0 3
2 0 6
2 1 4
3 1 7
1 1 5
;
run;</span>


<span style="font-size:12px;">/*根据id_1,id_2排序,默认从小到大排列,在每个变量前加descending从大到小排列*/
proc sort data=example;
	by id_1 id_2;
run;</span>
<span style="font-size:12px;">结果如下:</span>
<table width="131" height="135" style="width: 131px; height: 135px;" border="1" cellspacing="1" cellpadding="1"><tbody><tr><td><span style="font-size:12px;">id_1
</span></td><td><span style="font-size:12px;">id_2
</span></td><td><span style="font-size:12px;">num
</span></td></tr><tr><td><span style="font-size:12px;">1
</span></td><td><span style="font-size:12px;">0
</span></td><td><span style="font-size:12px;">5
</span></td></tr><tr><td><span style="font-size:12px;">1
</span></td><td><span style="font-size:12px;">1
</span></td><td><span style="font-size:12px;">5
</span></td></tr><tr><td><span style="font-size:12px;">2
</span></td><td><span style="font-size:12px;">0
</span></td><td><span style="font-size:12px;">6
</span></td></tr><tr><td><span style="font-size:12px;">2
</span></td><td><span style="font-size:12px;">1
</span></td><td><span style="font-size:12px;">4
</span></td></tr><tr><td><span style="font-size:12px;">3
</span></td><td><span style="font-size:12px;">0
</span></td><td><span style="font-size:12px;">3
</span></td></tr><tr><td><span style="font-size:12px;">3
</span></td><td><span style="font-size:12px;">1
</span></td><td><span style="font-size:12px;">7
</span></td></tr></tbody></table>

<span style="font-size:12px;">/*by first*/
data example_1;
set example;
by id_1 id_2;
if first.id_1 then output;
proc print;
run;</span>
<span style="font-size:12px;">结果如下:</span>
<table width="129" height="78" style="width: 129px; height: 78px;" border="1" cellspacing="1" cellpadding="1"><tbody><tr><td><span style="font-size:12px;">obs
</span></td><td><span style="font-size:12px;">id_1
</span></td><td><span style="font-size:12px;">id_2
</span></td><td><span style="font-size:12px;">num
</span></td></tr><tr><td><span style="font-size:12px;">1
</span></td><td><span style="font-size:12px;">1
</span></td><td><span style="font-size:12px;">0
</span></td><td><span style="font-size:12px;">5
</span></td></tr><tr><td><span style="font-size:12px;">2
</span></td><td><span style="font-size:12px;">2
</span></td><td><span style="font-size:12px;">0
</span></td><td><span style="font-size:12px;">6
</span></td></tr><tr><td><span style="font-size:12px;">3
</span></td><td><span style="font-size:12px;">3
</span></td><td><span style="font-size:12px;">0
</span></td><td><span style="font-size:18px;"><span style="font-size:12px;">3</span>
</span></td></tr></tbody></table>


可见,first.id_1取得是每个id_1分组中的第一个数据;

同理,last.id_1取得是每个id_1分组中的最后一个数据。


  • retain

        对变量进行值的初始化和保留到下一个迭代步的作用。


  • 宏变量定义方法

      %let c0t=831;  ---不能在宏函数外调用

      call symput('c0t',c0t);---可以在宏函数外调用;另只能提取该变量最后一个值。

      select x into :y;---不能再宏函数外调用


  • %eval与%sysevalf

     宏的本质是文本,对宏进行数字运算时,要使用%eval与%sysevalf;

    %eval必须是整数。 









评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值