iBetter Books
수정

잔차 플롯 (residplot)

regplot으로 회귀선을 그린 민서가 물었습니다.

"선이 데이터를 잘 요약하는지 어떻게 확인하죠?"

강주원 선배가 대답했습니다.

"잔차 플롯을 봐. 예측값과 실제값의 차이를 그리는 건데, 차이가 랜덤하게 퍼져 있으면 좋은 모델이야. 패턴이 보이면 뭔가 놓친 게 있다는 신호야."

이 차트가 보여주는 것

잔차(residual)는 실제 값에서 회귀선의 예측값을 뺀 차이입니다. x축에 예측값(또는 독립 변수), y축에 잔차를 놓습니다.

좋은 선형 회귀 모델이라면 잔차가 y=0 주변에 랜덤하게 흩어져야 합니다. 특정 패턴(곡선, 팬 모양)이 보이면 선형 모델이 데이터를 충분히 설명하지 못하고 있다는 뜻입니다.

기본 잔차 플롯

import seaborn as snsimport matplotlib.pyplot as plttips = sns.load_dataset("tips")sns.residplot(data=tips, x="total_bill", y="tip")plt.axhline(y=0, color="red", linestyle="--", alpha=0.7)plt.title("잔차 플롯: 계산 금액 vs 팁")plt.xlabel("계산 금액 (달러)")plt.ylabel("잔차 (실제값 - 예측값)")plt.show()

실행 결과

plt.axhline(y=0)으로 y=0 선을 추가하면 잔차의 분포를 기준선 대비로 읽기 쉽습니다.

잔차 패턴 해석

잔차 플롯에서 나타날 수 있는 패턴과 의미를 비교합니다.

import seaborn as snsimport matplotlib.pyplot as pltimport numpy as npimport pandas as pdrng = np.random.default_rng(42)x = np.linspace(1, 10, 100)# 패턴 1: 랜덤 (선형 모델이 적합)y_good = 2 * x + rng.normal(0, 1, 100)# 패턴 2: 곡선 (비선형 관계, 선형 모델이 부적합)y_curve = x**2 + rng.normal(0, 2, 100)# 패턴 3: 팬 모양 (분산이 x에 따라 증가)y_fan = 2 * x + rng.normal(0, x * 0.5, 100)fig, axes = plt.subplots(1, 3, figsize=(15, 4))for ax, y, title in zip(    axes,    [y_good, y_curve, y_fan],    ["랜덤 (좋은 모델)", "곡선 패턴 (비선형 관계)", "팬 모양 (이분산)"]):    df = pd.DataFrame({"x": x, "y": y})    sns.residplot(data=df, x="x", y="y", ax=ax)    ax.axhline(y=0, color="red", linestyle="--", alpha=0.7)    ax.set_title(title)plt.suptitle("잔차 패턴 비교", y=1.02)plt.tight_layout()plt.show()

실행 결과

  • 첫 번째(랜덤): 선형 모델이 데이터를 잘 설명합니다.
  • 두 번째(곡선): x의 제곱 항이 필요한 비선형 관계입니다. order=2인 regplot이나 다항 회귀를 고려합니다.
  • 세 번째(팬 모양): 분산이 x에 따라 증가합니다. 로그 변환이나 가중 회귀를 고려합니다.

lowess 옵션: 국소 회귀선 추가

lowess=True를 추가하면 잔차 위에 국소 회귀선(부드러운 곡선)을 그려 패턴을 더 뚜렷이 볼 수 있습니다.

import seaborn as snsimport matplotlib.pyplot as plttips = sns.load_dataset("tips")sns.residplot(    data=tips, x="total_bill", y="tip",    lowess=True,    scatter_kws={"alpha": 0.5},    line_kws={"color": "red", "linewidth": 2})plt.axhline(y=0, color="gray", linestyle="--", alpha=0.5)plt.title("잔차 플롯 (LOWESS 곡선 포함)")plt.xlabel("계산 금액 (달러)")plt.ylabel("잔차")plt.show()

실행 결과

빨간 선이 y=0에 가깝고 수평에 가까울수록 선형 모델이 적합하다는 신호입니다.