콘텐츠로 이동

Chapter 21: 분류 말고 회귀 - 숫자 예측하기

한 줄 요약: 분류가 "무엇인가?"를 맞추는 거라면, 회귀는 "얼마인가?"를 예측하는 것입니다.


🎯 이 장에서 배우는 것

  • [ ] 분류와 회귀의 차이를 명확히 구분할 수 있다
  • [ ] 회귀 모델로 연속적인 숫자를 예측할 수 있다
  • [ ] MAE, RMSE 등 회귀 평가 지표를 이해하고 계산할 수 있다
  • [ ] 예측값과 실제값을 비교하는 시각화를 만들 수 있다

💡 왜 이걸 배우나요?

세상의 절반은 "얼마?"라는 질문이다

지금까지 분류를 배웠어. "스팸일까 아닐까?", "고양이일까 강아지일까?" 같은 카테고리를 맞추는 문제였지.

하지만 세상의 많은 질문은 숫자로 답해야 해:

"이 집 가격이 얼마야?"           → 3억 2천만원
"내일 기온이 몇 도야?"           → 24.5도
"이 영상 조회수가 얼마나 될까?"   → 15만 뷰
"배달 도착까지 몇 분 걸려?"       → 32분
"이 주식 내일 가격이 얼마야?"    → 52,300원

분류는 정해진 선택지 중에 고르는 거고, 회귀는 무한한 숫자 중에서 정확한 값을 예측하는 거야.

이미 경험해본 회귀

사실 너도 이미 회귀를 경험했어:

  • 시험 점수 예상: "이 정도 공부했으면... 85점쯤?"
  • 도착 시간 계산: "거기까지 지하철로... 40분쯤?"
  • 가격 짐작: "이런 카페에서 아메리카노는... 4,500원쯤?"

과거 데이터와 경험을 바탕으로 숫자를 예측하는 게 바로 회귀야. 이제 컴퓨터가 이걸 더 정확하게 하도록 만들어보자!


📚 핵심 개념

개념 1: 분류 vs 회귀

비유로 시작 🎯

분류와 회귀는 마치 객관식 vs 주관식 같아요.

[객관식 - 분류]
Q: 이 동물은 무엇인가요?
   ① 고양이  ② 강아지  ③ 토끼  ④ 햄스터

[주관식 - 회귀]
Q: 이 집의 가격은 얼마인가요?
   ___________ 원

객관식은 정해진 보기 중에서 고르고, 주관식은 정확한 숫자를 직접 써야 해.

정확히 말하면: - 분류(Classification): 데이터를 정해진 범주 중 하나로 분류 - 회귀(Regression): 연속적인 숫자를 예측

예시로 확인:

질문 분류? 회귀? 이유
이 메일이 스팸인가? 분류 "스팸/정상" 둘 중 하나
이 집 가격이 얼마? 회귀 1억~100억 사이 어떤 숫자든 가능
이 학생이 합격할까? 분류 "합격/불합격" 둘 중 하나
이 학생 점수가 몇 점? 회귀 0~100 사이 어떤 숫자든 가능
이 영화가 어떤 장르? 분류 "액션/로맨스/공포" 등 정해진 장르
이 영화 평점이 몇 점? 회귀 1.0~10.0 사이 어떤 숫자든 가능

쉽게 말하면: 정해진 칸 중에 고르면 분류, 숫자를 직접 예측하면 회귀!


개념 2: 회귀는 "최적의 선 긋기"

비유로 시작 📏

회귀는 마치 데이터 점들 사이로 가장 잘 맞는 선을 긋는 것과 같아요.

가격(만원)
    │
 500┤                    ★  ← 실제 데이터
 400┤               ★  /
 300┤          ★   /
 200┤     ★    /
 100┤   ★   /  ← 이 선이 예측선!
    │___/______________________
       20  40  60  80  100  면적(㎡)

작은 집은 싸고, 큰 집은 비싸다는 패턴이 보이지? 이 패턴을 선(함수)으로 표현해서 새 데이터를 예측하는 거야.

정확히 말하면: 회귀 모델은 입력(X)과 출력(Y) 사이의 관계(함수)를 학습해. 가장 단순한 형태가 선형 회귀(Linear Regression):

Y = aX + b

가격 = (기울기) × 면적 + (기본값)
     = 5만원/㎡ × 면적 + 50만원

예시로 확인:

# 만약 기울기가 5, 기본값이 50이라면
# 30㎡ 집의 예상 가격 = 5 × 30 + 50 = 200만원
# 80㎡ 집의 예상 가격 = 5 × 80 + 50 = 450만원

쉽게 말하면: 회귀는 데이터의 패턴을 수식으로 표현하는 것!


개념 3: 회귀 평가 지표 - "얼마나 틀렸나?"

비유로 시작 🎯

분류에서는 "맞았다/틀렸다"로 평가했지? 회귀에서는 "얼마나 틀렸나"로 평가해.

[분류 - 이진적]
정답: 고양이
예측: 강아지
결과: 틀림 ❌

[회귀 - 정도의 문제]
정답: 300만원
예측: 280만원
결과: 20만원 차이 (꽤 가까움!)

정답: 300만원
예측: 100만원  
결과: 200만원 차이 (많이 틀림!)

정확히 말하면, 회귀의 대표적인 평가 지표 3가지:

1. MAE (Mean Absolute Error) - 평균 절대 오차

MAE = |오차들|의 평균

예) 실제값: [100, 200, 300]
    예측값: [90, 220, 280]
    오차:   [-10, +20, -20]
    절대값: [10, 20, 20]
    MAE = (10 + 20 + 20) / 3 = 16.67

해석: "평균적으로 16.67만큼 틀린다"

2. MSE (Mean Squared Error) - 평균 제곱 오차

MSE = (오차²)들의 평균

예) 오차:   [-10, +20, -20]
    제곱:   [100, 400, 400]
    MSE = (100 + 400 + 400) / 3 = 300

특징: 큰 오차에 더 큰 페널티 (제곱하니까)

3. RMSE (Root Mean Squared Error) - 평균 제곱근 오차

RMSE = √MSE = √300 ≈ 17.32

해석: MSE에 루트를 씌워서 원래 단위로 돌려놓음

비교 정리:

┌─────────┬───────────────────────────────────┐
│  지표   │           특징                    │
├─────────┼───────────────────────────────────┤
│  MAE    │ 직관적, 이상치에 덜 민감          │
│  MSE    │ 큰 오차에 더 민감 (제곱 효과)     │
│  RMSE   │ MSE의 해석 가능한 버전            │
└─────────┴───────────────────────────────────┘

쉽게 말하면: MAE는 "평균적으로 얼마나 틀렸나", RMSE는 "큰 실수를 더 심하게 벌주는 버전"!


개념 4: R² 스코어 - "얼마나 잘 설명하나?"

비유로 시작 📊

R²는 마치 시험에서 몇 점 맞았나와 비슷해.

R² = 0.0  → 0점 (모델이 아무것도 설명 못함)
R² = 0.5  → 50점 (절반 정도 설명)
R² = 1.0  → 100점 (완벽하게 설명)
R² < 0    → 그냥 평균 찍는 것보다 못함 😅

정확히 말하면: R²는 "모델이 데이터의 변동을 얼마나 설명하는가"를 0~1로 표현.

R² = 1 - (모델의 오차) / (그냥 평균 찍었을 때 오차)

예시로 확인:

집 가격 데이터 평균: 300만원

[그냥 평균 찍기] → 모든 집을 300만원으로 예측
[우리 모델]      → 면적 보고 예측

R² = 0.85라면?
→ "그냥 평균 찍는 것보다 85% 더 잘 설명한다"
→ "데이터 변동의 85%를 모델이 설명한다"

쉽게 말하면: R²가 1에 가까울수록 좋은 모델!


🔨 따라하기

📦 데이터셋 선택지 - 옵션 A: 캘리포니아 집 가격 (sklearn 내장) - 옵션 B: 당뇨병 진행도 예측 (sklearn 내장) - 옵션 C: 직접 만든 간단한 데이터

이 장에서는 캘리포니아 집 가격 데이터를 사용합니다. 어떤 회귀 데이터든 동일한 방법으로 분석할 수 있어요!


Step 1: 환경 준비와 데이터 불러오기

목표: sklearn에서 회귀용 데이터셋 불러오기

# === WHAT: 회귀 분석에 필요한 라이브러리와 데이터 불러오기 ===

# --- WHY: 회귀 모델과 평가 도구가 필요해서 ---

import pandas as pd  # 데이터프레임
import numpy as np   # 수치 계산
import matplotlib.pyplot as plt  # 시각화

# sklearn에서 필요한 것들
from sklearn.datasets import fetch_california_housing  # 데이터
from sklearn.model_selection import train_test_split   # 데이터 분할
from sklearn.linear_model import LinearRegression      # 선형 회귀
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score  # 평가

# --- 캘리포니아 집 가격 데이터 불러오기 ---
housing = fetch_california_housing()

# 데이터프레임으로 변환
df = pd.DataFrame(housing.data, columns=housing.feature_names)
df['Price'] = housing.target  # 타겟(집 가격)은 10만 달러 단위

print("=== 캘리포니아 집 가격 데이터 ===")
print(f"데이터 크기: {df.shape}")
print(f"\n컬럼 설명:")
print("- MedInc: 중위 소득")
print("- HouseAge: 집 연식")
print("- AveRooms: 평균 방 개수")
print("- AveBedrms: 평균 침실 개수")
print("- Population: 인구")
print("- AveOccup: 평균 거주자 수")
print("- Latitude: 위도")
print("- Longitude: 경도")
print("- Price: 집 가격 (10만 달러 단위)")
print()
print(df.head())

실행 결과: ``` === 캘리포니아 집 가격 데이터 === 데이터 크기: (20640, 9)

컬럼 설명: - MedInc: 중위 소득 - HouseAge: 집 연식 - AveRooms: