SAS邏輯迴歸之多分類

數據集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 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 ---------------------------';

/* 邏輯迴歸主程序 - 通過訓練集建立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;


 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章