您的位置:首页 > 其它

SAS逻辑回归之多分类

2017-02-28 11:00 295 查看
数据集Car(1728个观测值,6个自变量,因变量Car有unacc\acc\good\very good 4个取值。

分两个过程实现,代码如下:

 

1. PROC LOGISTIC 过程实现:

 

/*逻辑回归数据集Car(1728个观测值,每个含6个属性,目标变量Car(unacc\acc\good\very good))*/
/*导入数据集australian到逻辑库work中*/
proc import out=ds
datafile="\\vmware-host\Shared Folders\桌面\SAS\\data\\Car.csv"      /*文件路径*/
dbms=csv replace;                               /*文件类型指定*/
delimiter=',';
getnames=yes;                                   /*是否将第一列作为列名*/
run;

/****************************  使用交叉验证法选择最优模型  *****************************************/

/*利用10-折交叉验证法计算测试集上的预测准确率*/
%let k=10;                            /*定义宏变量-交叉验证的折数k*/
%let rate=%sysevalf((&k-1)/&k);       /*给出交叉验证的样本抽样比率(因为宏变量k的本质是文本,不能直接参与运算,要将其视为数字计算要用%evalf or %sysevalf)*/

/*生成交叉验证的10个样例,保存在cv中*/
proc surveyselect data=ds
out=cv            /*生成的样例全部放在数据集cv中*/
seed=158
samprate=&rate    /*抽样比率设定,宏变量rate的调用要加&*/
outall            /*输出全部数据*/
reps=10;          /*指定样本重复的次数*/
run;

/*交叉验证的生成数据集中,selected列为1表示该行为训练集样本,0表示测试集样本,这里为new_y赋值,
若selected=1,则可获得Y的值,若为0,该行的new_y为空。接下来给出new_y为空行的预测值。*/
data cv;
set cv;
if selected then new_y=Car;
run;

/*逻辑回归主程序 - 使用LOGISTIC进行有序多分类logit回归 - 10折交叉验证*/
PROC LOGISTIC data=cv ;
CLASS Buying Maint doors Persons Lug_boot Safety;
MODEL new_y=Buying Maint doors Persons Lug_boot Safety
/ LINK=cumLOGIT                /*拟合有序多分类logistic回归模型*/
SELECTION=STEPWISE           /*选择建模方式 - 逐步排除法*/
SLE=0.1 SLS=0.1 ;                /*拟合有序多分类logistic回归模型*/
by replicate;
score data=cv out=out1(where=(new_y='')) ;
RUN;

/*汇总交叉验证的结果*/
/*计算预测准确率(测试集中预测准确的样本占预测总样本的概率)*/
data out2;
set out1;
if Car=I_new_y then d=1;  /*d为真实值和预测值的误差,这里设无误差为1,有误差为0*/
else d=0;
run;

proc summary data=out2;
var d;
output out=out3 sum(d)=d1;   /*预测正确的个数*/
by replicate;
run;

data out3;
set out3;
acc=d1/_freq_;   /*预测准确率*/
keep replicate acc;
run;

title '交叉验证最优模型选择:组号、预测准确率';
ods output SQL_Results=cvparam;      /*保存最优模型结果在cvparam数据集中*/
proc sql ;
select replicate,acc f
4000
rom out3 having acc=max(acc);
quit;
ods output close;

/***************** 以交叉验证的最优结果组进行建模  *************************************/
/*以最优组合从cv的10个样例中拿出最优样例,作为训练集和测试集*/
/*取出最优组号对应的selected=1的行,作为训练集train,其余的作为测试集test*/
proc sql ;
create table train as
select * from cv where replicate in (select replicate from cvparam having replicate=min(replicate))
having selected=1;
create table test as
select * from cv where replicate in (select replicate from cvparam having replicate=min(replicate))
having selected=0;
quit;

TITLE '--------Logistic Regression - 数据集Neur - 建模方法 STEPWISE ---------------------------';

/* 逻辑回归主程序 - 通过训练集建立logistic模型*/
proc logistic data=train                      /*根据分类值从大到小选择建模组别,此处为yes*/
covout outest=Nout_step  /*输出建模参数估计值及变量间的协方差矩阵*/
outmodel=model            /*输出建模结果(若想要通过已有的建模结果来预测新数据集,这里可以用inmodel实现)*/
simple;                          /*输出变量的简单统计量*/
CLASS Buying Maint doors Persons Lug_boot Safety;
MODEL Car=Buying Maint Doors Persons Lug_boot Safety        /*logistic回归模型:反应变量=自变量1 2 3...*/
/ LINK=cumLOGIT                /*拟合有序多分类logistic回归模型*/
SELECTION=STEPWISE           /*选择建模方式 - 逐步排除法*/
SLE=0.1 SLS=0.1              /*变量在模型中的显著程度,默认为0.05*/
details                      /*输出模型界定的过程,包括自变量的检定和相关系数的值*/
lackfit                      /*输出HL拟合优度*/
RSQ                          /*模型解释度R方*/
STB                          /*输出标准化模型后的参数*/
CL                           /*参数估计和置信区间*/
itprint                      /*输出分析每个步骤的统计量*/
corrb                        /*输出变量的相关矩阵*/
covb                         /*输出变量的协方差矩阵*/
ctable                       /*输出不同阈值下的二分类变量的分组情况,类似于ROC曲线上的每个点的值*/
influence                    /*输出观察体中每个变量统计量,便于找出对分析结果影响力较大的观察体*/
IPLOTS ;                     /*针对influence的结果画出图形,影响力过高的观察体在图形上都会显得特别突出*/
score data=train out=train_pred outroc=train_roc;            /*通过score语句得到训练集上一系列的sensitivity和specificity,画出ROC曲线*/
score data=test
out=test_pred
outroc=test_roc;                      /*通过score来预测测试集,结果保存在test_pred中,画出ROC曲线*/
run;
quit;

/* 输出混淆矩阵 - 训练集*/
ods output CrossTabFreqs=ct_train;   /*保存混淆矩阵表(训练集)*/
proc freq data=train_pred;
tables F_Car*I_Car;
run;
ods output close;

proc sql;
create table acc1 as
select sum(percent) from ct_train where (F_CAR=I_Car and F_Car^='');
proc print data=acc1;
title '训练集上的预测准确率';
run;

/* 输出混淆矩阵及准确率等指标 - 测试集*/
ods output CrossTabFreqs=ct_test; /*保存混淆矩阵表(测试集)*/
proc freq data=test_pred;
tables F_Car*I_Car ;
run;
ods output close;

proc sql;
create table acc2 as
select sum(percent) from ct_test where (F_CAR=I_Car and F_Car^='');
proc print data=acc2;
title '测试集上的预测准确率';
run;


 

 

2.  PROC GENMOD 过程实现:

 

/*逻辑回归数据集Car(1728个观测值,每个含6个属性,目标变量Car(unacc\acc\good\very good))*/
/*导入数据集australian到逻辑库work中*/
proc import out=ds
datafile="\\vmware-host\Shared Folders\桌面\SAS\\data\\Car.csv"      /*文件路径*/
dbms=csv replace;                               /*文件类型指定*/
delimiter=',';
getnames=yes;                                   /*是否将第一列作为列名*/
run;

/****************************  使用交叉验证法选择最优模型  *****************************************/

/*利用10-折交叉验证法计算测试集上的预测准确率*/
%let k=10;                            /*定义宏变量-交叉验证的折数k*/
%let rate=%sysevalf((&k-1)/&k);       /*给出交叉验证的样本抽样比率(因为宏变量k的本质是文本,不能直接参与运算,要将其视为数字计算要用%evalf or %sysevalf)*/

/*生成交叉验证的10个样例,保存在cv中*/
proc surveyselect data=ds
out=cv            /*生成的样例全部放在数据集cv中*/
seed=158
samprate=&rate    /*抽样比率设定,宏变量rate的调用要加&*/
outall            /*输出全部数据*/
reps=10;          /*指定样本重复的次数*/
run;

/*交叉验证的生成数据集中,selected列为1表示该行为训练集样本,0表示测试集样本,这里为new_y赋值,
若selected=1,则可获得Y的值,若为0,该行的new_y为空。接下来给出new_y为空行的预测值。*/
data cv;
set cv;
if selected then new_y=Car;
run;

/*逻辑回归主程序 - 使用LOGISTIC进行有序多分类logit回归 - 10折交叉验证*/
PROC genmod data=cv ;
CLASS Buying Maint doors Persons Lug_boot Safety;
MODEL new_y=Buying Maint doors Persons Lug_boot Safety
/  DIST=multinomial
LINK=cumLOGIT;                /*拟合有序多分类logistic回归模型*/
by replicate;
output out=out1(where=(new_y='')) P=P ;
RUN;

/*汇总交叉验证的结果*/
/*计算预测准确率(测试集中预测准确的样本占预测总样本的概率)*/
data out2;
set out1;
if Car=I_new_y then d=1;  /*d为真实值和预测值的误差,这里设无误差为1,有误差为0*/
else d=0;
run;

proc summary data=out2;
var d;
output out=out3 sum(d)=d1;   /*预测正确的个数*/
by replicate;
run;

data out3;
set out3;
acc=d1/_freq_;   /*预测准确率*/
keep replicate acc;
run;

title '交叉验证最优模型选择:组号、预测准确率';
ods output SQL_Results=cvparam;      /*保存最优模型结果在cvparam数据集中*/
proc sql ;
select replicate,acc from out3 having acc=max(acc);
quit;
ods output close;

/***************** 以交叉验证的最优结果组进行建模  *************************************/
/*以最优组合从cv的10个样例中拿出最优样例,作为训练集和测试集*/
/*取出最优组号对应的selected=1的行,作为训练集train,其余的作为测试集test*/
proc sql ;
create table train as
select * from cv where replicate in (select replicate from cvparam having replicate=min(replicate))
having selected=1;
create table test as
select * from cv where replicate in (select replicate from cvparam having replicate=min(replicate))
having selected=0;
quit;

TITLE '--------Logistic Regression - 数据集Neur - 建模方法 STEPWISE ---------------------------';

/* 逻辑回归主程序 - 通过训练集建立genmod模型*/
proc genmod data=train ;
CLASS Buying Maint doors Persons Lug_boot Safety;
MODEL Car=Buying Maint Doors Persons Lug_boot Safety
/ DIST=multinomial
LINK=cumLOGIT ;
output out=train_pred P=P ;
run;
quit;

/* 输出混淆矩阵 - 训练集*/
ods output CrossTabFreqs=ct_train;   /*保存混淆矩阵表(训练集)*/
proc freq data=train_pred;
tables F_Car*I_Car;
run;
ods output close;

proc sql;
create table acc1 as
select sum(percent) from ct_train where (F_CAR=I_Car and F_Car^='');
proc print data=acc1;
title '训练集上的预测准确率';
run;

/* 输出混淆矩阵及准确率等指标 - 测试集*/
ods output CrossTabFreqs=ct_test; /*保存混淆矩阵表(测试集)*/
proc freq data=test_pred;
tables F_Car*I_Car ;
run;
ods output close;

proc sql;
create table acc2 as
select sum(percent) from ct_test where (F_CAR=I_Car and F_Car^='');
proc print data=acc2;
title '测试集上的预测准确率';
run;


 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: