zl程序教程

您现在的位置是:首页 >  其它

当前栏目

评分的切分—SAS实现

实现 SAS 评分 切分
2023-06-13 09:17:27 时间
文章载入中...

在模型开发好后,一般会以评分的形式输出,在使用评分时需要将评分切分成若干区间,那么选择从哪点切分?多少分切一段才合适呢?有时需要做的事情是不断地尝试。下面将该过程封装在SAS宏中,尽量使该过程自动化,减少人工时间。

见如下SAS宏代码:

其中:

Lib:SAS逻辑库

DSin:含评分的数据集

ScoreVar:评分字段

LowScore:评分最小切分点

delta:评分切分段长

CutNum:最大切分段数

DSout:输出分段后的数据集

SectProp:输出含每段比例的数据集

%macro Score_Cut(Lib, DSin, ScoreVar, LowScore, delta, CutNum, DSout, SectProp);
  
  data &Lib..&DSout(drop=i);
    set &Lib..&DSin;

    if &ScoreVar>0;

    if 0<&ScoreVar<&LowScore then
      Sect=1;

    do i=1 to (&CutNum-2);
      if &LowScore+&delta*(i-1)=<&ScoreVar<&LowScore+&delta*i then
        Sect=i+1;
    end;

    if &ScoreVar>=&LowScore+&delta*(&CutNum-2) then
      Sect=&CutNum;
  run;

  proc freq data=&Lib..&DSout noprint;
    table Sect/out=&Lib..&SectProp;
  run;

  data &Lib..&SectProp;
    set &Lib..&SectProp;
    PERCENT=PERCENT/100;
  run;

  goptions hsize=6 vsize=4;

  proc gchart data=&Lib..&SectProp;
    vbar Sect/type=pct sumvar=PERCENT discrete outside=percent;
  run;

  goptions reset=all;
%mend;

以某评分数据集为例:

%let Lib=XiaoShiTou;
%let DSin=ScoreSet;
%let ScoreVar=score;
%let LowScore=420;
%let delta=20;
%let CutNum=50;
%let DSout=ScoreSet_Sect;
%let SectProp=SectProp;
%Score_Cut(&Lib, &DSin, &ScoreVar, &LowScore, &delta, &CutNum, &DSout, &SectProp);

如果评分数据集中含有y变量,即值为1(坏)和0(好)的风险标识,则在评分切分时可以加入风险趋势。

将宏修改如下:

其中:

Lib:SAS逻辑库

DSin:含评分的数据集

ScoreVar:评分字段

LowScore:评分最小切分点

delta:评分切分段长

CutNum:最大切分段数

DSout:输出分段后的数据集

SectBadRate:输出含每段比例及坏账率的数据集

%macro Score_Cut_Bate(Lib, DSin, ScoreVar, YVar, LowScore, delta, CutNum, DSout, SectBadRate);
  
  data &Lib..&DSout(drop=i);
    set &Lib..&DSin;

    if &ScoreVar>0;

    if 0<&ScoreVar<&LowScore then
      Sect=1;

    do i=1 to (&CutNum-2);
      if &LowScore+&delta*(i-1)=<&ScoreVar<&LowScore+&delta*i then
        Sect=i+1;
    end;

    if &ScoreVar>=&LowScore+&delta*(&CutNum-2) then
      Sect=&CutNum;
  run;

  proc freq data=&Lib..&DSout noprint;
    table Sect/out=temp1;
    table &YVar*Sect/out=temp2;
  run;

  data temp1;
    set temp1;
    PERCENT=PERCENT/100;
    rename COUNT=total;
  run;

  data temp2;
    set temp2;

    if &YVar=1;
    rename COUNT=bad;
    keep Sect COUNT;
  run;

  proc sort data=temp1;
    by Sect;
  run;

  proc sort data=temp2;
    by Sect;
  run;

  data &Lib..&SectBadRate;
    merge temp2 temp1;
    by Sect;
  run;

  data &Lib..&SectBadRate;
    set &Lib..&SectBadRate;

    if bad=. then
      bad=0;
    BadRate=bad/total;
  run;
 
  * chart;
  goptions hsize=6 vsize=4;
  axis1 label=("Percent") minor=none; /* left */
  axis2 label=("BadRate") minor=none; /* right */
  axis3 label=("Sect") ; /* bottom */
  legend1 position=(top outside) across=1;
  legend2 position=(top outside) across=1;
  symbol1 c=black value=circle H=1.2;

  proc gbarline data=&Lib..&SectBadRate;
    bar Sect/ discrete sumvar=PERCENT
      raxis=axis1 maxis=axis3 legend=legend1
    ;
    plot / sumvar=BadRate axis=axis2 legend=legend2;
  run;

  quit;

  goptions reset=all;
%mend;

以同一评分数据集为例:

%let Lib=XiaoShiTou;
%let DSin=ScoreSet;
%let ScoreVar=score;
%let YVar=y;
%let LowScore=420;
%let delta=20;
%let CutNum=50;
%let DSout=ScoreSet_Sect;
%let SectBadRate=SectBadRate;
%Score_Cut_Bate(&Lib, &DSin, &ScoreVar, &YVar, &LowScore, &delta, &CutNum, &DSout, &SectBadRate);

下面减小评分切分的段长看看效果:

%let Lib=XiaoShiTou;
%let DSin=ScoreSet;
%let ScoreVar=score;
%let YVar=y;
%let LowScore=420;
%let delta=10;
%let CutNum=50;
%let DSout=ScoreSet_Sect;
%let SectBadRate=SectBadRate;
%Score_Cut_Bate(&Lib, &DSin, &ScoreVar, &YVar, &LowScore, &delta, &CutNum, &DSout, &SectBadRate);