R 모형 설계행렬(Design Matrix) 1

회귀분석(lm)같은 예측모형 함수를 생성하는데 중요하게 사용되는 것이 설계행렬(design matrix)이다. 설계행렬은 통계학에서 2차원 \(X\) 행렬로 행은 관측점, 열은 예측변수로 구성된다.

Sepal.Width 변수를 예측하는데 3개 변수가 투입되었지만, Species 변수가 수준 3개를 갖는 범주형이라 실제 설계행렬에는 변수가 4개 들어있음. 단, 절편(intercept)은 제외된다.

# 0. 환경설정 ----------------------------------------------------
library(tidyverse)

# 1. 예측모형 ----------------------------------------------------
mod1 <- lm(Sepal.Width ~ Petal.Width + log(Petal.Length) + Species, 
           data = iris, subset = Sepal.Length > 4.6)

# 2. model.frame ----------------------------------------------------

mf <- stats::model.frame(formula = Sepal.Width ~ Petal.Width + log(Petal.Length) + Species, 
                   data = iris, 
                   subset = Sepal.Length > 4.6, 
                   drop.unused.levels = TRUE)

mf <- stats::model.frame(formula = Sepal.Width ~ Petal.Width + log(Petal.Length) + Species, 
                   data = iris, 
                   subset = Sepal.Length > 4.6, 
                   drop.unused.levels = TRUE)

eval(expr = mf, envir = parent.frame()) %>% head
  Sepal.Width Petal.Width log(Petal.Length) Species
1         3.5         0.2         0.3364722  setosa
2         3.0         0.2         0.3364722  setosa
3         3.2         0.2         0.2623643  setosa
5         3.6         0.2         0.3364722  setosa
6         3.9         0.4         0.5306283  setosa
8         3.4         0.2         0.4054651  setosa

설계행렬을 얻는데 중요한 역할을 수행하는 것이 model.frame, model.matrix 함수다. 예를 들어 lm 함수에 포함된 모형수식(formula, Sepal.Width ~ Petal.Width + log(Petal.Length) + Species)을 받아 stats 팩키지의 model.frame 함수에 넘겨 설계행렬을 뽑아낸다.

1.1. 설계행렬 핵심객체: terms

model.frame 객체, mf에서 설계행렬에 대한 중요한 정보는 terms에 담겨있다. terms에 변수간 관계, 변수 변환등 설계행렬에 대한 상세한 정보가 담긴다.

# attributes(mf)
terms(mf)
Sepal.Width ~ Petal.Width + log(Petal.Length) + Species
attr(,"variables")
list(Sepal.Width, Petal.Width, log(Petal.Length), Species)
attr(,"factors")
                  Petal.Width log(Petal.Length) Species
Sepal.Width                 0                 0       0
Petal.Width                 1                 0       0
log(Petal.Length)           0                 1       0
Species                     0                 0       1
attr(,"term.labels")
[1] "Petal.Width"       "log(Petal.Length)" "Species"          
attr(,"order")
[1] 1 1 1
attr(,"intercept")
[1] 1
attr(,"response")
[1] 1
attr(,".Environment")
<environment: R_GlobalEnv>
attr(,"predvars")
list(Sepal.Width, Petal.Width, log(Petal.Length), Species)
attr(,"dataClasses")
      Sepal.Width       Petal.Width log(Petal.Length)           Species 
        "numeric"         "numeric"         "numeric"          "factor" 

terms 객체가 중요한 이유는 예측모형이 개발된 후에 예측할 데이터가 들어올 때 예측을 위한 설계행렬을 만드는데 활용되기 때문이다.

1.2. 설계행렬 생성: model.matrix

model.frame을 통해 terms 객체를 추출하고 나면 이를 model.matrix에 넣게 되면 설계행렬(design matrix)을 얻게 된다. model.matrix() 함수가 가변수, 교호작용 등을 표현한 설계행렬 정보를 담아낸다.

# 3. design matrix ----------------------------------------------------

mt <- attr(x = mf, which = "terms")

model.matrix(object = mt, data = mod1$model, contrasts.arg = contrasts) %>% head
  (Intercept) Petal.Width log(Petal.Length) Speciesversicolor Speciesvirginica
1           1         0.2         0.3364722                 0                0
2           1         0.2         0.3364722                 0                0
3           1         0.2         0.2623643                 0                0
5           1         0.2         0.3364722                 0                0
6           1         0.4         0.5306283                 0                0
8           1         0.2         0.4054651                 0                0

R 모형 수식 표현의 한계점 2 3

caret 팩키지 저자로 현재 RStudio 근무중인 Max Khun 박사가 예측모형 개발을 위한 R 모형수식 메쏘드에 다음 문제점을 언급하며 Recipes를 caret 대신 개발한 사유를 밝히고 있다.


  1. The R Formula Method: The Good Parts

  2. Model Fitting Functions in R

  3. The R Formula Method: The Bad Parts