June 30, 2013

[SAS] 如何建立虛擬變項 (Dummy variable)???

 進行統計分析遇到資料中含有類別變項的時候,不能像連續變項一樣直接放入迴歸模型之中。舉例來說,假設現在我們的資料中有種族這個類別變項${x}_{1}$,而其中包含白人、黑人、黃種人。在不設虛擬變項的狀況之下,分別令黑人=1,黃種人=2,白人=3,代入下列回歸方程式$ y={ \beta }_{ 1 }{ x }_{ 1 }+\alpha $中,則結果如下:

$ {x}_{1}$=1,$ {y}_{1}={1}{ \beta }_{ 1 }+\alpha $

$ {x}_{1}$=2,$ {y}_{2}={2}{ \beta }_{ 1 }+\alpha $

$ {x}_{1}$=3,$ {y}_{3}={3}{ \beta }_{ 1 }+\alpha $

如果是連續變項,所求得的${\beta}_{1}$值來自於${y}_{n}-{y}_{n-1}={\beta}_{1}$,換句話說是${x}_{1}$每增加1個單位,則${y}$就會增加${\beta}$。試問在這個例子中又該如何解釋呢?這些數值代表的是該類別的"特質",而不是已經實際的量,因此我們無法解釋這樣的結果,這種情況下就得用到虛擬變項來解決這個困境。

類別變項該如何編碼成虛擬變項呢?虛擬變項由0或1組成,如果類別變項具有A個類別,則需要A-1個虛擬變項。假設第一個類別作為參考組,則所有的虛擬變項數值皆為0,若虛擬變項${A}_{1}$代表第二個類別,則虛擬變項${A}_{1}$的數值為1,其餘虛擬變項數值為0。假設一個簡單回歸方程式的類別變項有三個類別,則我們可以將方程式簡單寫成如下:

${y}={\alpha}+{\beta}_{1}{x}_{1}+{\beta}_{2}{x}_{2}$

以第一個類別作為參考組,方程式可寫成:

${y}_{1}={\alpha}+{\beta}_{1}(0)+{\beta}_{2}(0)={\alpha}$(式一)

第二個類別方程式寫成:

${y}_{2}={\alpha}+{\beta}_{1}(1)+{\beta}_{2}(0)={\alpha}+{\beta}_{1}$(式二)

第三個類別方程式則寫成:

${y}_{3}={\alpha}+{\beta}_{1}(0)+{\beta}_{2}(1)={\alpha}+{\beta}_{2}$(式三)

將式二與式一相減可得${\beta}_{1}$,式三與式一相減可得${\beta}_{2}$,換言之,當第二類別與第一類別相比之下的差異量為${\beta}_{1}$,第三類別與第一類別相比之下的差異量則為${\beta}_{2}$,這下子知道該如何去解釋迴歸模型中虛擬變項所代表的迴歸係數了吧?

方法一
/*此部分為母資料集,下列範例皆須使用此資料集*/
DATA AUTO ;
LENGTH MAKE $ 20 ;
INPUT MAKE $ 1-17 PRICE MPG REP78 ;
CARDS;
AMC CONCORD 4099 22 3
AMC PACER 4749 17 3
AUDI 5000 9690 17 5
AUDI FOX 6295 23 3
BMW 320I 9735 25 4
BUICK CENTURY 4816 20 3
BUICK ELECTRA 7827 15 4
BUICK LESABRE 5788 18 3
CAD. ELDORADO 14500 14 2
OLDS STARFIRE 4195 24 1
OLDS TORONADO 10371 16 3
PLYM. VOLARE 4060 18 2
PONT. CATALINA 5798 18 4
PONT. FIREBIRD 4934 18 1
PONT. GRAND PRIX 5222 19 3
PONT. LE MANS 4723 19 3
;
RUN;
/*方法一由此開始*/ DATA AUTO2;
SET AUTO;
IF REP78=1 THEN REP78_1=1;ELSE REP78_1=0;
IF REP78=2 THEN REP78_2=1;ELSE REP78_2=0;
IF REP78=3 THEN REP78_3=1;ELSE REP78_3=0;
IF REP78=4 THEN REP78_4=1;ELSE REP78_4=0;
RUN;
/*此部分為檢驗編碼正確與否*/ PROC FREQ DATA=AUTO2;
TABLE REP78*REP78_1*REP78_2*REP78_3*REP78_4 /LIST;
RUN;

程式說明:此例中,rep78共有五個類別,需要產生四個虛擬變項,REP78=5作為參考組。

方法二
DATA AUTO3;
SET AUTO;
REP78_1=(REP78=1);
REP78_2=(REP78=2);
REP78_3=(REP78=3);
REP78_4=(REP78=4);
RUN;
PROC FREQ DATA=AUTO3;
TABLE REP78*REP78_1*REP78_2*REP78_3*REP78_4 /LIST;
RUN;

這個程式算是方法一的改良版,省略了繁複的if then else,是我很喜愛的做法。

方法三
DATA AUTO4;
SET AUTO;
ARRAY DUMMYS {*} 3. REP78_1 - REP78_5;
DO I=1 TO 5;
DUMMYS(I) = 0;
END;
DUMMYS( REP78 ) = 1;
RUN;
PROC FREQ DATA=AUTO4;
TABLES REP78*REP78_1*REP78_2*REP78_3*REP78_4*REP78_5 / LIST ;
RUN;

這個方法是用ARRAY敘述句來進行虛擬變項的編碼,一個類別需要搭配一個虛擬變項,該陣列的名稱為DUMMYS,內涵五個新的變項REP78_1 - REP78_5,接下來使用"DO...TO...END" LOOP,先令所有變項預設值為0,最後再用DUMMYS(REP78)=1給定適當的值,譬如說當REP78=4時,則DUMMYS(4)、也就是陣列中的第四個元素REP78_4=1

跑完這個程式可能有些人會有一個疑問,哪一個虛擬變項是這個程式中的參考組?以PROC REG為例,系統預設最後一個虛擬變項作為參考組,迴歸分析的報表出來時最後一個虛擬變項的${\beta}$值會顯示為0,且在報表中會出現下列字串:

Note: The following parameters have been set to 0, since the variables are a linear combination of other variables as shown.

如果還是不放心的人,可以用下列的程式驗證這樣的編碼是否會影響統計分析的結果:

PROC REG DATA=AUTO3;
MODEL PRICE=REP78_1-REP78_4;
RUN;
PROC REG DATA=AUTO4;
MODEL PRICE=REP78_1-REP78_5;
RUN;

※迴歸分析前要記得先編譯好虛擬變項阿!!

方法四
/* A MACRO FOR DUMMING CODING */
%MACRO NOMINAL_TO_BINARY(
SM_DATASET=/* DATA SET */,
SM_VAR= /* CATEGORICAL VARIABLE */,
SM_PREFIX= /* PREFIX FOR DUMMY VARIABLES */);
/* FIND THE UNIQUE LEVELS OF THE CATEGORICAL VARIABLE */
PROC SORT DATA=&SM_DATASET(KEEP=&SM_VAR) OUT=&SM_DATASET._UNIQUE NODUPKEY;
BY &SM_VAR;
RUN;
DATA _NULL_;
SET &SM_DATASET._UNIQUE END=END;
/* USE CALL EXECUTE TO DYNAMICALLY CREATE A MACRO THAT EXECUTES */
/* AFTER THIS DATA STEP FINISHES. THE METAPROGRAMMED MACRO */
/* MODIFIES THE ORIGINAL DATA SET. */
IF _N_ EQ 1 THEN DO;
CALL EXECUTE("DATA &SM_DATASET;");
CALL EXECUTE("SET &SM_DATASET;");
END;
CALL EXECUTE(CAT("LENGTH &SM_PREFIX", &SM_VAR," 3;")); /* USE MINIMUM STORAGE */
CALL EXECUTE(CATS("&SM_PREFIX", &SM_VAR," = &SM_VAR = '", &SM_VAR,"';"));
IF END THEN CALL EXECUTE('RUN;');
RUN;
PROC SQL;
/* CLEAN UP */
DROP TABLE &SM_DATASET._UNIQUE;
QUIT;
%MEND;
/* GENERATE A SAMPLE DATA SET */
DATA AUTO6;
SET AUTO;
RUN;
/* EXAMPLE INVOCATION */
%NOMINAL_TO_BINARY(SM_DATASET=AUTO6, SM_VAR=REP78, SM_PREFIX=REP78_);
PROC FREQ DATA=AUTO6;
TABLES REP78*REP78_1*REP78_2*REP78_3*REP78_4*REP78_5 / LIST ;
RUN;

這個方法出自於Heuristic Andrew,有興趣的人可以研究作者所寫的Comment,我在這部分沒有進行更動。這個方法是將資料內重新排序,並且利用資料內容來判斷需要多少虛擬變項。要特別注意的一點是,如果你要建立虛擬變項的類別變項是連續變項再分組而來的話,不建議使用這個方法,假使你其中一個組數目為0,那他就不會將該組納入虛擬變項中。

使用這個程式的方法很簡單。將Marco貼上之後讀入資料集,最後唯一要修改地方在最後一行:

%NOMINAL_TO_BINARY(SM_DATASET=(1), SM_VAR=(2), SM_PREFIX=(3));
  1. 要建立虛擬變項的資料集
  2. 類別變項的名稱
  3. 通常是類別變項加上"_"符號

這個做法在只有一個類別變項需要建立虛擬變項的時候效果並不明顯,但如果遇到的狀況是許多類別變項的時候就會非常好用。

延伸閱讀

Is there a quick way to create dummy variables?
How to Create Dummy Variables in SAS

本著作依據Creative Commons 姓名標示-非商業性-相同方式分享授權條款釋出

No comments :