[데이터 칼럼] 회귀모델의 절편을 0 으로 조정 했을때 결정계수는 어떻게 변할까?
과거에 저는 밀 종자의 면적을 구하기 위해 밀 종자를 이미지 스캔하고, 그 다음에는 각 밀 종자의 면적에 해당하는 무게를 측정하였습니다. 다음 회귀 분석은 밀 종자의 면적과 무게 간의 관계를 보여줍니다.
# Data download https://www.kaggle.com/datasets/agronomy4future/wheat-grain-area-vs-weight
위 데이터를 제 Github 에서 R 로 업로드 하겠습니다.
#to upload data
library(readr)
github="https://raw.githubusercontent.com/agronomy4future/raw_data_practice/main/wheat_grain_area_vs_weight.csv"
dataA=data.frame(read_csv(url(github),show_col_types = FALSE))
그리고 통계 분석을 해 보겠습니다.
# to analyze linear regression
model=lm(grain_weight ~ grain_area, data=dataA)
summary(model)
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -13.7155 0.4866 -28.19 <2e-16 ***
grain_area 3.3333 0.0266 125.32 <2e-16 ***
Residual standard error: 2.965 on 1330 degrees of freedom
Multiple R-squared: 0.9219, Adjusted R-squared: 0.9219
F-statistic: 1.57e+04 on 1 and 1330 DF, p-value: < 2.2e-16
회귀모형 y= 3.3333x - 13.7155
을 Excel 과 R을 사용하여 얻었습니다. 여기서 y 는 밀 종자 무게(mg) 이고, x 는 밀 종자 면적(mm2) 입니다. 그러나 이 모델에서, x 값이 작아지는 어느 시점부터 y 값은 음수 값이 되는데, 이는 밀 종자 면적이 특정 지점 이하로 감소할 때 밀 종자 무게가 음수가 될 것으로 예측되는 비현실적인 상황입니다. 이 문제를 해결하기 위해, 우리는 간단히 절편을 0으로 조정할 수 있습니다.
Excel 에서는 ‘Format Trendline
‘ 에서 ‘Set Intercept
‘ 을 선택하여 절편을 0으로 조정 할 수 있습니다.
엑셀에서 절편을 0으로 조정한 뒤 새로운 회귀 모델인 y= 2.594x
를 얻었습니다. 이 모델의 R2 값은 0.9938입니다. 그러나 그래프를 보니 잔차 (residuals) 가 비교적 크게 나타나는 것으로 보입니다. 이는 Excel 이 제공하는 R2 값의 정확도에 대한 의문을 품게 만듭니다. 따라서 이 회귀모델에서 R2 값이 0.99 가 진짜 맞는 값인지 궁금해 집니다.
Excel이 제공한 R2 값에 의심이 생겨서 R 을 이용하여 절편을 0으로 조정해 봤습니다.
#to upload data
library(readr)
github="https://raw.githubusercontent.com/agronomy4future/raw_data_practice/main/wheat_grain_area_vs_weight.csv"
dataA=data.frame(read_csv(url(github), show_col_types = FALSE))
grain_area grain_weight
1 15.57 43.40
2 17.14 49.70
3 16.24 45.20
4 7.85 11.00
5 14.32 36.40
6 10.93 25.60
7 18.69 55.60
8 10.81 24.50
9 16.90 49.90
10 13.79 42.20
.
.
.
# to force intercept to 0
intercept_zero=lm (grain_weight ~ 0 + grain_area, data=dataA)
summary (intercept_zero)
Coefficients:
Estimate Std. Error t value Pr(>|t|)
grain_area 2.594003 0.005611 462.3 <2e-16 ***
Residual standard error: 3.746 on 1331 degrees of freedom
Multiple R-squared: 0.9938, Adjusted R-squared: 0.9938
F-statistic: 2.137e+05 on 1 and 1331 DF, p-value: < 2.2e-16
R 로 절편을 0 으로 조정했을 때 그 값은 Excel 이 제공한 값과 동일하지만, 이 R2 값이 틀렸다는 생각에는 변함이 없습니다. 그래서, 기본으로 돌아가 직접 R2 을 계산해보겠습니다.
Step 1) 절편을 0 으로 조정하기전 R2 계산하기
1) 예측값 계산하기
엑셀에서 회귀모형 y = 3.3333x - 13.716
을 이용해서 예측값을 계산하겠습니다.
R 에서 아래 코드로 쉽게 예측값을 계산할 수 있습니다.
model=lm(grain_weight ~ grain_area, data=dataA)
prediction_calculation=predict(model)
dataA$prediction_value=prediction_calculation
grain_area grain_weight prediction_value
1 15.57 43.40 38.18340
2 17.14 49.70 43.41663
3 16.24 45.20 40.41669
4 7.85 11.00 12.45061
.
.
.
2) 데이터 파티셔닝 하기
이제 데이터를 파티셔닝 해 보겠습니다. 기본 개념은 Data = Fit + Error
입니다.
이 개념은 아래의 단순 선형 회귀 모델에 기반합니다. 아래 모델 계산식을 자세히 살펴 보시면 위 계산식이 어떻게 이루어 지는지 이해가 가실 겁니다.
3) Sum of squares 계산하기
다음으로 각각의 값을 제곱하고 각각의 제곱의 합을 계산하겠습니다. 그래서 Sum of squares 입니다.
위 계산식에서 우리는 SST = SSR + SSE
라는 것을 증명할 수 있습니다.
하지만 소수점 문제로 인해 계산에 약간의 차이가 있을 수 있습니다. 우리는 값이 소수점 네 번째 자리까지 반올림된 모델 방정식 y=3.3333x - 13.7155
를 사용했기 때문입니다. 실제 값은 정확히 3.3333이나 13.7155 가 아닐 수 있습니다. R에서 동일한 계산을 수행하여 결과를 비교하겠습니다.
y_mean=mean(dataA$grain_weight)
dataA$Data=dataA$grain_weight-y_mean
dataA$Fit=dataA$prediction_value-y_mean
dataA$Error=dataA$grain_weight-dataA$prediction_value
dataA$SST=(dataA$Data)^2
dataA$SSR=(dataA$Fit)^2
dataA$SSE=(dataA$Error)^2
sum(dataA$SST)
[1] 149735.9
sum(dataA$SSR)
[1] 138044.8
sum(dataA$SSE)
[1] 11691.09
sum(dataA$SST) - (sum(dataA$SSR) - sum(dataA$SSE))
[1] 0.000000
소수점 반올림 없이 계산 했을때 우리는 SST = SSR + SSE
라는 것을 증명할 수 있습니다.
4) R2 계산하기
이제 아래 계산식을 이용하여 R2 를 계산해 보겠습니다.
R2 는 0.9219 (=138047.88 / 149735.93) 입니다. 이 값은 앞에서 엑셀과 R 이 제공 했던 값과 동일합니다.
Step 2) 절편이 0 으로 조정된 R2 계산하기
이제 절편이 0 으로 조정 되었을때의 R2 를 계산해 보겠습니다. 이 계산식은 엑셀과 R 이 어떤 로직으로 0.9938 이라는 새로운 R2 값을 제공했는지 추적하는 작업 입니다.
여기서 중요한 것은, 절편이 0 으로 조정되었을때, SST (Sum of Squares Total) 는 Σ(yi - ȳ)2
로 계산된 것이 아니라 Σ(yi)2
로 계산되었습니다. 또한 SSR (Sum of Squares due to regression) 역시 Σ(ŷi - ȳ)2
로 계산된 것이 아니라 Σ(ŷi)2
로 계산이 되었습니다. 오직 SSE (Sum of Squared Error) 만이 Σ(yi - ŷi)2
로 계산이 되었습니다.
결국 SST 와 SSR 은 극단적으로 커지게 됩니다. 첫번째 오류는 여기서 발생 됩니다. 만일 우리가 기존의 R2 = SSR / SST
를 생각한다면, 절편이 0 으로 조정되었을때의 R2 는 0.9938 (= 2999131.15 / 3017806.25) 이 될 것입니다. 즉, 이 값은 엑셀과 R 이 제공한 값과 동일 합니다.
가끔은 소프트웨어 프로그램이 틀릴 때도 있다!!
우리는 프로그램이 제공하는 값들을 의심 없이 받아들입니다. 그러나 절편을 0으로 조정 했을 때, R2 = SSR / SST
으로 구한 결정계수 R2 는 틀린 값입니다. 대신, 절편을 0으로 조정 했을 때, R2는 아래와 같이 계산되어야 합니다.
R2 = 1 – SSE (when intercept is 0) / SST (when intercept exists)
오직 SSE (Sum of Squared Error) 만이 절편이 존재할 때 처럼 Σ(yi - ŷi)2
로 계산이 되었고 나머지 SST 와 SSR 는 절편이 존재할 때 와는 다른 방법으로 계산이 되었습니다. 그러므로, 다른 가정 하에서 얻은 SST와 SSR 값을 사용하여 절편이 0인 경우의 R2 를 계산하는데 이용할 수 없습니다.
절편을 0으로 조정 했을 때의 새로운 R2 계산식은 여러 수학자들에게서 검증을 받았습니다.
https://stats.stackexchange.com/questions/495217/when-forcing-intercept-to-zero-how-r-squared-is-changed
만약 절편을 0으로 설정 했을 때 위에서 제안한 방정식을 사용하여 R2 를 계산한다면,
R2
= 1 - 18675.90 / 149735.93 ≈ 0.875
R2 는 0.875 가 될 것입니다. 즉 절편을 0 으로 조정하면 R2 는 무조건 낮아져야 합니다.
“회귀 모델은 오차를 최소화하는 위치에 선을 그은 것을 의미합니다. 그러므로, 우리가 인위적으로 그 선을 조작한다면, R2 는 감소해야 합니다. 다시 말해, 우리가 회귀 선을 인위적으로 조작하여 더 높은 R2 를 얻었다면 기존의 회귀 모델은 잘못된 것 이라는 것을 의미합니다.“
FYI
엑셀의 다른 언어 버전이 다른 R2 값을 제공한다는 것을 발견했습니다. 영어 버전의 엑셀은 잘못된 R2 값을 계산했는데 (0.9938), 스페인어 버전의 엑셀은 올바른 R2 값을 계산했습니다 (0.875). 왜 그런지 모르겠습니다. 다른 언어 버전은 어떨지 궁금하긴 합니다.