모델이 얼마나 틀렸는지 재는 비용 함수
Machine Learning

모델이 얼마나 틀렸는지 재는 비용 함수

2026.01.04.
ML 기초39편
  1. 1머신러닝은 데이터에서 규칙을 찾는다, 지도·비지도·강화학습
  2. 2문제 정의부터 배포까지, 머신러닝 프로젝트의 전 과정
  3. 3데이터에 가장 잘 맞는 직선을 찾는 선형 회귀
  4. 4모델이 얼마나 틀렸는지 재는 비용 함수읽는 중
  5. 5비용 함수의 바닥까지 걸어 내려가는 경사하강법
1 / 8

선형 회귀의 목표는 잔차를 최소화하는 직선을 찾는 것이다. 그런데 데이터가 100개면 잔차도 100개다. 숫자 100개를 동시에 “최소화”한다는 게 정확히 무슨 뜻인가?

여기서 비용 함수(Cost Function) 가 나온다. 여러 개의 잔차를 숫자 하나로 요약하는 함수다. 이 숫자가 작을수록 모델이 데이터를 잘 맞추고 있다는 뜻이고, 학습이란 이 숫자를 최대한 줄이는 일이다.

요약하는 방식은 하나가 아니다. 어느 쪽을 고르느냐에 따라 모델이 어떤 종류의 오차를 더 싫어하는지가 달라진다.

여러 개의 잔차를 숫자 하나로

잔차는 실제값에서 예측값을 뺀 값이다. 잔차 네 개가 +3,−2,+1,−2+3, -2, +1, -2로 나왔다고 하자.

그냥 더하면 합이 0이다. 네 예측이 전부 틀렸는데 오차가 없는 것처럼 보인다. 양수 잔차(과소 예측)와 음수 잔차(과대 예측)가 서로 상쇄되기 때문이다. 부호를 먼저 없애지 않으면 어떤 요약도 성립하지 않는다.

절댓값을 씌워 평균 내면 (3+2+1+2)/4=2.0(3+2+1+2)/4 = 2.0이 된다. 이게 평균 절대 오차(Mean Absolute Error, MAE) 다. 직관적이고 단위도 원래 값과 같다. 다만 절댓값 함수는 0에서 꺾여 미분이 깔끔하지 않다.

제곱해서 평균 내면 (9+4+1+4)/4=4.5(9+4+1+4)/4 = 4.5가 된다. 부호가 사라지는 건 절댓값과 같지만, 큰 오차가 더 크게 반영된다는 점이 다르다. 이게 평균 제곱 오차(Mean Squared Error, MSE) 이고 회귀 문제의 기본 비용 함수다.

MSE의 정의

J(w,b)=1n∑i=1n(y(i)−y^(i))2,y^(i)=wx(i)+bJ(w, b) = \frac{1}{n}\sum_{i=1}^{n}\left(y^{(i)} - \hat{y}^{(i)}\right)^2, \qquad \hat{y}^{(i)} = wx^{(i)} + b

nn은 데이터 개수, y(i)y^{(i)}는 ii번째 실제값, y^(i)\hat{y}^{(i)}는 ii번째 예측값이다. JJ가 비용(Cost)이고, 이 값을 최소로 만드는 w,bw, b를 찾는 게 학습의 목표다. 합계가 아니라 평균을 쓰는 이유는 데이터 개수가 다른 모델끼리도 값을 견줄 수 있게 하기 위해서다. 참고로 개별 포인트의 오차 (y^(i)−y(i))2\left(\hat{y}^{(i)} - y^{(i)}\right)^2만 가리킬 때는 손실 함수(Loss Function)라 부르지만, 실무에서 두 용어는 거의 구분 없이 쓰인다.

면적과 가격 데이터 8건으로 직접 계산해보자.

import numpy as np
from sklearn.linear_model import LinearRegression

area = np.array([60, 75, 85, 95, 110, 120, 140, 155]).reshape(-1, 1)   # ㎡
price = np.array([2.1, 2.8, 3.2, 3.6, 4.1, 4.5, 5.2, 5.8])             # 억 원

model = LinearRegression().fit(area, price)
y_pred = model.predict(area)
print(f"{np.mean((price - y_pred) ** 2):.6f}")  # 0.002542 (= mean_squared_error 결과)

0.0025는 제곱된 값이라 그대로는 감이 오지 않는다. 제곱근을 씌우면 0.0025≈0.05\sqrt{0.0025} \approx 0.05, 예측이 500만 원 안팎으로 빗나간다는 뜻이 된다. 이 J\sqrt{J}가 RMSE이고, 단위가 yy와 같아서 사람이 읽기 좋다.

분모에 2를 넣는 관습

교과서에 따라 J=12n∑(y^−y)2J = \frac{1}{2n}\sum\left(\hat{y} - y\right)^2로 쓰기도 한다. 미분할 때 제곱의 지수 2가 앞으로 나오면서 12\frac{1}{2}과 상쇄되어 식이 깔끔해지기 때문이다. 함수 전체에 상수를 곱해도 최솟값의 위치는 바뀌지 않으므로 어느 쪽을 써도 학습 결과는 같다.

왜 절댓값이 아니라 제곱인가

큰 오차에 더 큰 벌점

제곱은 큰 잔차를 불균형하게 키운다.

잔차 절댓값 (MAE 기여분) 제곱 (MSE 기여분)
0.5 0.5 0.25
1.0 1.0 1.00
2.0 2.0 4.00
5.0 5.0 25.00

잔차가 5일 때 MAE는 “5만큼 나쁘다”고 보지만 MSE는 “25만큼 나쁘다”고 본다. 조금씩 빗나간 예측 여럿보다 크게 빗나간 예측 하나가 보통 더 곤란하니, 대부분의 회귀 문제에서 이쪽이 바람직하다.

어디서나 미분된다

절댓값 함수와 제곱 함수 x x² |x| x = 0에서 꺾임

절댓값 함수는 x=0x = 0에서 꺾이고, 그 점에서 미분값이 정의되지 않는다. 왼쪽에서 다가가면 기울기가 −1-1, 오른쪽에서 다가가면 +1+1이라 하나로 정해지지 않는다. 반면 x2x^2은 모든 구간에서 매끄럽고 x=0x = 0에서 기울기가 정확히 0이다.

이게 중요한 이유는 최적화 알고리즘이 비용 함수의 미분값을 따라 파라미터를 옮기기 때문이다. 기울기가 정의되지 않는 지점이 있으면 그 근처에서 갱신이 불안정해진다. MAE도 subgradient 같은 기법으로 쓸 수 있으니 불가능한 건 아니지만, MSE 쪽이 다루기 쉬운 건 분명하다.

최솟값이 하나뿐이다

선형 회귀의 MSE는 파라미터 w,bw, b에 대해 볼록 함수(Convex Function) 다. 볼록 함수에서는 국소 최솟값이 곧 전역 최솟값이라, 어느 지점에서 출발해 내려가든 같은 바닥에 도착한다. 최적화 알고리즘이 “여기가 진짜 바닥인가”를 의심할 필요가 없다는 뜻이다.

비용 함수의 모양

비용 함수를 이해하는 가장 빠른 방법은 직접 그려보는 것이다. 절편 bb를 최적값에 고정하고 기울기 ww만 바꿔가며 J(w)J(w)를 계산한다.

w_values = np.linspace(-0.01, 0.08, 200)
b = -0.08176
costs = [np.mean((price - (w * area.ravel() + b)) ** 2) for w in w_values]
기울기 w에 따른 비용 J(w) 비용 J 파라미터 w 기울기 0 최적 w

깨끗한 포물선이다. ww가 너무 작으면 직선이 눕는 바람에 넓은 집의 가격을 크게 과소 예측하고, 너무 크면 직선이 가팔라져 좁은 집을 과대 예측한다. 양쪽 모두 비용이 커지고 그 사이 한 점에서만 최소가 된다.

바닥에서는 곡선의 기울기가 0이다. “비용을 줄인다”는 막연한 목표가 “기울기가 0인 지점을 찾는다”는 계산 가능한 문제로 바뀌는 자리가 여기다.

ww와 bb가 함께 변하면 J(w,b)J(w, b)는 밥그릇 모양의 3차원 곡면이 되고, 그릇의 바닥이 최적의 (w∗,b∗)(w^{*}, b^{*})다.

볼록한 건 모델이 선형이라서다

비용 함수가 매끈한 그릇 모양인 건 예측식이 파라미터에 대해 선형이기 때문이다. 신경망처럼 비선형 모델에서는 비용 지형이 울퉁불퉁해져 국소 최솟값이 여럿 생기고, 어디서 출발하느냐에 따라 도착하는 바닥이 달라진다.

MSE 말고 다른 선택지

비용 함수 정의 이상치 민감도 미분 주 용도
MSE 잔차 제곱의 평균 높음 매끄러움 회귀의 기본값
MAE 잔차 절댓값의 평균 낮음 x=0x = 0에서 꺾임 이상치가 많은 데이터
RMSE MSE\sqrt{\text{MSE}} 높음 매끄러움 사람이 읽는 평가 지표
Huber 작은 잔차는 제곱, 큰 잔차는 절댓값 중간 매끄러움 이상치 대응 회귀

같은 예측에 세 지표를 재보면 MSE 0.0025, MAE 0.0405, RMSE 0.0504가 나온다. RMSE가 MAE보다 큰 이유는 MSE가 큰 잔차에 가중 벌점을 주기 때문이다. 잔차가 전부 같은 크기면 두 값이 일치하고, 잔차의 편차가 클수록 격차가 벌어진다. 그래서 RMSE와 MAE의 격차 자체가 유독 크게 빗나간 예측이 섞여 있는지를 알려주는 신호가 된다.

고민된다면 MSE로 시작하면 된다. 이상치가 많은 데이터라면 MAE나 Huber로 바꿔 성능을 비교해본다.

마치며

비용 함수는 모델의 성적표다. 잔차라는 낱개 점수들을 하나의 총점으로 묶고, 학습은 그 총점을 낮추는 과정이 된다.

MSE가 기본값 자리를 차지한 이유는 세 가지가 겹쳤기 때문이다. 큰 오차에 더 무거운 벌점을 매기고, 어디서나 미분되며, 선형 모델에서는 최솟값이 하나뿐이다. 뒤의 두 가지는 전부 다음 단계를 위한 성질이다. 미분이 되니 기울기를 따라갈 수 있고, 볼록하니 어디서 출발해도 도착지가 같다. 비용 함수를 정한다는 건 무엇을 줄일지 고르는 동시에, 그걸 어떻게 줄일 수 있는지까지 결정하는 일이다.

함께 보면 좋은 글

참고자료

Thank You for Visiting My Blog, Have a Good Day 😆