R語言中啞變量的設置

原文來源:https://www.sohu.com/a/199698358_489312

在構建迴歸模型時,如果自變量X爲連續性變量,迴歸係數β可以解釋爲:在其他自變量不變的條件下,X每改變一個單位,所引起的因變量Y的平均變化量;如果自變量X爲二分類變量,例如是否飲酒(1=是,0=否),則迴歸係數β可以解釋爲:其他自變量不變的條件下,X=1(飲酒者)與X=0(不飲酒者)相比,所引起的因變量Y的平均變化量。

但是,當自變量X爲多分類變量時,例如職業、學歷、血型、疾病嚴重程度等等,此時僅用一個迴歸係數來解釋多分類變量之間的變化關係,及其對因變量的影響,就顯得太不理想。

此時,我們通常會將原始的多分類變量轉化爲啞變量,每個啞變量只代表某兩個級別或若干個級別間的差異,通過構建迴歸模型,每一個啞變量都能得出一個估計的迴歸係數,從而使得迴歸的結果更易於解釋,更具有實際意義。

啞變量(Dummy Variable),又稱爲虛擬變量、虛設變量或名義變量,從名稱上看就知道,它是人爲虛設的變量,通常取值爲0或1,來反映某個變量的不同屬性。對於有n個分類屬性的自變量,通常需要選取1個分類作爲參照,因此可以產生n-1個啞變量。

什麼情況下需要設置啞變量

1. 對於無序多分類變量,引入模型時需要轉化爲啞變量

舉一個例子,如血型,一般分爲A、B、O、AB四個類型,爲無序多分類變量,通常情況下在錄入數據的時候,爲了使數據量化,我們常會將其賦值爲1、2、3、4。

從數字的角度來看,賦值爲1、2、3、4後,它們是具有從小到大一定的順序關係的,而實際上,四種血型之間並沒有這種大小關係存在,它們之間應該是相互平等獨立的關係。如果按照1、2、3、4賦值並帶入到迴歸模型中是不合理的,此時我們就需要將其轉化爲啞變量。

2. 對於有序多分類變量,引入模型時需要酌情考慮

例如疾病的嚴重程度,一般分爲輕、中、重度,可認爲是有序多分類變量,通常情況下我們也常會將其賦值爲1、2、3(等距)或1、2、4(等比)等形式,通過由小到大的數字關係,來體現疾病嚴重程度之間一定的等級關係。

但需要注意的是,一旦賦值爲上述等距或等比的數值形式,這在某種程度上是認爲疾病的嚴重程度也呈現類似的等距或等比的關係。而事實上由於疾病在臨牀上的複雜性,不同的嚴重程度之間並非是嚴格的等距或等比關係,因此再賦值爲上述形式就顯得不太合理,此時可以將其轉化爲啞變量進行量化。

3. 對於連續性變量,進行變量轉化時可以考慮設定爲啞變量

對於連續性變量,很多人認爲可以直接將其帶入到迴歸模型中即可,但有時我們還需要結合實際的臨牀意義,對連續性變量作適當的轉換。例如年齡,以連續性變量帶入模型時,其解釋爲年齡每增加一歲時對於因變量的影響。但往往年齡增加一歲,其效應是很微弱的,並沒有太大的實際意義。

此時,我們可以將年齡這個連續性變量進行離散化,按照10歲一個年齡段進行劃分,如0-10、11-20、21-30、31-40等等,將每一組賦值爲1、2、3、4,此時構建模型的迴歸係數就可以解釋爲年齡每增加10歲時對因變量的影響。

以上賦值方式是基於一個前提,即年齡與因變量之間存在着一定的線性關係。但有時候可能會出現以下情況,例如在年齡段較低和較高的人羣中,某種疾病的死亡率較高,而在中青年人羣中,死亡率卻相對較低,年齡和死亡結局之間呈現一個U字型的關係,此時再將年齡段賦值爲1、2、3、4就顯得不太合理了。

因此,當我們無法確定自變量和因變量之間的變化關係,將連續性自變量離散化時,可以考慮進行啞變量轉換

還有一種情況,例如將BMI按照臨牀診斷標準分爲體重過低、正常體重、超重、肥胖等幾種分類時,由於不同分類之間劃分的切點是不等距的,此時賦值爲1、2、3就不太符合實際情況,也可以考慮將其轉化爲啞變量。

在設定啞變量時,應該選擇哪一類作爲參照呢?

1. 一般情況下,可以選擇有特定意義的,或者有一定順序水平的類別作爲參照

例如,婚姻狀態分爲未婚、已婚、離異、喪偶等情況,可以將“未婚”作爲參照;或者如學歷,分爲小學、中學、大學、研究生等類別,存在着一定的順序,可以將“小學”作爲參照,以便於迴歸係數更容易解釋。

2. 可以選擇臨牀正常水平作爲參照

例如,BMI按照臨牀診斷標準分爲體重過低、正常體重、超重、肥胖等類別,此時可以選擇“正常體重”作爲參照,其他分類都與正常體重進行比較,更具有臨牀實際意義。

3. 還可以將研究者所關注的重點類別作爲參照

例如血型,分爲A、B、O、AB四個類型,研究者更關注O型血的人,因此可以將O型作爲參照,來分析其他血型與O型相比後對於結局產生影響的差異。

4. R語言中實現

R語言中對包括分類變量(factor)的數據建模時,一般會將其自動處理爲虛擬變量或啞變量(dummy variable)。但有一些特殊的函數,如neuralnet包中的neuralnet函數就不會預處理。如果直接將原始數據扔進去,會出現”requires numeric/complex matrix/vector arguments”需要數值/複數矩陣/矢量參數錯誤。

這個時候,除了將這些變量刪除,我們只能手動將factor variable轉換爲取值(0,1)的虛擬變量。所用的函數一般有model.matrix(),nnet package中的class.ind()

下面以UCI的german credit data爲例說明。

首先,從UCI網站上下載到german.data數據集,並用str函數對其有個簡單的認識。

download.file("http://archive.ics.uci.edu/ml/machine-learning-databases/statlog/german/german.data", "./german.data")
data <- read.table("./german.data")
str(data)

該數據有21個變量,其中V21爲目標變量,V1-V20中包括integer和factor兩種類型。下面將用V1分類變量(包含4個level)和V2,V5,V8三個數值型變量作爲解釋變量建模。

## 'data.frame':    1000 obs. of  21 variables:
##  $ V1 : Factor w/ 4 levels "A11","A12","A13",..: 1 2 4 1 1 4 4 2 4 2 ...
##  $ V2 : int  6 48 12 42 24 36 24 36 12 30 ...
##  $ V3 : Factor w/ 5 levels "A30","A31","A32",..: 5 3 5 3 4 3 3 3 3 5 ...
##  $ V4 : Factor w/ 10 levels "A40","A41","A410",..: 5 5 8 4 1 8 4 2 5 1 ...
##  $ V5 : int  1169 5951 2096 7882 4870 9055 2835 6948 3059 5234 ...
##  $ V6 : Factor w/ 5 levels "A61","A62","A63",..: 5 1 1 1 1 5 3 1 4 1 ...
##  $ V7 : Factor w/ 5 levels "A71","A72","A73",..: 5 3 4 4 3 3 5 3 4 1 ...
##  $ V8 : int  4 2 2 2 3 2 3 2 2 4 ...
##  $ V9 : Factor w/ 4 levels "A91","A92","A93",..: 3 2 3 3 3 3 3 3 1 4 ...
##  $ V10: Factor w/ 3 levels "A101","A102",..: 1 1 1 3 1 1 1 1 1 1 ...
##  $ V11: int  4 2 3 4 4 4 4 2 4 2 ...
##  $ V12: Factor w/ 4 levels "A121","A122",..: 1 1 1 2 4 4 2 3 1 3 ...
##  $ V13: int  67 22 49 45 53 35 53 35 61 28 ...
##  $ V14: Factor w/ 3 levels "A141","A142",..: 3 3 3 3 3 3 3 3 3 3 ...
##  $ V15: Factor w/ 3 levels "A151","A152",..: 2 2 2 3 3 3 2 1 2 2 ...
##  $ V16: int  2 1 1 1 2 1 1 1 1 2 ...
##  $ V17: Factor w/ 4 levels "A171","A172",..: 3 3 2 3 3 2 3 4 2 4 ...
##  $ V18: int  1 1 2 2 2 2 1 1 1 1 ...
##  $ V19: Factor w/ 2 levels "A191","A192": 2 1 1 1 1 2 1 2 1 1 ...
##  $ V20: Factor w/ 2 levels "A201","A202": 1 1 1 1 1 1 1 1 1 1 ...
##  $ V21: int  1 2 1 1 2 1 1 1 1 2……

首先加載neuralnet包嘗試一下,只用數值型變量建模,沒有報錯。

library("neuralnet")
NNModelAllNum <- neuralnet(V21 ~ V2 + V5 + V8, data)
NNModelAllNum

當我們把V1放入解釋變量中出現瞭如下錯誤

NNModel <- neuralnet(V21 ~ V1 + V2 + V5 + V8, data)
## Error: 需要數值/複數矩陣/矢量參數

此時可以用model.matrix函數將V1轉化爲三個虛擬變量,V1A12,V1A13,V1A14。

>dummyV1 <- model.matrix(~V1, data)
>head(cbind(dummyV1, data$V1))
   (Intercept) V1A12 V1A13 V1A14  
 1           1     0     0     0 1
 2           1     1     0     0 2
 3           1     0     0     1 4
 4           1     0     0     0 1
 5           1     0     0     0 1
 6           1     0     0     1 4

因爲model.matrix函數對數值型和分類Level=2的類別型變量沒有影響,所以可以將四個變量一起用該函數生成新的數據集modelData,就可以用該數據集建模了。

>modelData <- model.matrix(~V1 + V2 + V5 + V8 + V21, data)
>head(modelData)
   (Intercept) V1A12 V1A13 V1A14 V2   V5 V8 V21
 1           1     0     0     0  6 1169  4   1
 2           1     1     0     0 48 5951  2   2
 3           1     0     0     1 12 2096  2   1
 4           1     0     0     0 42 7882  2   1
 5           1     0     0     0 24 4870  3   2
 6           1     0     0     1 36 9055  2   1

另一種方法是來自nnet package的class.ind函數

>library("nnet")
>dummyV12 <- class.ind(data$V1)
>head(dummyV12)
      A11 A12 A13 A14
 [1,]   1   0   0   0
 [2,]   0   1   0   0
 [3,]   0   0   0   1
 [4,]   1   0   0   0
 [5,]   1   0   0   0
 [6,]   0   0   0   1

可以看到,該結果和model.matrix稍有區別,生成了四個虛擬變量。要注意,爲了避免多重共線性,對於level=n的分類變量只需選取其任意n-1個虛擬變量。

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