R을 이용한 모델링을 할 때 formula
인자값을 어떤 식으로
입력해야 하는지 정리해 볼 필요가 있다.
대표적으로 lm()
함수의 첫 번째 인자에 대한 입력값을 예로 들
수 있을 것이다.
이 인자값에는 약속에 의해 정해진 기호(operator)를 이용하여 모델의 뼈대를
설정할 수 있다.
몇가지의 기호만 알고 이를 조합한다면 일반적인 뼈대를 구성하는데 문제가
생기진 않을 것이다.
(본 글에서 사용될 기초데이터는 mtcars
이다.)
head(mtcars)
## mpg cyl disp hp drat wt qsec vs am gear carb
## Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
## Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
## Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
## Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
## Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
## Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1
“~” 기호
기본적으로 formula
인자값의 입력은 종속변수를 앞에 쓰고
독립변수를 뒤에 쓰게 되는데
종속변수와 독립변수를 구분 짓는 기호는 “~” 이다.
lm(mpg ~ wt, data = mtcars)
##
## Call:
## lm(formula = mpg ~ wt, data = mtcars)
##
## Coefficients:
## (Intercept) wt
## 37.285 -5.344
위의 단순선형회귀적합 코드를 살펴보자.
lm()
함수의 첫 번째 인자입력값을 보면 mpg ~ wt
로 되어있다.
왼쪽 맨 앞의 mpg
는 종속변수로 지정하고, 오른쪽 뒤에 있는
wt
는 독립변수로 지정하겠다는 의미가 된다.
“+” 기호
독립변수를 wt
뿐만 아니라 cyl
변수까지
고려하는 다중회귀분석을 하고 싶다면 “+” 기호를 이용해 고려대상이 되는
변수를 추가시킬 수 있다.
lm(mpg ~ wt + cyl, data = mtcars)
##
## Call:
## lm(formula = mpg ~ wt + cyl, data = mtcars)
##
## Coefficients:
## (Intercept) wt cyl
## 39.686 -3.191 -1.508
그런데 만약 자신이 가지고 있는 데이터셋에 종속변수를 설명시킬 독립변수들이 이미 모두 포진되어있는 상태라면, 그리고 그 독립변수들을 모두 고려한 다중회귀적합을 시키고 싶다면 어떻게 해야 할까?
lm(mpg ~ cyl + disp + hp + drat + wt + qsec + vs + am + gear + carb, data = mtcars)
##
## Call:
## lm(formula = mpg ~ cyl + disp + hp + drat + wt + qsec + vs +
## am + gear + carb, data = mtcars)
##
## Coefficients:
## (Intercept) cyl disp hp drat
## 12.30337 -0.11144 0.01334 -0.02148 0.78711
## wt qsec vs am gear
## -3.71530 0.82104 0.31776 2.52023 0.65541
## carb
## -0.19942
이런 식으로 고려대상이 되는 독립변수의 명칭을 모두 적은 다음
사이사이에 “+” 기호를 무식하게 넣어주어야 하는 상황이다.
하지만 위의 코딩은 매우 비효율적 🙄 손이 아파질 수 있다.
“.” 기호
이를 대비해 특수하게 약속된 “.” 기호를 이용하면 좋다.
lm(mpg ~ ., data = mtcars)
##
## Call:
## lm(formula = mpg ~ ., data = mtcars)
##
## Coefficients:
## (Intercept) cyl disp hp drat
## 12.30337 -0.11144 0.01334 -0.02148 0.78711
## wt qsec vs am gear
## -3.71530 0.82104 0.31776 2.52023 0.65541
## carb
## -0.19942
“.” 기호는 “전부” 의 의미를 가진다.
위의 코드는 종속변수로 이미 배정된 mpg 이외의 모든 변수를 독립변수로
고려하라 라는 의미가 된다.
“-” 기호
“+” 기호의 반대는 “-” 이다. 의미 역시 반대이다.
고려대상에서 추가하는 “+” 와 다르게 “-” 는 고려대상에서
제외시킨다.
“.” 기호를 통해 모든 독립변수를 배정했는데, 여기서 cyl
변수만은 독립변수에서 제외하고 싶을 경우
lm(mpg ~ . - cyl, data = mtcars)
##
## Call:
## lm(formula = mpg ~ . - cyl, data = mtcars)
##
## Coefficients:
## (Intercept) disp hp drat wt
## 10.96007 0.01283 -0.02191 0.83520 -3.69251
## qsec vs am gear carb
## 0.84244 0.38975 2.57743 0.71155 -0.21958
이렇게 “-” 기호를 활용하면 된다.
한 가지 덧붙이자면 회귀적합시 기본적으로 절편(intercept)을 고려하는
회귀적합을 하게 되는데, 절편이 0인 모델로 적합하고 싶은 경우 절편항을
제외시켜야 할 것이다.
“-” 기호를 아래와 같이 이용하면 된다.
lm(mpg ~ . - 1, data = mtcars)
##
## Call:
## lm(formula = mpg ~ . - 1, data = mtcars)
##
## Coefficients:
## cyl disp hp drat wt qsec vs
## 0.35083 0.01354 -0.02055 1.24158 -3.82613 1.19140 0.18972
## am gear carb
## 2.83222 1.05426 -0.26321
결과를 확인해 보면 항시 언급되었던 절편항 “(Intercept)” 이 없어진
것을 확인할 수 있다.
참고로 아래와 같이 해도 절편항을 제외한다.
lm(mpg ~ . + 0, data = mtcars)
##
## Call:
## lm(formula = mpg ~ . + 0, data = mtcars)
##
## Coefficients:
## cyl disp hp drat wt qsec vs
## 0.35083 0.01354 -0.02055 1.24158 -3.82613 1.19140 0.18972
## am gear carb
## 2.83222 1.05426 -0.26321
“:” 기호
회귀적합에서 상호작용에 대해 고려한다면 “:” 기호를 이용하여
상호작용항을 부여할 수 있다.
만약 종속변수 mpg
에 대해 설명하는 독립변수를
wt
, cyl
2개 설정하고,
이 두 변수의 상호작용까지 고려하고자 한다면 이렇게 하면 된다.
lm(mpg ~ wt + cyl + wt:cyl, data = mtcars)
##
## Call:
## lm(formula = mpg ~ wt + cyl + wt:cyl, data = mtcars)
##
## Coefficients:
## (Intercept) wt cyl wt:cyl
## 54.3068 -8.6556 -3.8032 0.8084
그런데 고려대상인 독립변수가 3개 이상, 그리고 독립변수의 조합별
상호작용을 고려하게 된다면 골치가 아플 수 있다.
예를 들어 mpg
에 대해 설명하는 독립변수를 wt
,
cyl
, gear
3개이고, 3개의 모든 조합에 대해
상호작용을 고려한다면 formula
인자값이 아래처럼 매우 길게
된다.
lm(mpg ~ wt + cyl + gear + wt:cyl + wt:gear + cyl:gear + wt:cyl:gear, data = mtcars)
##
## Call:
## lm(formula = mpg ~ wt + cyl + gear + wt:cyl + wt:gear + cyl:gear +
## wt:cyl:gear, data = mtcars)
##
## Coefficients:
## (Intercept) wt cyl gear wt:cyl
## 47.3853 -10.4502 -0.8957 2.2704 0.5459
## wt:gear cyl:gear wt:cyl:gear
## 0.3527 -0.8794 0.1001
“*” 기호
상호작용항을 고려하되 각 개별항과 상호작용항이 될 수 있는 모든 조합을
알아서 배정시키는
약속된 기호가 바로 “*” 이다.
lm(mpg ~ wt * cyl * gear, data = mtcars)
##
## Call:
## lm(formula = mpg ~ wt * cyl * gear, data = mtcars)
##
## Coefficients:
## (Intercept) wt cyl gear wt:cyl
## 47.3853 -10.4502 -0.8957 2.2704 0.5459
## wt:gear cyl:gear wt:cyl:gear
## 0.3527 -0.8794 0.1001
위의
mpg ~ wt * cyl * gear
는
mpg ~ wt + cyl + gear + wt:cyl + wt:gear + cyl:gear + wt:cyl:gear
와 동일한 것이다.
따라서 실행된 코드의 출력결과도 비교해 보면 같은 것을 확인할 수
있다.
I()
함수
만약 분석자 나름대로 다변수들의 정보를 하나로 압축시킨 파생변수로
회귀적합을 하고 싶다면 어떻게 해야 할까?
예를 들어 hp
변수값과 루트를 씌운 wt
변수값을
더하고 carb
변수의 값을 뺀 값을 독립변수로 설정하여
단순회귀적합을 하고 싶다고 가정해보자. (일부러 의미 없이 복잡하게 설정해
봄)
일단 떠오르는 방법은 mtcars
에 새로운 변수열을 만들어
위의 상황대로
hp + sqrt(wt) - carb
를 계산한 새로운 변수를 만들어 이 변수열과 회귀적합을 하면 될
것이다.
하지만 I()
함수를 알게 된다면 새로운 변수를 직접 만들
필요가 없다. 이렇게 하면 된다.
lm(mpg ~ I(hp + sqrt(wt) - carb), data = mtcars)
##
## Call:
## lm(formula = mpg ~ I(hp + sqrt(wt) - carb), data = mtcars)
##
## Coefficients:
## (Intercept) I(hp + sqrt(wt) - carb)
## 30.20584 -0.06945
그런데 한 가지 의문이 생길 수 있다.
만약 I()
함수를 이용하지 않고 formula
에
hp + sqrt(wt) - carb
의 날것의 형태로 입력하면 되지 않을까?
라는 의문이다.
실행해보면 다음과 같다.
lm(mpg ~ hp + sqrt(wt) - carb, data = mtcars)
##
## Call:
## lm(formula = mpg ~ hp + sqrt(wt) - carb, data = mtcars)
##
## Coefficients:
## (Intercept) hp sqrt(wt)
## 50.42823 -0.02908 -14.70273
우리가 줄곧 배운 formula
의 입력값은 특정한 기호에 의해
약속된 문법을 따른다.
따라서 hp + sqrt(wt) - carb
의 형태는 우리가 원하는
파생변수를 만들어 적합시키지 않는다.
hp
값에 sqrt(wt)
값이 더해진 후
carb
변수값이 차감된 것을 원하지만,
독립변수에 hp
, sqrt(wt)
가 따로따로 고려되고
carb
변수가 독립변수로 제외됨을 명시할 뿐이다.
다시 I()
함수를 이용한 결과로 돌아가 보면
I()
의 쓰임은 결국 formula
인자의 약속된
문법을 escape 하는 역할로 볼 수도 있겠다.
formula
인자에 입력할 값의 사용방법과 기호의 의미를
정리해 보았다.
위의 내용 외에도 더 많은 팁과 기호들의 조합을 생각해 볼 수 있을
것이다.