SAS金融数据挖掘与建模:系统方法与案例解析
上QQ阅读APP看书,第一时间看更新

2.3 构建评分模型

2.3.1 算法选择

目前二分类模型常用的算法包括Logistic回归、神经网络和决策树类算法,三个算法的优缺点对比如表2-3所示。

表2-3 三种常用分类算法的优缺点对比

鉴于欺诈行为稀疏,属于小概率事件,需要对细部数据结构进行深入挖掘才能发掘欺诈特征,需要“专家”知识,因此决策树类算法较为适合。考虑到决策树的缺点,单纯应用决策树效果肯定粗糙,而由大量决策树组成的随机森林,则兼顾了决策树探查局部规律和Logistic回归把握全局的能力,非常适合欺诈评分场景。森林即很多棵树,随机则是指这些树彼此独立没有关联,随机森林算法就是每次在数据集中对观测样本和变量分别做随机抽样,构建出若干棵决策树,最终组合使用每棵树形成的规则和评分。对于评分或预测来说,每棵树可以看作一个特定领域(少数几个显著变量)的“专家”,针对每个客户的评分是所有“专家”综合打分的结果。随机森林无须像决策树那样剪枝,少数“专家”的打分误差并不能左右全局,因此相比单个决策树来说,随机森林模型更加准确、可靠。

由于随机森林兼具计算简单、建模速度快、结果容易解释、能够深入数据局部、预测能力强等优点,综合性能优于套袋算法、支持向量机、朴素贝叶斯、神经网络和决策树等分类算法,目前被广泛应用于信用评分和反欺诈等数据量大、响应率低的场景。本案例选取随机森林作为评分模型的算法。

2.3.2 模型训练

当准备好建模宽表后,就可以训练模型了。为了更客观地评估模型效果,通常将数据划分为两部分:一部分用来训练模型,另一部分用来评估模型效果。

1)将建模数据随机划分为两组,用变量Group区分,一组作为训练集(Group='t'),另一组作为验证集(Group='v'),前者训练模型,后者的目标变量置为缺失,使其不参与模型训练,只是应用评分规则打分,用于验证效果。在模型训练过程中,通过将验证集的目标变量置为缺失值,可以同时实现模型训练和评分,一举两得。如果数据量小,可以用这种方法。

2)先用一组数据训练模型,输出打分代码,针对另一组数据打分,评估模型效果。如果数据量大,建议用这种办法,本案例及对应的代码采用该方法。

多说一句,当欺诈客户占比非常低,欺诈样本可能不足以覆盖特征空间和各类欺诈场景时,为避免模型过拟合,可以对训练集采取欠采样方法,从正常客户中随机抽样,使欺诈客户占比在5%左右,验证集则无须调整,关于欠采样此处不再详述。下面是随机森林算法核心部分的SAS代码,各部分功能详见注释。

代码清单2-1 模型训练代码

        *指定模型训练后打分代码存放的目录;
        %let pth=C:\Users;

        *以下为模型训练;
        %macro rftrain(indat, p, outdat);

        proc contents noprint data=&indat. out=train_data_name;
        run;

        data train_data_name;
        set train_data_name;
        where type=1 and upcase(compress(name)) not in ( 'CSR_ID', 'TARGET') ;
        keep name;
        run;

        %do i=1 %to &p.;

        *每次随机筛选15个变量;
        proc surveyselect data=train_data_name out=var_01 sampsize=50; quit;

        proc sql;
            select distinct name into:var separated by ' '    from var_01;
        quit;

        *每次随机筛选20%的观测;
        data step01;
        set &indat.;
        x=ranuni(0);
        if x<=0.2;
        run;

        *构建决策树,criterion=entropy指定信息熵作为决策树分割的依据,可以选择信息增益、Gini系数等其他指标;
        Proc split data=step01 outleaf=leaf
        outimportance=importance outtree=tree outmatrix=matrix outseq=seq
        criterion=entropy
        assess=impurity
        maxbranch=3
        maxdepth=5
        exhaustive=1000
        leafsize=30
        splitsize=30
        subtree=assessment;
        code file="&pth.\sas_rule&i..txt";
        describe file="&pth.\rulefinal&i..txt";
        input  &var./ level=interval;
        target target/level=binary;
        run;
        %end;
        %mend;

        * fraud_train_samp是建模数据,训练1000棵决策树,训练结果输出到表score_rf;
        %rftrain(fraud_train_samp,1000, score_rf);

运行上面代码,输出评分规则到指定文件C:\Users\fraud_rule.txt,同时产生每个客户的欺诈评分,如表2-4所示。Fraud为每个客户实际的欺诈标签,“1”表示有过欺诈;Target为模型训练时的目标变量,验证集全部置为缺失值;Pr是模型对每个客户的欺诈评分。考虑到模型或多或少存在过拟合的情况,该评分结果仅用于评估模型的拟合情况,模型质量将使用验证数据评估。

表2-4 欺诈评分示例(score_rf)

2.3.3 模型评估

由于随机森林算法是集合了成百上千个“专家”(决策树)的综合评分,每个“专家”只选用其中的少数几个变量进行打分,因此很难评估每个变量的显著性以及与最终评分的函数关系,只能关注最终的评分是否准确可靠。

评分模型是否准确可靠,需要使用验证集的评分进行评估,首先使用上一步骤得到的打分代码,对验证数据进行打分。

代码清单2-2 模型打分代码

        %macro rfscore(indat, p, outdat);
        %do i=1 %to &p.;

        data score_&i.;
        set &indat.;
        %include "&pth.\sas_rule&i..txt";
        p_&i.=p_target1;
        keep csr_id p_&i.;
        run;

        proc sort data=score_&i.;
        by csr_id;
        run;
        %end;

        proc sort data=&indat.(keep=csr_id target) out=tmp1;
        by csr_id;
        run;

        data &outdat.;
        merge tmp1 %do i=1 %to &p.; score_&i. %end;;
        by csr_id;
        pr=sum(of p_1-p_&p.)/&p.;
        keep csr_id target pr;
        run;

        %mend;

        *对验证数据fraud_valdt_data打分,结果输出到表score_valdt;
        %rfscore(fraud_valdt_data,1000, score_valdt);

通过对验证数据打分,生成每个客户的欺诈评分,结果输出到表score_valdt。模型的目标是将欺诈客户锁定在尽可能小的范围内,既要能够“抓住”尽可能多的欺诈客户,又要尽量减少误报,因此识别率和误报率是两个主要的评估指标。按照模型评分Pr对全部客户从高到低排序、分组,这里等分100组,分别计算每组的Pr平均值、实际欺诈人数及其占比,实现代码如下,分组结果如表2-5所示(前4列)。误报率AFPR为各组累计人数/累计欺诈人数,第一组为4(4481/1027)表示每预报4人可抓获1个欺诈客户;识别率ADR为累计欺诈人数/全部欺诈人数,第一组为18%(1027/5722)表示预报的4481人(占全部客户的1%)中覆盖了全部欺诈客户的18%。

表2-5 识别率和误报率的计算方法

①AFPR=纵向累积(Nbr)/纵向累积(Fraud Nbr)

②ADR=纵向累积(Fraud Nbr)/合计(Fraud Nbr)

代码清单2-3 模型评估代码

        %macro Fit(in, out, grp_cnt, pred_var, act_var);

        data work.tt1;
        set ∈
        run;

        data _null_;
        set work.tt1 nobs=obs ;
        call symput("Base", obs/&grp_cnt);
        stop;
        run;
        proc sort data=work.tt1;
        by  descending &pred_var;
        run;

        data work.tt1;
        N=_N_;
        set work.tt1;
        format Grp2 4.0;
        Grp2=INT((N-1)/&base);
        run;

        proc means data=work.tt1 nway noprint;
        class  Grp2 ;
        output out=&out mean(&pred_var &act_var)=pred_evt actual_evt;
        run;

        %mend;

        *fit_valdt就是表2-5前五列;
        %Fit(score_valdt, fit_valdt,100, pr, fraud);

运行上述评估代码,得到如表2-5所示的前五列,基于此可进一步计算误报率、识别率等具体的评估指标。

如图2-2所示,横坐标为误报率,纵坐标为识别率,显然,随着误报率的增加识别率也在增加,拐点出现得越早,模型效果越好。这里拐点的识别率=80%,对应误报率为20:1,也就是说,根据评分每处理20个警报即可抓获1个欺诈客户,按该方法可以预防80%欺诈事件的发生。

图2-2 欺诈评分模型效果评估