《信用風險評分卡研究——基於SAS的開發與實施》學習筆記(2)
阿新 • • 發佈:2019-01-24
注:該系列文章都是學習馬姆杜 雷法特著的《信用風險評分卡研究——基於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 |
0 | 3 |
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必須是整數。