모형성능
Contents
3.6. 모형성능#
회귀분석을 하기 위해서는 먼저 어떤 독립변수를 사용할지를 선택해야 하는데 사용하는 독립변수의 종류나 개수가 달라지면 선형회귀분석에서 가정하는 선형회귀분석 모형(model)이 달라진다. 올바른 독립변수를 선택하기 위해서는 여러가지 선형회귀분석 모형들의 성능을 비교하는 방법을 알아야 한다. 이 절에서는 선형회귀분석의 성능을 가늠하는 방법을 설명한다.
예제 데이터로는 상관관계를 설명할 때 사용하였던 보스턴 집값 데이터를 사용한다. 보스턴 집값 데이터는 13개의 독립변수를 이용하여 medv라는 종속변수를 예측한다.
import statsmodels.api as sm
boston = sm.datasets.get_rdataset("Boston", "MASS").data
boston
crim | zn | indus | chas | nox | rm | age | dis | rad | tax | ptratio | black | lstat | medv | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0.00632 | 18.0 | 2.31 | 0 | 0.538 | 6.575 | 65.2 | 4.0900 | 1 | 296 | 15.3 | 396.90 | 4.98 | 24.0 |
1 | 0.02731 | 0.0 | 7.07 | 0 | 0.469 | 6.421 | 78.9 | 4.9671 | 2 | 242 | 17.8 | 396.90 | 9.14 | 21.6 |
2 | 0.02729 | 0.0 | 7.07 | 0 | 0.469 | 7.185 | 61.1 | 4.9671 | 2 | 242 | 17.8 | 392.83 | 4.03 | 34.7 |
3 | 0.03237 | 0.0 | 2.18 | 0 | 0.458 | 6.998 | 45.8 | 6.0622 | 3 | 222 | 18.7 | 394.63 | 2.94 | 33.4 |
4 | 0.06905 | 0.0 | 2.18 | 0 | 0.458 | 7.147 | 54.2 | 6.0622 | 3 | 222 | 18.7 | 396.90 | 5.33 | 36.2 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
501 | 0.06263 | 0.0 | 11.93 | 0 | 0.573 | 6.593 | 69.1 | 2.4786 | 1 | 273 | 21.0 | 391.99 | 9.67 | 22.4 |
502 | 0.04527 | 0.0 | 11.93 | 0 | 0.573 | 6.120 | 76.7 | 2.2875 | 1 | 273 | 21.0 | 396.90 | 9.08 | 20.6 |
503 | 0.06076 | 0.0 | 11.93 | 0 | 0.573 | 6.976 | 91.0 | 2.1675 | 1 | 273 | 21.0 | 396.90 | 5.64 | 23.9 |
504 | 0.10959 | 0.0 | 11.93 | 0 | 0.573 | 6.794 | 89.3 | 2.3889 | 1 | 273 | 21.0 | 393.45 | 6.48 | 22.0 |
505 | 0.04741 | 0.0 | 11.93 | 0 | 0.573 | 6.030 | 80.8 | 2.5050 | 1 | 273 | 21.0 | 396.90 | 7.88 | 11.9 |
506 rows × 14 columns
우선 첫번째 모형으로 범죄율 crim 변수만 사용하여 medv 값을 예측해 보자. 이 때 모형 문자열은 다음과 같다.
"medv ~ scale(crim)"
선형회귀분석은 다음 코드로 실시한다.
import statsmodels.api as sm
model1 = sm.OLS.from_formula("medv ~ scale(crim)", boston)
result1 = model1.fit()
두번째로는 zn 독립변수를 사용하여 medv 값을 예측해 보자.
이 때 모형 문자열은 다음과 같다.
"medv ~ scale(zn)"
model2 = sm.OLS.from_formula("medv ~ scale(zn)", boston)
result2 = model2.fit()
이 두가지의 선형회귀분석 모형 중 어느 것이 더 나은 모형일까? 가장 먼저 생각할 수 있는 방법은 잔차제곱합 RSS(Residual Sum of Squares) 수치를 비교하는 것이다. 잔차제곱합은 결과요약에 나타나지 않고 결과 객체의 ssr
속성에 저장되어 있다.
result1.ssr, result2.ssr
(36275.512356275096, 37166.55822394634)
두 모형 중 crim 독립변수를 사용한 모형이 zn 독립변수를 사용한 모형보다 잔치제곱합이 작으므로 더 나은 모형이라고 할 수 있다.
그런데 만약 비교 대상이 되는 선형회귀분석에서 사용한 데이터의 개수가 다르면 문제가 발생한다. 잔차제곱합은 각 데이터에 대해 발생한 잔차 제곱의 합이므로 데이터의 개수가 늘어나면 증가하고 데이터의 개수가 적어지면 감소한다. 예를 들어 zn 데이터 중 일부가 누락되어가 잘못된 값이 들어가 있어서 zn 데이터를 독립변수로 사용하는 선형회귀분석에서는 데이터의 일부만 사용할 수 있다고 가정하고 다시 계산해보자. 여기에서는 데이터의 절반만 사용해보자.
model3 = sm.OLS.from_formula("medv ~ scale(zn)", boston.iloc[:len(boston)//2])
result3 = model3.fit()
result3.ssr
15732.770624734292
잔차제곱합 값은 앞에서 구한 두 개의 결과보다 훨씬 작은 값이 나왔다. 따라서 잔차제곱합을 사용하여 선형회귀분석의 성능을 비교하는 방법은 데이터 개수가 다른 경우에 사용할 수 없다.
3.6.1. 결정계수#
이러한 단점을 극복하기 위해 잔차제곱합 RSS를 특정한 범위내로 정규화(normalization)시킨 결정계수(Coefficient of Determination)라는 성능지표를 사용할 수 있다. 결정계수는 다음과 같이 계산한다.
또는
두 식 중 어떤 것을 사용해도 같은 값이 나온다. 위 식에서 TSS와 ESS는 각각 다음과 같이 정의한다.
TSS를 정의할 때 사용된 \(\bar{y}\)는 전체 \(y\) 데이터의 평균값이고 ESS를 정의할 때 사용된 \(\bar{\hat{y}}\)는 전체 예측값 \(\hat{y}\)의 평균값이다.
TSS는 Total Sum of Squares의 약자로 독립변수를 사용한 회귀분석을 하지 않았을 때의 잔차제곱합이다. 즉, 상수항만 있는 회귀분석 모형을 사용한 경우다. 이러한 모형을 1차 모형(first-order model)이라고 한다. 아무런 독립변수를 사용하지 않았을 때, 우리가 사용할 수 있는 가장 좋은 예측은 \(y\) 데이터의 평균값이다.
ESS는 Explained Sum of Squares의 약자로 회귀분석을 실시하여 구한 예측값 \(\hat{y}\) 데이터에 대해 TSS와 마찬가지 방법으로 1차 모형의 잔차제곱합을 구한 값이다.
잔차제곱합 RSS와 TSS, ESS 사이에는 다음과 같은 관계가 항상 성립한다.
만약 우리가 구한 선형회귀모형이 완벽하게 \(y\)값을 예측한다면 모든 데이터에 대해 예측값 \(\hat{y}\)과 원래 데이터 \(y\)가 같으므로 모든 잔차 \(e\)는 0이 된다. 따라서 잔차제곱합 RSS도 0이 된다.
이 때는 결정계수 \(R^2\) 값이 1이 된다.
회귀모형의 오차가 점점 증가할수록 RSS 값이 증가하므로 결정계수는 차츰 감소한다. 가장 극단적인 경우로 모든 독립변수가 아무런 의미가 없을 때는 가중치 값이 모두 0이 되므로
선형회귀모형이 상수항만 있는 1차 모형이 되고 이 경우의 잔차제곱합 RSS 값이 TSS 값과 같아진다. 따라서 결정계수 값은 0이 된다.
지금까지의 내용을 요약하면 다음과 같다.
결정계수
유의한 독립변수가 없는 최악의 경우에 결정계수는 0이된다.
선형회귀분석의 예측성능이 증가할수록 결정계수 값은 증가한다.
모든 데이터를 정확히 예측한 완벽한 경우에 결정계수는 1이 된다.
결정계수는 잔차제곱합과 달리 데이터 개수와 상관없이 0부터 1사이의 값만 가지므로 여러가지 회귀분석모형의 성능을 비교하는데 용이하다.
statsmodels 패키지를 사용한 선형회귀분석 결과 객체는 각각 다음 속성에 결정계수, RSS, TSS, ESS 값을 가지고 있다.
결정계수 :
rsquared
RSS :
ssr
TSS :
centered_tss
ESS :
ess
crim 독립변수를 사용한 회귀분석의 경우 각각의 값을 구하면 다음과 같다.
result1.centered_tss, result1.ssr, result1.ess
(42716.29541501977, 36275.512356275096, 6440.783058744673)
RSS와 ESS를 더하면 TSS와 같아지는 것을 확인할 수 있다.
result1.ssr + result1.ess
42716.29541501977
결정계수는 분석결과 요약에도 표시된다.
print(result1.summary())
OLS Regression Results
==============================================================================
Dep. Variable: medv R-squared: 0.151
Model: OLS Adj. R-squared: 0.149
Method: Least Squares F-statistic: 89.49
Date: Fri, 12 Aug 2022 Prob (F-statistic): 1.17e-19
Time: 11:23:50 Log-Likelihood: -1798.9
No. Observations: 506 AIC: 3602.
Df Residuals: 504 BIC: 3610.
Df Model: 1
Covariance Type: nonrobust
===============================================================================
coef std err t P>|t| [0.025 0.975]
-------------------------------------------------------------------------------
Intercept 22.5328 0.377 59.745 0.000 21.792 23.274
scale(crim) -3.5677 0.377 -9.460 0.000 -4.309 -2.827
==============================================================================
Omnibus: 139.832 Durbin-Watson: 0.713
Prob(Omnibus): 0.000 Jarque-Bera (JB): 295.404
Skew: 1.490 Prob(JB): 7.14e-65
Kurtosis: 5.264 Cond. No. 1.00
==============================================================================
Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
상단 오른쪽 열의 가장 윗쪽, 첫번째에 있는 R-squared
값이 결정계수다.
OLS Regression Results
==============================================================================
R-squared: 0.151
결정계수를 사용하여 crim 독립변수를 사용한 회귀분석과 zn 독립변수를 사용한 회귀분석의 성능을 비교하면 crim 독립변수를 사용한 첫번째 모형의 성능이 더 우수한 것을 알 수 있다.
result1.rsquared, result2.rsquared
(0.15078046904975717, 0.12992084489428946)
참고로 결정계수의 수학기호가 \(R^2\)인 이유는 결정계수값이 종속변수의 원 데이터 값과 예측값 사이의 상관계수(\(\rho\))의 제곱과 같은 값이기 때문이다. 실제로 계산해 보면 같은 값이 나온다.
from scipy.stats import pearsonr
r1 = pearsonr(result1.model.endog, result1.fittedvalues)[0]
r2 = pearsonr(result2.model.endog, result2.fittedvalues)[0]
r1 ** 2, r2 ** 2
(0.15078046904975695, 0.129920844894289)
3.6.2. F-검정#
모형의 성능을 살펴보는 또다른 방법은 선형회귀분석 F-검정(regression F-test) 혹은 간단하게 F-검정이다. F-검정은 다음과 같은 귀무가설을 검증하는 것이다.
이 귀무가설은 우리가 회귀분석에 사용한 독립변수 중 어느 것도 유의한 것이 없다는 뜻이다. 우리가 아무런 상관관계도 없는 독립변수만 골라서 넣을리는 없기 때문에 현실에서 대부분의 경우 이 귀무가설은 기각된다. 다만 유의확률이 작으면 작을수록 귀무가설을 더 강력하게 기각한 것이므로 더 의미가 있는 모형이라고 할 수 있다. 따라서 여러 모형의 유의확률을 비교하여 어느 모형이 더 성능이 좋은가를 비교할 때 이 유의확률을 사용할 수 있다.
위에서 사용한 귀무가설을 결정계수와 결합하여 생각해보면 모든 독립변수의 계수가 유의하지 않다는 것은 회귀분석 모형이 1차 모형과 같아지는 최악의 경우이다. 이때는 RSS 값이 TSS와 같아져서 결정계수 \(R^2\)의 값이 0이된다. 따라서 F-검정의 귀무가설은 다음 귀무가설과 같다고 볼 수 있다.
F-검정이라는 이름은 ESS값을 잔차제곱합으로 나눈 ESS/RSS 값이 F분포라는 확률분포를 따른다는 점에서 나온 것이다.
결정계수 \(R^2\)가 1에 가까울수록 (모형성능이 좋을수록) RSS가 감소하고 ESS는 증가하므로 ESS/RSS 값이 커지고 F-검정의 유의확률은 감소한다. 반대로 결정계수 \(R^2\)가 0에 가까울수록 (모형성능이 나빠질수록) ESS/RSS 값은 작아지고 F-검정의 유의확률이 증가한다. 따라서 F-검정의 ESS/RSS 값이 크거나 유의확률이 작을수록 더 뛰어난 회귀분석 성능을 보인다고 할 수 있다.
RSS/ESS 값과 F-검정의 유의확률은 각각 회귀분석 결과 객체의 fvalue
, f_pvalue
속성에 저장되어 있다.
result1.fvalue, result1.f_pvalue
(89.4861147576812, 1.1739870821944483e-19)
이 값은 결과요약의 상단 오른쪽 열에도 나타나는데 각각 F-statistic
, Prob (F-statistic)
라는 이름으로 표시된다.
OLS Regression Results
==============================================================================
F-statistic: 89.49
Prob (F-statistic): 1.17e-19
F-검정을 사용하여 crim 독립변수를 사용한 회귀분석과 zn 독립변수를 사용한 회귀분석의 성능을 비교하면 결정계수를 사용하였을 때와 마찬가지로 crim 독립변수를 사용한 첫번째 모형의 성능이 더 우수한 것을 알 수 있다.
result1.fvalue, result2.fvalue
(89.4861147576812, 75.2576422989542)
result1.f_pvalue, result2.f_pvalue
(1.1739870821944483e-19, 5.71358415308128e-17)
3.6.3. 로그가능도#
지금까지는 가중치를 구하기 위해 잔차제곱합을 최소화하는 최소자승법을 사용했지만 몇가지 확률론적 가정을 한다면 앞 장에서 설명한 최대가능도추정(MLE: Maximum Likelihood Estimation) 방법으로도 가중치를 구할 수 있다. 자세한 증명은 생략하겠지만 일반적인 경우에는 최대가능도추정 방법으로 가중치를 구해도 최소자승법으로 구한 값과 같은 값이 나오게 된다. 즉, 다음과 같은 수식으로 가중치가 구해진다.
최대가능도추정법은 우리가 가진 데이터가 나올 가능성 즉, 가능도(likelihood)를 가장 크게 만드는 모수값을 찾는 방법이었다. 가능도에 로그(log)를 취한 로그가능도를 최대화하는 모수를 찾아도 같은 결과가 나온다. 최대가능도추정법을 사용하여 구한 경우에는 우리가 구한 가중치에 대한 (로그)가능도를 계산할 수 있다. 가능도나 로그가능도가 클수록 모형성능이 좋다.
선형회귀분석 결과요약에서 상단 오른쪽열의 Log-Likelihood
정보가 로그가능도 값이다.
OLS Regression Results
==============================================================================
Log-Likelihood: -1798.9
로그가능도는 보통 음수인 경우가 많기 때문에 두 값을 비교할 때 주의해야 한다. 로그가능도 값이 클수록 좋은 모형이라고 했는데 이는 (부호를 뺀) 절대값만 크다는 뜻이 아니라 부호까지 감안하여 더 큰 수를 의미한다.
분석결과 객체는 llf
속성에 로그가능도 값을 저장하고 있다. 로그가능도를 사용하여 crim 독립변수를 사용한 회귀분석과 zn 독립변수를 사용한 회귀분석의 성능을 비교하면 마찬가지로 crim 독립변수를 사용한 첫번째 모형의 성능이 더 우수한 것을 알 수 있다.
result1.llf, result2.llf
(-1798.8903655469715, -1805.029780329389)