數據集這裏用的是australian,有14個自變量Xi,一個因變量Y,Y值只取0或1。
代碼如下:
/*邏輯迴歸數據集australian(690個觀測值,每個含14個屬性,目標變量y(0、1))*/
/*導入數據集australian到邏輯庫work中*/
proc import out=aus
datafile="\\vmware-host\Shared Folders\桌面\SAS\\data\australian.csv" /*文件路徑*/
dbms=csv replace; /*文件類型指定*/
delimiter=',';
getnames=yes; /*是否將第一列作爲列名*/
run;
/*查看數據集*/
proc print data=aus;
run;
/**************************** 使用交叉驗證法選擇最優模型 *****************************************/
/*利用10-折交叉驗證法計算測試集上的預測準確率*/
%let k=10; /*定義宏變量-交叉驗證的折數k*/
%let rate=%sysevalf((&k-1)/&k); /*給出交叉驗證的樣本抽樣比率(因爲宏變量k的本質是文本,不能直接參與運算,要將其視爲數字計算要用%evalf or %sysevalf)*/
/*生成交叉驗證的10個樣例,保存在cv中*/
proc surveyselect data=aus
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=Y;
run;
/*邏輯迴歸主程序 - 10折交叉驗證*/
ods output parameterestimates=paramest /*輸出交叉驗證的參數估計值*/
association=assoc; /*輸出交叉驗證的C統計量*/
proc logistic data=cv des; /*des控制以Y=1來建模*/
/* class new_y (param=ref ref='yes'); 若new_y是分類變量,則用class對其參數化處理,這裏選擇處理方式爲ref,以“yes”作爲參考水平,以便於後續odds的計算*/
model new_y=X1-X14 / SELECTION=STEPWISE SLE=0.1 SLS=0.1;
by replicate; /*以交叉驗證的組別來分組建模*/
output out=out1(where=(new_y=.)) /*只給出測試集的預測結果(即new_y爲空的樣本)*/
p=y_hat;
run;
ods output close;
data out1;
set out1;
if y_hat>0.5 then pred=_LEVEL_ ; /* PHAT爲logistic方程針對每個觀察體計算的屬於該組別的概率,若PHAT>0.5,則屬於該組別(這裏level爲1),否則,屬於另一組別 */
else pred=0; /* 本例爲二分類,概率依照level(1)計算,因此另一類爲0 */
run;
/*彙總交叉驗證的結果*/
/*計算預測準確率(測試集中預測準確的樣本佔預測總樣本的概率)*/
data out2;
set out1;
if Y=pred then d=1; /*d爲真實值和預測值的誤差,這裏設無誤差爲1,有誤差爲0*/
else d=0;
run;
proc summary data=out2;
var d;
by replicate;
output out=out3 sum(d)=d1; /*預測正確的個數*/
run;
data out3;
set out3;
acc=d1/_freq_; /*預測準確率*/
keep replicate acc;
run;
/*結果中加入交叉驗證的C統計量(度量觀測值和預測值之間的一致性,越大越好)*/
data assoc;
set assoc;
where label2="c";
keep replicate cvalue2;
run;
/*合併交叉驗證的統計結果*/
data cvresult;
merge assoc(in=ina) out3(in=inb);
keep replicate cvalue2 acc;
run;
proc print data=cvresult;
title'交叉驗證組號、c統計量、預測準確率';
run;
title '交叉驗證最優模型選擇:組號、預測準確率';
ods output SQL_Results=cvparam; /*保存最優模型結果在cvparam數據集中*/
proc sql ;
select replicate,acc from cvresult 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 selected=1;
create table test as
select * from cv where replicate in (select replicate from cvparam)
having selected=0;
run;
TITLE '--------Logistic Regression - 數據集Neur - 建模方法 STEPWISE ---------------------------';
/* 邏輯迴歸主程序 - 通過訓練集建立logistic模型*/
proc logistic data=train DES /*根據分類值從大到小選擇建模組別,此處爲yes*/
covout outest=Nout_step /*輸出建模參數估計值及變量間的協方差矩陣*/
outmodel=model /*輸出建模結果(若想要通過已有的建模結果來預測新數據集,這裏可以用inmodel實現)*/
simple; /*輸出變量的簡單統計量*/
/* class Y (param=ref ref='yes'); 若Y是分類變量,則用class對其參數化處理,這裏選擇處理方式爲ref,以“yes”作爲參考水平,以便於後續odds的計算*/
MODEL Y=X1-X14 /*logistic迴歸模型:反應變量=自變量1 2 3...*/
/ 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 outroc=train_roc; /*通過score語句得到訓練集上一系列的sensitivity和specificity,畫出ROC曲線*/
score data=test
out=test_pred
outroc=test_roc; /*通過score來預測測試集,結果保存在test_pred中,畫出ROC曲線*/
OUTPUT out=train_pred /*保存模型預測結果在該數據集中,數據集中包含的列由以下添加的統計量給出*/
P=PHAT lower=LCL upper=UCL /*輸出文件中包含每個觀察體屬於logistic方程預測組別的概率,用PHAT作列名,LCL和UCL爲置信上下限的值*/
RESCHI=RESCHI RESDEV=RESDEV /*Pearson殘差和偏差殘差,找出與模型不太符合的觀察體*/
DIFCHISQ=DIFCHISQ DIFDEV=DIFDEV /*檢測觀察體對對皮爾森卡方適合度和對偏激統計量的影響程度,越大說明與模型越不符*/
/* 還可加入的統計量:C、CBAR、DFBETAS、H、XBETA、STDXBETA */
/ ALPHA=0.1; /*界定P值的信賴度,默認爲0.05,對應信賴度爲95%,這裏爲90%*/
run;
quit;
/*
邏輯迴歸主程序 - 根據logistic模型對測試集進行預測(有需要時可使用獨立的logistic過程對新數據進行預測)
proc logistic inmodel=model;
SCORE data=test
outroc=predict_roc;
run;
*/
/* 訓練集的預測結果中只給出了預測概率,接下來根據0.5分界將觀察體歸到具體的類中,加一列“pred”(預測組別)*/
data train_pred;
set train_pred;
if PHAT>0.5 then pred=_LEVEL_ ; /* PHAT爲logistic方程針對每個觀察體計算的屬於該組別的概率,若PHAT>0.5,則屬於該組別(這裏level爲1),否則,屬於另一組別 */
else pred=0;
run;
/* 輸出混淆矩陣 - 訓練集*/
ods output CrossTabFreqs=ct_train; /*保存混淆矩陣表(訓練集)*/
ods trace on;
proc freq data=train_pred;
tables Y*pred;
run;
ods trace off;
ods output close;
proc sql;
create table acc1 as
select sum(percent) from ct_train where (Y=pred and Y ^=.);
proc print data=acc1;
title '訓練集上的預測準確率';
run;
/* 輸出混淆矩陣及準確率等指標 - 測試集*/
ods output CrossTabFreqs=ct_test; /*保存混淆矩陣表(測試集)*/
proc freq data=test_pred;
tables F_Y*I_Y ;
run;
ods output close;
proc sql;
create table acc2 as
select sum(percent) from ct_test where (F_Y=I_Y and F_Y ^='');
proc print data=acc2;
title '測試集上的預測準確率';
run;