登录
首页精彩阅读sas信用评分之评分卡的生成
sas信用评分之评分卡的生成
2017-05-12
收藏

sas信用评分之评分卡的生成

今天介绍的“信用风险评分卡研究”中的生成评分卡的代码,哪一章生成评分卡我琢磨了好久,所以我觉得要是有疑惑的可以看下我写的这篇文章。至于理论的东西我就不说,基本要学评分卡的,这本书都是人手一本啦。
这个代码分为三部分:1、准备数据集。2、代码执行 3、生成sas代码。我今天也会按照这个顺序介绍下。
1  准备数据集。
(1)准备一个逻辑库,最好数据不要太多,可以是本地的也可以是数据库上的。
(2)生成变量码表:
    <1>、数值的码表是长这样子的:

 
      其中-1000和-999代表的是空值。Bin是分组,ll是下限,ul是上限。一定要这么      命名,不要问为什么      
     <2>、字符的码表长这样子:

   全部的变量码表的命名都是“new_q_lcc_six_map”,就是后面有个 “_map”的后缀。
 (3)准备变量的woe表。在这里强调一下,每个变量都是一张码表还有一张对应的woe表,woe表长下面这样子:


生成表的规则是,第一列是变量码表中的分组,名字是该变量名加上后缀“_b”,第二列就是该分组对应的woe值,命名也是叫woe。Woe值是等下要生成评分的。Woe的命名规则是,该变量名后面加后缀”_woe”。像上面这个数据集,他的数据集名称就叫“new_q_lsix_cnt_woe”。
准备数据集中的工作就这样子啦,强调一遍,这些数据集都必须全部放在我刚才说的那个你准备的逻辑库里面。
2 代码执行
%macro SCScale(BasePoints, BaseOdds, PDO, M_alpha, M_beta);

%local bb;

%let bb=%sysevalf(&PDO / %sysfunc(log(2)));

%let &M_Beta = &bb;

%let &M_alpha= %sysevalf(&BasePoints - &bb * %sysfunc(log(&BaseOdds)));

%mend;

%macro GenSCDS(ParamDS, Lib, DVName, BasePoints, BaseOdds, PDO, SCDS);


%local alpha beta;

%let alpha=;

%let beta=;

%SCScale(&BasePoints, &BaseOdds, &PDO, alpha, beta);

proc transpose data =&ParamDS out=temp_mpt;

run;

%local Intercept;


data temp_mptc;

 set temp_mpt;

length VarName $32.;

length MapDS  $32.;

length WOEDS $32.;

if _Name_ eq 'Intercept' then do;

  call symput('Intercept', compress(&DVName));

  delete;

  end;

  ix=find(upcase(_Name_),'_WOE')-1;

  if ix >0 then VarName=substr(_Name_,1,ix);

  MapDS=compress(VarName)||'_MAP';

  BinName=compress(VarName)||'_b';

  WOEDS=_Name_;

  Parameter=&DVName;


  if _Name_ ne '_LNLIKE_' and &DVName ne . ;

  keep VarName BinName MapDS WOEDS Parameter;

run;

  %local SCBase;

  %let SCBase = %sysfunc(int(&alpha + &beta * &Intercept));

%local i N;

data _null_;

 set temp_mptc;

  call symput('N',compress(_N_));

run;

%do i=1 %to &N;

 %local V_&i P_&i WOE_&i Map_&i;

%end;

data _null_;

 set temp_mptc;

  call symput('V_'||left(_N_),compress(VarName));

  call symput('B_'||left(_N_),compress(BinName));

  call symput('P_'||left(_N_),compress(Parameter));

  call symput('WOE_'||left(_N_),"&Lib.."||compress(WOEDS));

  call symput('Map_'||left(_N_),"&lib.."||compress(MapDS));

run;

%put &&Map_&i.;

proc sql noprint;

 create table &SCDS (VarName char(80), UL num, LL num,  Points num);

 insert into &SCDS values('_BasePoints_' , 0    , 0     ,  &SCBase);

run; quit;

%do i=1 %to &N;


   data temp1;

     set &&WOE_&i;

         bin=&&B_&i;

         VarName="&&V_&i";

         ModelParameter=&&P_&i;

   run;


   proc sort data=temp1;

    by bin;

   run;

      proc contents data=&&Map_&i out=temp_cont nodetails noprint;

      run;

      %local MapType;

      proc sql noprint;

       select Type into :MapType from temp_cont where upcase(Name)='CATEGORY';

      run; quit;

      %if &MapType =1 %then %do;

       Data &&Map_&i;

        set &&Map_&i;

         N_category=Category;

         drop category;

       run;

      %end;


   proc sort data=&&Map_&i;

    by bin;

   run;


    data temp_v;

     merge temp1 &&Map_&i;

        by bin;

      run;


      proc sort data=temp_v;

       by VarName;

      run;


    proc sort data=&SCDS;

       by VarName;

    run;


    data temp_all;

       merge &&SCDS temp_v;

        by VarName;

      run;


    Data &SCDS;

        set temp_all;

        drop &&B_&i;

      run;


%end;

data &SCDS;

  set &SCDS;

   if VarName = '_BasePoints_' then VarType=0;

   else do;

       Points=-WOE*ModelParameter * &beta ;

        if UL ne . and LL ne . then VarType=1;

        else if N_Category eq . then VarType=2;

        else VarType=3;

      end;


   drop WOE bin ModelParameter;

run;

proc sort data=&SCDS;

 by VarType VarName;

run;

/*proc datasets library=work nodetails;*/

/*delete temp1 temp_all temp_cont temp_mpt temp_mptc temp_v;*/

/*run; quit;*/

%mend;

%GenSCDS(ParamDS=raw.bb, Lib=raw, DVName=appl_status_1, BasePoints=540, BaseOdds=7.5, PDO=20, SCDS=cc);

代码使用:

%GenSCDS(ParamDS=raw.bb, Lib=raw, DVName=appl_status_1, BasePoints=540, BaseOdds=7.5, PDO=20, SCDS=cc);

ParamDS= 这个数据集就是你执行以下这个过程中outest=产出的数据集,其实就是各个变量的系数。这个说一下(event="1")这个参数,就是假设你的好客户是1的话,那使用这个outest=产出的数据集计算的评分,就是越高分越是好人。

Ods Output ParameterEstimates=aa ;

proc logistic data=test.RONG_total12 outest=bb ;

model APPL_STATUS_1(event="1")=

*****

/selection=s sle=0.05 sls=0.05 include=12;

output out=pp

    p=pred_status lower=pi_l upper=pi_u;

run;


Lib=填入你第一步哪里我说的准备的逻辑库。

BasePoints=基础分,具体的基础分是什么,书里有详细的解释。

BaseOdds=7.5  违约比正常,7.5那就是违约率大概是11%。具体看样本的坏样本量。

PDO=20 你想设置的刻度,这个你也自己看书,我不是很能表达这个参数的意义

SCDS=cc 输出数据集。

输出的数据集长的是这样子的:

就是每个变量的区间对应的分数,方便生成sql或者是sas代码去对初始变量执行。

3 生成sas代码

%macro SCSasCode(SCDS,BasePoints, BaseOdds, PDO, IntOpt,FileName);


proc sort data=&SCDS;

by VarType VarName;

run;


data _null_;

set &SCDS nobs=nx;

by VarType VarName;

file "&FileName";

length cond $300.;

length value $300.;


if _N_ =1 then do;

put '/*********************************************/' ;

put '/*********************************************/';

put '/***** Automatically Generated Scorecard *****/';

put '/*********************************************/';

      put '/************    SAS CODE             ********/';

      put;

      put '/* Scorecard Scale : */';

put "/*  Odds of [ 1 : &BaseOdds ] at  [ &BasePoints ] Points ";

 put "     with PDO of [ &PDO ] */";

      put;

put '/*********************************************/';

put '/*********************************************/';

      put ;

put '/********** START OF SCORING DATA STEP *******/';

put '/*********************************************/';

put '/*********************************************/';

      put;

put 'DATA SCORING;/********** Modify ************/';

put ' SET ScoringDataset; /********** Modify ************/';

      put;

put '/*********************************************/';

put '/*********************************************/';

end;


/* print the dataset RulesDS */


%if &IntOpt=1 %then xPoints=int(Points);

%else xPoints=Points; ;


if VarName="_BasePoints_" then do;

put '/*********************************************/';

      put "/* Base Points   */";

put '/*********************************************/';

put "Points=" xPoints ";";

                            end;

 else do;

   if first.VarName then do;

put '/*********************************************/';

put "/* Variable : " VarName "    *****/";

put '/*********************************************/';

                      end;

    value= "  THEN  Points=Points +("||compress(xPoints)||");";


    /* The rule */

    if VarType=1 then  do;/* continuous */

      if first.VarName then  cond='IF '||compress(VarName)||' LE ('||compress(UL) || ') ';

      else if last.VarName then cond='IF '||compress(VarName)||' GT ('|| compress(LL)||')';

    else cond='IF '||compress(VarName)||' GT ('|| compress(LL)||') AND '||compress(VarName)||' LE ('||compress(UL) || ') ';

                       end;

    else if VarType=2 then /* nominal string */

      cond = 'IF '||compress(VarName)||' = '|| quote(compress(Category)) ;


      else /* nominal numeric */

      cond='IF '||compress(VarName)||' = ('|| compress(N_Category)||') ';

     

      put "      " cond value;


 end;


 if _N_=Nx then do;

      put 'RUN;';

      put;

put '/*************END OF SCORING DATA STEP *******/';

put '/*********************************************/';

end;

run;

%mend;

%SCSasCode(SCDS=cc,BasePoints=540, BaseOdds=7.5, PDO=20,IntOpt=1,FileName=D:\工作\简版征信\scorecard.sas);

SCDS=填入你上个代码生成评分卡的那个输出数据集。

BasePoints=如上代码

BaseOdds=如上代码

PDO=如上代码

IntOpt=1的意思就是使所有的分值都四舍五入为整数。

FileName 你想把这个代码放在那里的路径。

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

最新资讯
更多
客服在线
立即咨询