단순 선형회귀분석
- 1. 기초 설명
- 2. 모델링
- 3. 선형 회귀 결과 추출
- 3. 1. 회귀계수
- 3. 2. 적합된 값(fitted value)
- 3. 3. 잔차(residuals)
- 3. 4. 회귀 계수의 신뢰구간
- 3. 5. 잔차제곱합
- 4. 예측과 신뢰구간
- 5. 모형 평가
- 6. 모형 진단 그래프
- 7. 회귀직선의 시각화
1. 기초 설명
- 단순 선형 회귀(Simple Linear Regression)는 반응변수 \(Y_i\)를 하나의 설명변수 \(X_i\)로 설명합니다.
모형식은 다음과 같습니다.
\[Y_i = \beta_0 + \beta_1 X_i + \epsilon_i\]
- 이 식에서 \(\beta_0\)는 절편, \(\beta_1\)은 설명변수 \(X_i\)의 계수이며, 이 들을 회귀 계수(regression coefficient)라고 부릅니다.
- 또한 \(\epsilon_i\)는 오차항을 뜻하며 \(\epsilon_i \sim N(0, 1)\)을 가정합니다.
2. 모델링
- 선형 회귀를 위한 함수는
lm()
함수로 linear model의 약자라고 생각하시면 됩니다. - 단순 선형회귀뿐만 아니라 설명변수가 여러 개인 선형회귀 또한
lm()
함수를 사용합니다. 많은 옵션 argument가 있지만 꼭 필요한 두 개의 argument에 대해서만 간단하게 설명드리겠습니다.
lm(formula, data, ...)
- formula : 반응변수 ~ 설명변수의 형태로 지정한 식
- data : 변수가 포함된 데이터 프레임
R에 기본적으로 내장되어 있는
cars
데이터를 가지고lm()
함수를 적용하겠습니다.cars
데이터는 자동차의 주행 속도(speed 변수)와 브레이크를 밟았을 때 제동 거리(dist 변수) 두 가지 변수로 이루어진 데이터입니다.
data(cars) head(cars)
## speed dist ## 1 4 2 ## 2 4 10 ## 3 7 4 ## 4 7 22 ## 5 8 16 ## 6 9 10
주행 속도에 따른 제동 거리 식을 다음과 같이 생각할 수 있습니다.
\[\text{dist}_i = \beta_0 + \beta_1 \text{speed}_i + \epsilon_i\]
이를
formula
argument로 표시한다면formula = dist ~ speed
가 되며 설명변수 끝에dist ~ speed - 1
을 따로 표시하지 않는 이상 절편에 해당하는 \(\beta_0\)는 포함하게 됩니다.m1 <- lm(dist ~ speed, data = cars) m1
## ## Call: ## lm(formula = dist ~ speed, data = cars) ## ## Coefficients: ## (Intercept) speed ## -17.579 3.932
- 그 결과, 주행 속도와 제동 거리 간의 관계는 \(\text{dist}_i = -17.579 + 3.932 \text{speed}_i + \epsilon_i\) 로 구해질 수 있습니다.
3. 선형 회귀 결과 추출
lm()
함수를 적용하여 구한 모형의 구체적인 아웃풋을 확인하기 위한 함수들을 알아보겠습니다.
3. 1. 회귀계수
coef()
함수를 통하여 회귀계수를 따로 출력할 수 있습니다. 다만coef()
함수 안에 들어갈 객체는lm()
함수를 통해 얻은 객체의 형태가 되어야 합니다.coef(m1)
## (Intercept) speed ## -17.579095 3.932409
3. 2. 적합된 값(fitted value)
fitted()
함수 또는predict()
함수를 통하여 모형에 의해 예측된 값을 구할 수 있습니다.predict()
함수는 새로운 데이터를 input 시켜 새로운 데이터에 대한 예측된 값도 구할 수 있습니다. 이 때newdata
라는 argument를 이용합니다.fitted(m1)[1:10]
## 1 2 3 4 5 6 7 ## -1.849460 -1.849460 9.947766 9.947766 13.880175 17.812584 21.744993 ## 8 9 10 ## 21.744993 21.744993 25.677401
predict(m1, newdata = data.frame(speed = 10))
## 1 ## 21.74499
3. 3. 잔차(residuals)
- 잔차는 실제값과 선형회귀 모형으로부터 구한 예측값과의 차이를 의미합니다. \(e_i = Y_i - \hat{Y}_i\)
residuals()
함수를 통해 잔차를 출력할 수 있습니다.residuals(m1)[1:4]
## 1 2 3 4 ## 3.849460 11.849460 -5.947766 12.052234
cars$dist[1:4] - fitted(m1)[1:4]
## 1 2 3 4 ## 3.849460 11.849460 -5.947766 12.052234
3. 4. 회귀 계수의 신뢰구간
confint()
함수를 이용하여 회귀계수에 대한 신뢰구간을 구할 수 있습니다. 기본값으로 95% 신뢰구간을 추정하며,level
argument를 이용하여 수정할 수 있습니다.confint(m1)
## 2.5 % 97.5 % ## (Intercept) -31.167850 -3.990340 ## speed 3.096964 4.767853
confint(m1, level = 0.90)
## 5 % 95 % ## (Intercept) -28.914514 -6.243676 ## speed 3.235501 4.629317
3. 5. 잔차제곱합
deviance()
함수를 통해 잔차제곱합 \(\sum_{i=1}^{n} e_i^2 = \sum_{i=1}^{n} (Y_i - \hat{Y}_i)^2\) 값을 구할 수 있습니다.deviance(m1)
## [1] 11353.52
4. 예측과 신뢰구간
- 2절에서 잠깐 언급한
predict()
함수는 새로운 데이터에 대한 예측값을 구하는 함수입니다.
- 2절에서 잠깐 언급한
사실
predict()
는 R에서 일반함수(generic function)로 회귀모형뿐만 아니라 다른 방식으로 여러 가지 모형을 만들었을 때 해당 모형으로부터 새로운 데이터에 대한 예측값을 구하는데 쓰입니다.predict(object, newdata, interval = c("none", "confidence", "prediction"))
- object : 선형 모형 또는 기타 모형 객체
- newdata : 예측을 수행할 새로운 데이터. 여기서 조심해야할 부분이 이 데이터의 변수명은 해당 모형의 변수명과 똑같이 설정을 해주셔야 합니다.
- interval : 계수에 대한 신뢰구간 또는 예측구간(prediction interval) 출력
predict(m1, newdata = data.frame(speed = 3), interval = "confidence")
## fit lwr upr ## 1 -5.781869 -17.02659 5.462853
-17.579095 + 3.932409 * 3
## [1] -5.781868
5. 모형 평가
- 선형회귀모형을 평가하는 기준은 결정 계수(R-squared), 조정된 결정 계수(Adjusted R-squared), F 통계량 등이 있습니다.
주요 함수는
summary()
함수입니다. 이 함수 또한 일반 함수로 주어진 객체에 대한 요약 정보를 보여줍니다.a <- summary(m1) a
## ## Call: ## lm(formula = dist ~ speed, data = cars) ## ## Residuals: ## Min 1Q Median 3Q Max ## -29.069 -9.525 -2.272 9.215 43.201 ## ## Coefficients: ## Estimate Std. Error t value Pr(>|t|) ## (Intercept) -17.5791 6.7584 -2.601 0.0123 * ## speed 3.9324 0.4155 9.464 1.49e-12 *** ## --- ## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 ## ## Residual standard error: 15.38 on 48 degrees of freedom ## Multiple R-squared: 0.6511, Adjusted R-squared: 0.6438 ## F-statistic: 89.57 on 1 and 48 DF, p-value: 1.49e-12
- 다음과 같이 객체로 지정해서 필요한 부분만 출력하실 수 있습니다.
- 구체적으로 살펴보면 Residuals 부분에서는 실제 데이터에서 관측된 잔차를 요약해준 통계량을 나타냅니다.
Coefficients 부분에서는 모형의 계수와 이 계수들의 통계적 유의성에 대해서 알려줍니다.
- t-분포를 사용하여 각 변수가 얼마나 유의한지를 판단할 수 있는 p-value가 출력되는데, 이 때 귀무가설은 \(H_0 : \beta_j = 0\), \(j = 0, 1\)이다.
그리고 하단 부분에 Multiple R-squared와 Adjusted R-squared는 모형이 데이터의 분산을 얼마만큼 설명하는지를 나타내주며, F-statistics 부분은 모형이 통계적으로 유의한지를 판단해줍니다.
- 여기서 F-통계량에 의한 F-검정 시 귀무가설은 축소 모형(reduced model)과 완전 모형(full model)간에 잔차 제곱합이 얼마나 유의하게 다른지를 살펴보는 방식으로 \(H_0 : \beta_1 = 0\) 입니다.
6. 모형 진단 그래프
- 단순히
plot()
함수만으로 선형회귀모형을 평가하는데 필요한 몇 가지 그래프를 볼 수 있습니다. 역시
plot()
도 일반 함수로서 선형회귀모형 객체를 인자로 하게되면plot.lm()
을 호출하는 것으로 볼 수 있습니다.plot.lm(object, which = c(1:3, 5))
- object : 선형모형 객체
- which : 출력할 그래프의 종류로 1~6까지 총 6가지 그래프가 있습니다.
par(mfrow = c(2, 2)) plot(m1)
plot(m1, which = 1)
- 첫 번째 그래프는 Residuals vs Fitted plot입니다. 즉 x축에 \(\hat{Y}\)를 y축에는 잔차 \(e_i\)로 하여금 그래프를 출력합니다. 선형회귀에서 오차는 평균이 0이고 분산이 일정한 정규분포를 가정하기에 \(\hat{Y}\)와 무관하게 잔차의 평균은 0을 중심으로 일정하게 패턴 없이 분포되어 있어야 합니다.
plot(m1, which = 2)
- 두 번째 그래프는 Normal Q-Q plot으로 잔차가 정규분포를 따르는지 확인하기 위한 Q-Q plot입니다. Q-Q plot에 대해서는 예전에 포스팅했던 부분을 참고해주세요.
plot(m1, which = 3)
- 세 번째 그래프는 Scale-Location plot으로 x축에 \(\hat{Y}\), y축에는 표준화 잔차(Standardized residuals)를 보입니다. 이는 이상점(outlier)을 탐지할 수 있는 그래프로 빨간색 추세선이 0인 직선이 가장 이상적이며 크게 벗어난 값은 이상점일 가능성이 있습니다.
plot(m1, which = 4)
- 네 번째 그래프는 Cook’s distance가 표시됩니다. 이 값의 의미는 회귀 직선의 모양(기울기나 절편 등)에 크게 영향을 끼치는 점들을 찾는 그래프입니다. 이 값은 레버리지(leverage)와 잔차에 비례합니다.
plot(m1, which = 5)
- 다섯 번째 그래프는 Residuals vs Leverage plot 입니다. 여기서 레버리지는 설명변수가 얼마나 극단에 치우쳐 있는지를 말합니다. 대부분 값들이 1~10일 때 어느 한 값이 1000을 갖는다면 그 1000을 갖는 점은 레버리지 값이 크다고 말할 수 있습니다.
- 빨간 dash line으로 Cook’s distance를 표시하기 때문에 이 부분을 고려해서 잘 살펴봐야할 필요가 있습니다.
7. 회귀직선의 시각화
- 데이터의 산점도와 회귀직선 역시
plot()
함수를 이용하여 그릴 수 있습니다. 여기서
coef()
는 회귀모델의 계수를 출력하는 함수이고abline()
함수는 주어진 절편과 기울기를 가지고 직선을 그릴 수 있는 함수라는 걸 우선 기억하시길 바랍니다.plot(cars$speed, cars$dist, xlab = "speed", ylab = "distance") abline(coef(m1), col = "blue")
그래프에 추정값의 신뢰구간을 포함시키는 방법은 우선
summary()
함수를 통해 설명변수의 최솟값과 최댓값을 먼저 확인해야 합니다.summary(cars$speed)
## Min. 1st Qu. Median Mean 3rd Qu. Max. ## 4.0 12.0 15.0 15.4 19.0 25.0
다음 그 범위 안에서
predict()
함수를 통해 신뢰구간을 구하여 따로 객체에 저장합니다.speed.range <- seq(from = 4.0, to = 25.0, by = 0.2) conf.int <- predict(m1, newdata = data.frame( speed = speed.range ), interval = "confidence")
마지막으로 행렬에 저장된 데이터를 그리는 함수
matplot()
,matlines()
함수를 이용하여 그릴 수 있습니다.matplot(speed.range, conf.int, type = "n", xlab = "speed", ylab = "distance") matlines(speed.range, conf.int, lty = c(1, 2, 2))