회귀 모형이 맞는지 확인하는 법: R²에서 교차검증까지

회귀분석 모형의 가정 검토부터 R²·AIC·BIC 같은 적합도 지표, 교차 검증, 잔차 분석까지 신뢰할 수 있는 모델을 검증하는 방법을 정리한다.

2026-08-13 · 최초 발행 2025-05-23

회귀 모델을 만드는 것과 그 모델을 믿어도 되는지 확인하는 것은 다른 작업이다. 회귀분석은 변수 간의 관계를 모델링하는 통계 기법으로 데이터 분석과 예측에 광범위하게 활용되지만, 적절한 평가 없이 회귀 모델을 활용하면 잘못된 의사결정으로 이어질 수 있다.

모델이 정확한지, 과적합인지, 변수 선택이 맞는지 확인하는 이유

회귀분석 모형 적합도 평가는 여러 이유로 중요하다. 구축된 모델이 실제 데이터를 얼마나 잘 설명하고 예측하는지 확인하는 모델의 정확성 검증, 모델이 훈련 데이터에 지나치게 맞춰지거나 핵심 패턴을 놓치는 문제를 감지하는 과적합(Overfitting)·과소적합(Underfitting) 식별, 모델에 포함된 독립변수들이 종속변수를 설명하는 데 적합한지 평가하는 변수 선택의 적절성 판단, 그리고 평가 결과를 바탕으로 한 모델 개선 방향 제시가 그 이유다.

선형성부터 다중공선성까지, 가정이 지켜졌는지 먼저 본다

적합도를 평가하기 전에 회귀분석의 기본 가정들이 충족되는지 확인해야 한다.

선형성(Linearity)은 독립변수와 종속변수 간 선형 관계를 가정하며, 잔차 대 예측값 산점도로 검증하고 비선형 패턴이 발견되면 변수 변환을 고려한다. 독립성(Independence)은 오차항 간 독립성을 가정하며, Durbin-Watson 검정으로 자기상관을 확인하고 값이 2에 가까울수록 자기상관이 없음을 의미한다. 등분산성(Homoscedasticity)은 오차항의 분산이 일정하다는 가정으로, Breusch-Pagan 검정이나 White 검정으로 평가하며 잔차 대 예측값 산점도에서 패턴이 없어야 한다. 정규성(Normality)은 오차항이 정규분포를 따른다는 가정으로 Shapiro-Wilk 검정, Q-Q 플롯으로 확인하며 표본 크기가 클 경우 중심극한정리에 따라 덜 중요해진다. 다중공선성(Multicollinearity) 부재는 독립변수 간 높은 상관관계가 없어야 한다는 가정으로, 분산팽창계수(VIF) 계산으로 확인하며 일반적으로 VIF > 10이면 문제가 있다고 간주한다.

R²와 수정된 R², MSE·MAE·AIC·BIC로 적합도를 잰다

결정계수(R²)는 회귀모델이 종속변수의 변동을 설명하는 비율을 나타낸다. R² = 1 - (SSE/SST)로 계산하며, SSE는 오차제곱합(Sum of Squared Errors), SST는 총제곱합(Total Sum of Squares)이다. 범위는 0 ≤ R² ≤ 1이고 값이 1에 가까울수록 모델 설명력이 높지만, 독립변수가 추가될수록 R²는 항상 증가하는 문제가 있다.

높을수록낮을수록전체 변동회귀에 의한 변동잔차에 의한 변동 증가

수정된 결정계수(Adjusted R-squared)는 독립변수 추가에 따른 R² 증가 문제를 보완한 지표로, Adjusted R² = 1 - [(1-R²)(n-1)/(n-k-1)]로 계산한다(n: 표본 크기, k: 독립변수 수). 불필요한 변수를 추가하면 감소할 수 있어 모델 비교에 더 적합하다.

평균제곱오차(MSE)와 평균제곱근오차(RMSE)는 예측값과 실제값 차이의 제곱 평균이다. MSE = Σ(y - ŷ)²/n, RMSE = √MSE로 계산하며, 값이 작을수록 모델 성능이 우수하고 RMSE는 원래 종속변수와 같은 단위로 해석할 수 있지만 이상치에 민감하다.

평균절대오차(MAE)는 예측값과 실제값 차이의 절대값 평균으로 MAE = Σ|y - ŷ|/n이다. 이상치에 상대적으로 덜 민감하고 해석이 직관적이다.

AIC(Akaike Information Criterion)와 BIC(Bayesian Information Criterion)는 모델의 복잡성을 고려한 적합도 지표다. AIC = 2k - 2ln(L)(k: 모델 파라미터 수, L: 우도함수의 최댓값), BIC = k·ln(n) - 2ln(L)(n: 표본 크기)로 계산하며, 값이 작을수록 모델이 우수하고 서로 다른 모델 비교에 유용하다. BIC는 AIC보다 모델 복잡성에 더 큰 페널티를 부여한다.

모델 적합도 평가설명력 기반오차 기반정보 기준AdjustedMSE/RMSEMAEAICBIC

k-fold부터 시계열 분할까지, 교차 검증으로 일반화 성능을 확인한다

단일 데이터셋에서의 적합도 평가를 넘어 모델의 일반화 성능을 평가하는 방법이 교차 검증이다.

k-fold 교차 검증은 데이터를 k개 부분으로 나누어 k번 검증을 반복한다. 각 반복에서 k-1개 부분은 훈련용, 나머지 1개 부분은 검증용으로 쓰며, 최종 성능은 k번 검증 결과의 평균값으로 판단한다.

검증용검증용검증용검증용검증용전체 데이터셋Fold 1Fold 2Fold 3...Fold k반복 1반복 2반복 3...반복 k평균 성능 계산

홀드아웃(Hold-out) 방법은 데이터를 훈련용·검증용·테스트용으로 분할해 평가한다. 일반적으로 6:2:2 또는 7:1.5:1.5 비율로 분할하며, 훈련 데이터로 모델을 학습하고 검증 데이터로 하이퍼파라미터를 튜닝하며 테스트 데이터로 최종 성능을 평가한다.

시간 의존성이 있는 데이터는 시간 기반 분할(Time-based split), 확장 윈도우(Expanding window), 롤링 윈도우(Rolling window) 같은 특수한 교차 검증 방법을 쓴다.

잔차를 들여다보면 안 보이던 문제가 보인다

잔차 플롯(Residual Plot)은 예측값에 대한 잔차 산점도로 패턴을 확인한다. 이상적인 경우 잔차가 무작위로 0을 중심으로 분포하며, 패턴이 있다면 모델 가정 위반 가능성을 시사한다.

표준화 잔차(Standardized Residuals)는 잔차를 표준편차로 나눈 값으로, 일반적으로 ±2 또는 ±3 범위 내에 있어야 하며 범위 밖의 값은 이상치 가능성을 시사한다.

레버리지(Leverage)는 독립변수의 특이값을 측정하고, 쿡의 거리(Cook's distance)는 해당 관측치를 제거했을 때의 모델 변화를 측정해 영향점(Influential Points)을 찾아낸다.

주택 가격 예측 모델로 보는 적합도 평가 전 과정

가상의 주택 가격 예측 모델로 적합도 평가 프로세스를 살펴본다. 독립변수는 면적, 방 개수, 건축 연도, 학군 점수다.

# 가상의 코드 예시
import statsmodels.api as sm
import numpy as np

# 독립변수: 면적, 방 개수, 건축 연도, 학군 점수
X = df[['area', 'rooms', 'year_built', 'school_score']]
X = sm.add_constant(X)
y = df['price']

# 모델 구축
model = sm.OLS(y, X).fit()

기본 가정을 검증하려면 다중공선성과 자기상관을 확인한다.

# 다중공선성 확인
from statsmodels.stats.outliers_influence import variance_inflation_factor
vif = [variance_inflation_factor(X.values, i) for i in range(X.shape[1])]

# Durbin-Watson 검정
from statsmodels.stats.stattools import durbin_watson
dw = durbin_watson(model.resid)

적합도는 결정계수, AIC/BIC, RMSE로 평가한다.

# 결정계수와 수정된 결정계수
print(f"R-squared: {model.rsquared}")
print(f"Adjusted R-squared: {model.rsquared_adj}")

# AIC, BIC
print(f"AIC: {model.aic}")
print(f"BIC: {model.bic}")

# RMSE
import numpy as np
from sklearn.metrics import mean_squared_error
rmse = np.sqrt(mean_squared_error(y, model.predict(X)))

교차 검증은 5-fold로 진행한다.

from sklearn.model_selection import KFold
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error

kf = KFold(n_splits=5, shuffle=True, random_state=42)
rmse_scores = []

for train_idx, test_idx in kf.split(X_no_const):
    X_train, X_test = X_no_const.iloc[train_idx], X_no_const.iloc[test_idx]
    y_train, y_test = y.iloc[train_idx], y.iloc[test_idx]

    lr = LinearRegression()
    lr.fit(X_train, y_train)
    y_pred = lr.predict(X_test)

    rmse = np.sqrt(mean_squared_error(y_test, y_pred))
    rmse_scores.append(rmse)

print(f"Average RMSE from 5-fold CV: {np.mean(rmse_scores)}")

잔차는 산점도와 Q-Q 플롯으로 시각화한다.

import matplotlib.pyplot as plt
import seaborn as sns

# 잔차 플롯
plt.figure(figsize=(10, 6))
plt.scatter(model.predict(X), model.resid)
plt.axhline(y=0, color='r', linestyle='-')
plt.xlabel('Predicted Values')
plt.ylabel('Residuals')
plt.title('Residual Plot')
plt.show()

# Q-Q 플롯
from statsmodels.graphics.gofplots import qqplot
qqplot(model.resid, line='45', fit=True)
plt.title('Q-Q Plot of Residuals')
plt.show()

실무에서는 이 결과를 바탕으로 의사결정을 내린다. R² = 0.82, Adjusted R² = 0.81로 모델 설명력은 양호했고, RMSE = 50,000(USD)로 평균 오차가 크지 않았다. 다만 다중공선성 검사 결과 '면적'과 '방 개수' 변수 간 VIF > 10으로 높은 상관관계가 발견됐고, 잔차 플롯에서는 예측값이 커질수록 잔차가 커지는 이분산성 문제가 나타났으며 고가 주택에서 예측 성능이 저하되는 문제가 확인됐다.

변수 변환, 정규화, 비모수 모델로 모델을 개선하는 방법

적합도 평가 결과를 바탕으로 모델을 개선하는 방향은 여러 갈래다. 비선형 관계를 해결하기 위한 로그 변환·다항식 변환 같은 변수 변환, 단계적 회귀분석·LASSO·Ridge를 통한 변수 선택 최적화, 영향점 제거나 가중치 조정 같은 이상치 처리, 의사결정 트리·랜덤 포레스트 같은 비모수적 접근법 고려, 여러 모델의 결과를 결합하는 모델 앙상블이 그 방법이다.

회귀분석 모형의 적합도 평가는 R²과 같은 단일 지표에 의존하기보다 다양한 지표와 방법을 종합적으로 활용해야 한다. 기본 가정 검증부터 교차 검증, 잔차 분석에 이르는 체계적인 접근이 필요하며, 적합도 평가는 모델 개발의 마지막 단계가 아니라 더 나은 모델을 구축하기 위한 반복적 프로세스의 일부로 이해해야 한다. 데이터 과학자와 분석가는 모델의 통계적 성능뿐 아니라 실무적 활용 가치를 함께 고려해야 하며, 예측 정확도와 해석 가능성 사이의 균형을 맞추고 문제 도메인에 적합한 평가 지표를 선택하는 것이 중요하다.

회귀분석모형적합도교차검증잔차분석다중공선성