머신러닝에서 가장 먼저 배우는 모델 중 하나가 선형회귀입니다. 선형회귀는 단순히 직선을 하나 긋는 방법처럼 보이지만, 그 안에는 다음과 같은 중요한 개념이 모두 들어 있습니다.
예측값과 실제값의 차이
잔차와 제곱오차
SSE, SST, SSR
R²와 기준 모델
최소제곱법
목적함수와 gradient
경사하강법
이번 글에서는 “왜 평균이 회귀의 기준이 되는가?”라는 질문에서 출발해 선형회귀가 오차를 어떻게 줄이는지까지 한 번에 연결해 보겠습니다.
1. 선형회귀란 무엇인가?
입력 x와 정답 y의 관계를 직선으로 설명한다고 해보겠습니다.
가장 간단한 단순 선형회귀 모델은 다음과 같습니다.
y_hat = w x + b
여기서 각각의 의미는 다음과 같습니다.
x = 입력 변수
y = 실제 정답
y_hat = 모델의 예측값
w = 기울기
b = 절편
기울기 w는 x가 1만큼 증가할 때 예측값이 얼마나 변하는지를 나타냅니다. 절편 b는 x가 0일 때의 예측값입니다.
예를 들어
y_hat = 2x + 1
이라면 x가 1 증가할 때 예측값은 2만큼 증가합니다.
x = 0 -> y_hat = 1
x = 1 -> y_hat = 3
x = 2 -> y_hat = 5
선형회귀의 목표는 데이터에 가장 잘 맞는 w와 b를 찾는 것입니다.
좋은 w, b 찾기
-> 예측값 y_hat과 실제값 y의 차이를 작게 만들기

2. 예측 오차와 잔차
각 데이터의 예측 오차를 잔차, residual이라고 합니다.
e_i = y_i - y_hat_i
예를 들어 실제값이 10이고 예측값이 8이라면
e = 10 - 8 = 2
입니다.
예측값이 실제값보다 크면 잔차는 음수가 됩니다.
실제값 y = 10
예측값 y_hat = 12
잔차 e = 10 - 12 = -2
잔차의 부호는 모델이 어느 방향으로 틀렸는지를 알려 줍니다.
e_i > 0:
모델이 실제값보다 작게 예측
e_i < 0:
모델이 실제값보다 크게 예측
그런데 잔차를 그냥 모두 더하면 문제가 생깁니다. 양의 잔차와 음의 잔차가 서로 상쇄될 수 있기 때문입니다.
잔차 = [2, -2]
잔차의 합 = 2 + (-2) = 0
오차가 분명히 존재하지만 합만 보면 완벽하게 맞춘 것처럼 보입니다. 그래서 선형회귀에서는 잔차를 제곱한 뒤 더합니다.
3. SSE: 제곱오차의 합
SSE는 Sum of Squared Errors의 약자입니다.
SSE = sum_i (y_i - y_hat_i)^2
즉, 실제값과 예측값의 차이를 제곱해 모두 더한 값입니다.
데이터가 세 개라면
SSE
= (y_1 - y_hat_1)^2
+ (y_2 - y_hat_2)^2
+ (y_3 - y_hat_3)^2
입니다.
SSE가 작을수록 모델의 예측이 실제값에 가깝습니다.
간단한 예시
실제값이
y = [10, 20, 30]
이고 모델이
y_hat = [12, 20, 28]
이라고 합시다.
각 잔차는
e = y - y_hat
= [10-12, 20-20, 30-28]
= [-2, 0, 2]
입니다.
따라서 SSE는
SSE
= (-2)^2 + 0^2 + 2^2
= 4 + 0 + 4
= 8
입니다.
SSE는 회귀모델이 훈련 데이터에서 얼마나 틀렸는지를 나타내는 가장 기본적인 목적함수입니다.
4. 왜 오차를 제곱할까?
제곱오차를 사용하는 이유는 여러 가지가 있습니다.
1. 양수와 음수의 상쇄 방지
잔차 합:
2 + (-2) = 0
제곱잔차 합:
2^2 + (-2)^2 = 8
2. 큰 오차를 더 강하게 벌점
오차 1 -> 제곱오차 1
오차 2 -> 제곱오차 4
오차 5 -> 제곱오차 25
큰 오차가 있는 데이터에 더 큰 패널티를 줍니다.
3. 미분하기 쉬움
절댓값은 0에서 미분이 매끄럽지 않지만, 제곱함수는 모든 지점에서 미분할 수 있습니다.
(y - y_hat)^2
은 경사하강법으로 최적화하기 좋습니다.
4. 통계적 의미
오차가 평균 0인 Gaussian noise를 따른다고 가정하면, 제곱오차를 최소화하는 것은 likelihood를 최대화하는 것과 연결됩니다.
Gaussian noise 가정
-> 최대우도추정
-> 제곱오차 최소화
다만 제곱오차는 이상치에 민감합니다. 아주 큰 오차 하나가 전체 SSE를 크게 키울 수 있습니다.
5. 아무 정보가 없을 때의 기준 모델
이제 중요한 질문을 생각해 보겠습니다.
x 정보를 전혀 사용하지 않고, 모든 데이터에 하나의 숫자만 예측해야 한다면 어떤 숫자를 선택해야 할까?
모델이 모든 데이터에 같은 값 c를 예측한다고 합시다.
y_hat_i = c
그러면 목적함수는
SSE(c) = sum_i (y_i - c)^2
입니다.
실제값이
y = [10, 20, 30]
이라면
SSE(c)
= (10-c)^2 + (20-c)^2 + (30-c)^2
입니다.
우리는 이 SSE(c)를 가장 작게 만드는 c를 찾고 싶습니다.
6. 평균이 기준인 이유
SSE(c)를 c에 대해 미분합니다.
dSSE(c)/dc
= -2(10-c) - 2(20-c) - 2(30-c)
정리하면
dSSE(c)/dc
= -2(60 - 3c)
최솟값에서는 미분값이 0이므로
-2(60 - 3c) = 0
60 - 3c = 0
c = 20
이 됩니다.
그런데 실제값의 평균은
(10 + 20 + 30) / 3 = 20
입니다.
따라서 제곱오차를 기준으로 모든 데이터에 하나의 숫자만 예측해야 한다면, 가장 좋은 숫자는 평균입니다.
일반적으로도 같습니다.
SSE(c) = sum_(i=1)^n (y_i - c)^2
이를 미분하면
dSSE(c)/dc
= -2 sum_i (y_i - c)
최솟값에서 0으로 놓으면
sum_i (y_i - c) = 0
sum_i y_i - n c = 0
따라서
c = (1/n) sum_i y_i
= y_bar
입니다.
즉, 평균은 다음과 같은 의미를 가집니다.
x 정보를 전혀 사용하지 않고 하나의 숫자만 예측할 때, 제곱오차를 가장 작게 만드는 기준 예측값

이 결과는 선형회귀의 중요한 기준이 됩니다.
기준 모델:
모든 데이터에 평균 y_bar 예측
비교 모델:
x를 사용해 y_hat = w x + b 예측
회귀모델은 최소한 평균만 예측하는 기준 모델보다 잘해야 의미가 있습니다.
7. 평균은 모든 오차 기준의 최선은 아니다
평균이 항상 기준이 되는 것은 아닙니다. 어떤 오차함수를 사용하느냐에 따라 최적의 대표값이 달라집니다.
제곱오차
sum_i (y_i - c)^2
-> 평균
절대오차
sum_i |y_i - c|
-> 중앙값
절대오차에서는 중앙값이 가장 좋은 대표값이 됩니다.
예를 들어
y = [1, 2, 100]
일 때 평균은 약 34.33이지만 중앙값은 2입니다. 이상치 100의 영향을 덜 받고 싶다면 절대오차와 중앙값이 더 적합할 수 있습니다.
정리하면
제곱오차 최소화 -> 평균
절대오차 최소화 -> 중앙값
선형회귀와 R²에서 평균이 등장하는 이유는 제곱오차를 기준으로 삼기 때문입니다.
8. SST: 전체 변동량
이제 회귀모델이 설명한 변동과 설명하지 못한 변동을 나누어 보겠습니다.
실제값 y_i가 평균 y_bar에서 얼마나 떨어져 있는지를 측정하는 값이 전체제곱합, SST입니다.
SST는 Total Sum of Squares의 약자입니다.
SST = sum_i (y_i - y_bar)^2
예를 들어
y = [10, 20, 30]
y_bar = 20
이면
SST
= (10-20)^2 + (20-20)^2 + (30-20)^2
= 100 + 0 + 100
= 200
입니다.
SST는 x를 사용하기 전, y 데이터 자체가 가진 전체 흩어짐의 크기입니다.
분산과 SST
표본분산은
s^2 = 1/(n-1) sum_i (y_i - y_bar)^2
이므로
SST = (n-1) s^2
입니다.
따라서 SST는 분산의 분자 부분이라고 생각할 수 있습니다.
SST가 큼:
y 값들이 평균에서 많이 흩어져 있음
SST가 작음:
y 값들이 평균 주변에 모여 있음
9. 회귀모델이 설명하는 변동
회귀모델의 예측값을
y_hat_i = w x_i + b
라고 합시다.
실제값 y_i가 평균에서 떨어진 정도는 두 부분으로 나눌 수 있습니다.
y_i - y_bar
= (y_hat_i - y_bar) + (y_i - y_hat_i)
각 항의 의미는 다음과 같습니다.
y_i - y_bar:
실제값이 평균에서 떨어진 전체 변화
y_hat_i - y_bar:
회귀모델이 평균에서 움직여 준 변화
y_i - y_hat_i:
회귀모델이 설명하지 못하고 남은 잔차
그림으로 보면 다음과 같습니다.
평균 y_bar
|
| 모델이 설명한 변동
|
예측값 y_hat
|
| 모델이 설명하지 못한 잔차
|
실제값 y
모델이 모든 예측을 평균으로만 하면
y_hat_i = y_bar
이므로 설명한 변동은 0입니다.
y_hat_i - y_bar = 0
반대로 회귀선이 x에 따른 y의 패턴을 잘 잡으면 예측값이 평균에서 의미 있게 움직입니다.
10. SSR: 모델이 설명한 변동
SSR은 Regression Sum of Squares 또는 Explained Sum of Squares라고 부릅니다.
SSR = sum_i (y_hat_i - y_bar)^2
SSR은 회귀모델의 예측값이 평균 예측에서 얼마나 벗어났는지를 측정합니다.
SSR가 큼:
모델이 y의 변화를 많이 설명
SSR가 작음:
모델이 평균 예측과 크게 다르지 않음
주의할 점은 예측값이 평균에서 멀다고 무조건 좋은 것은 아니라는 점입니다. 예측값이 실제 패턴과 함께 움직이고 잔차도 작아야 좋은 모델입니다. 그래서 SSR과 SSE를 함께 봐야 합니다.
11. SSE: 모델이 설명하지 못한 변동
앞에서 정의한 SSE는 다시 다음과 같습니다.
SSE = sum_i (y_i - y_hat_i)^2
이번에는 의미를 “모델이 설명하지 못한 변동”으로 볼 수 있습니다.
SSE가 작음:
실제값과 예측값이 가까움
SSE가 큼:
회귀선에서 실제 데이터가 많이 벗어남
SSE는 훈련 과정에서 직접 최소화하는 값이고, SSR은 모델이 평균 기준에서 얼마나 설명력을 만들어 냈는지 보여 주는 값입니다.
12. SST = SSR + SSE
다음 식에서 출발합니다.
y_i - y_bar
= (y_hat_i - y_bar) + (y_i - y_hat_i)
양변을 제곱하면
(y_i - y_bar)^2
= (y_hat_i - y_bar)^2
+ (y_i - y_hat_i)^2
+ 2(y_hat_i - y_bar)(y_i - y_hat_i)
모든 데이터에 대해 더하면
sum_i (y_i - y_bar)^2
= sum_i (y_hat_i - y_bar)^2
+ sum_i (y_i - y_hat_i)^2
+ 2 sum_i (y_hat_i - y_bar)(y_i - y_hat_i)
최소제곱법으로 절편 b를 포함한 회귀선을 구하면 마지막 교차항이 0이 됩니다.
sum_i (y_hat_i - y_bar)(y_i - y_hat_i) = 0
따라서
SST = SSR + SSE
가 됩니다.
각 항을 다시 정리하면
SST = sum_i (y_i - y_bar)^2
= y의 전체 변동량
SSR = sum_i (y_hat_i - y_bar)^2
= 모델이 설명한 변동량
SSE = sum_i (y_i - y_hat_i)^2
= 모델이 설명하지 못한 변동량

13. OLS 예시로 분해 확인하기
정확한 SST = SSR + SSE를 숫자로 확인해 보겠습니다.
입력과 실제값을 다음처럼 둡니다.
x = [1, 2, 3]
y = [1, 3, 8]
실제값의 평균은
y_bar = (1 + 3 + 8) / 3 = 4
최소제곱 회귀선을 계산하면
y_hat = 3.5x - 3
입니다.
따라서 예측값은
y_hat = [0.5, 4, 7.5]
입니다.
SST
SST
= (1-4)^2 + (3-4)^2 + (8-4)^2
= 9 + 1 + 16
= 26
SSR
SSR
= (0.5-4)^2 + (4-4)^2 + (7.5-4)^2
= 12.25 + 0 + 12.25
= 24.5
SSE
SSE
= (1-0.5)^2 + (3-4)^2 + (8-7.5)^2
= 0.25 + 1 + 0.25
= 1.5
확인해 보면
SSR + SSE = 24.5 + 1.5 = 26
SST = 26
이므로
SST = SSR + SSE
가 정확히 성립합니다.
14. R²: 평균 기준보다 얼마나 좋아졌는가?
R²는 결정계수, coefficient of determination이라고 합니다.
R²는 회귀모델이 평균만 예측하는 기준 모델보다 얼마나 잘했는지를 나타냅니다.
기준 모델의 오차는 SST입니다.
기준 모델:
모든 데이터에 y_bar 예측
기준 모델의 SSE:
sum_i (y_i - y_bar)^2 = SST
회귀모델의 오차는 SSE입니다.
회귀모델:
x를 사용해 y_hat_i 예측
회귀모델의 SSE:
sum_i (y_i - y_hat_i)^2
따라서 R²는 다음과 같습니다.
R^2 = 1 - SSE/SST
SST = SSR + SSE이므로 다음과 같이 쓸 수도 있습니다.
R^2 = SSR/SST
두 식은 같은 의미입니다.
R^2
= 1 - 모델이 남긴 오차 / 평균 기준의 전체 오차
= 모델이 설명한 변동 / 전체 변동
숫자 예시
SST = 100
SSE = 20
이라면
R^2 = 1 - 20/100
= 0.8
입니다.
이는 다음과 같이 해석할 수 있습니다.
평균만 사용했을 때보다 회귀모델이 y의 변동을 약 80% 더 설명했다.
또는
y가 평균에서 흩어진 전체 변동 중 약 80%가 회귀모델의 예측으로 설명된다.
15. R²의 범위와 주의점
훈련 데이터에서 절편을 포함한 최소제곱 선형회귀를 사용하면 보통
0 <= R^2 <= 1
의 형태가 됩니다.
하지만 다음 상황에서는 R²가 음수가 될 수 있습니다.
절편을 제외한 회귀
테스트 데이터 평가
모델이 평균 기준보다 못함
일반적인 비선형 모델
R²가 음수라는 것은 모델의 SSE가 평균만 예측하는 기준 모델의 SST보다 크다는 뜻입니다.
SSE > SST
-> 1 - SSE/SST < 0
R²가 높다고 항상 좋은 모델일까?
그렇지는 않습니다.
R²는 인과관계를 말하지 않음
R²는 미래 성능을 보장하지 않음
R²는 이상치에 영향을 받음
R²가 높아도 과적합일 수 있음
R²는 절대적인 오차 크기를 알려 주지 않음
예를 들어 정답의 단위가 크게 바뀌면 SSE와 SST는 함께 변하지만, R²는 같은 값을 유지할 수 있습니다. 따라서 R²와 함께 RMSE, MAE, 검증 성능을 같이 보는 것이 좋습니다.
16. MSE와 RMSE
SSE는 데이터 개수가 많아지면 자연스럽게 커집니다. 그래서 데이터 개수로 나눈 평균제곱오차, MSE를 사용합니다.
MSE = SSE / n
= (1/n) sum_i (y_i - y_hat_i)^2
MSE는 평균적인 제곱오차입니다.
RMSE는 MSE에 제곱근을 취합니다.
RMSE = sqrt(MSE)
RMSE의 단위는 y와 같습니다.
y의 단위 = 만 원
MSE의 단위 = 만 원^2
RMSE의 단위 = 만 원
세 지표의 역할
SSE:
전체 데이터에서 누적된 제곱오차
MSE:
데이터 하나당 평균 제곱오차
RMSE:
y의 단위로 환산한 평균적인 오차 크기
R^2:
평균 기준에 비해 변동을 얼마나 설명했는지
17. 선형회귀의 목적함수
선형회귀에서는 보통 다음 목적함수를 최소화합니다.
J(w,b)
= sum_i (y_i - (w x_i + b))^2
또는 데이터 개수로 나눈 MSE를 사용합니다.
J(w,b)
= (1/n) sum_i (y_i - (w x_i + b))^2
SSE와 MSE는 상수배 관계이므로 최솟값을 만드는 w와 b의 위치는 같습니다.
argmin SSE
= argmin MSE
차이는 gradient의 크기입니다.
SSE:
gradient에 n이 포함된 크기
MSE:
gradient가 1/n만큼 평균화됨
실제 딥러닝 코드에서는 MSE를 평균으로 계산하는 경우가 많습니다. 샘플 수와 배치 크기에 따라 손실 규모가 크게 달라지는 것을 줄일 수 있기 때문입니다.
18. 행렬로 표현하는 선형회귀
여러 입력 변수가 있는 다중 선형회귀는 행렬로 간단히 쓸 수 있습니다.
y_hat = X beta
절편까지 포함하려면 X의 첫 번째 열을 모두 1로 둡니다.
X =
[1 x_11 x_12 ... x_1d
1 x_21 x_22 ... x_2d
...
1 x_n1 x_n2 ... x_nd]
파라미터 벡터는
beta = [b, w_1, w_2, ..., w_d]^T
입니다.
목적함수는
J(beta) = ||y - X beta||_2^2
로 쓸 수 있습니다.
이 식은 선형대수에서 배운 벡터 놈과 연결됩니다.
잔차 벡터 = y - X beta
SSE = ||y - X beta||_2^2
19. 정규방정식과 최소제곱해
행렬식 목적함수를 beta로 미분해 0으로 놓으면 정규방정식이 나옵니다.
X^T X beta = X^T y
X^T X가 가역이라면
beta_hat = (X^T X)^(-1) X^T y
입니다.
이것을 정규방정식 해 또는 OLS( Ordinary Least Squares ) 해라고 합니다.
하지만 실제 계산에서는 역행렬을 직접 계산하는 방식이 항상 좋은 것은 아닙니다.
X^T X가 거의 singular할 수 있음
조건수가 커질 수 있음
역행렬 계산 비용이 큼
수치 오차가 커질 수 있음
실전에서는 QR 분해, SVD, 수치 선형대수 라이브러리를 사용해 더 안정적으로 계산하는 경우가 많습니다.
20. 경사하강법이 필요한 이유
정규방정식은 선형회귀의 최적해를 한 번에 계산할 수 있는 좋은 방법입니다. 그런데 데이터와 특성 수가 매우 커지면 X^T X를 만들고 역행렬을 계산하는 비용이 부담이 될 수 있습니다.
이때 경사하강법을 사용할 수 있습니다.
현재 beta에서 gradient 계산
-> 손실이 줄어드는 방향으로 beta 이동
-> 반복
경사하강법은 역행렬을 직접 계산하지 않고도 최적해에 가까워질 수 있습니다.
21. 선형회귀의 gradient 유도
단순 선형회귀의 목적함수를 다음처럼 두겠습니다.
J(w,b) = sum_i (y_i - (w x_i + b))^2
예측값은
y_hat_i = w x_i + b
입니다.
잔차를
e_i = y_i - y_hat_i
라고 하면
J(w,b) = sum_i e_i^2
입니다.
w에 대한 미분
연쇄법칙을 사용합니다.
dJ/dw
= sum_i 2 e_i * de_i/dw
잔차는
e_i = y_i - (w x_i + b)
이므로
de_i/dw = -x_i
입니다.
따라서
dJ/dw
= -2 sum_i x_i e_i
입니다.
잔차 대신 예측 오차 y_hat_i - y_i를 사용하면
dJ/dw
= 2 sum_i x_i (y_hat_i - y_i)
로 쓸 수 있습니다.
b에 대한 미분
de_i/db = -1
이므로
dJ/db
= -2 sum_i e_i
= 2 sum_i (y_hat_i - y_i)
입니다.
최종 gradient는
gradient_w = 2 sum_i x_i (y_hat_i - y_i)
gradient_b = 2 sum_i (y_hat_i - y_i)
입니다.
22. 경사하강법 업데이트
gradient의 음의 방향으로 이동합니다.
w <- w - eta * gradient_w
b <- b - eta * gradient_b
식을 대입하면
w <- w - eta * 2 sum_i x_i (y_hat_i - y_i)
b <- b - eta * 2 sum_i (y_hat_i - y_i)
입니다.
MSE를 사용하면 1/n이 추가됩니다.
gradient_w
= (2/n) sum_i x_i (y_hat_i - y_i)
gradient_b
= (2/n) sum_i (y_hat_i - y_i)
SSE와 MSE의 gradient 차이는 상수배이므로 학습률을 조절하면 같은 방향으로 학습할 수 있습니다.
23. 경사하강법의 직관
경사하강법은 산에서 가장 낮은 곳을 찾는 과정과 비슷합니다.
현재 위치에서 주변의 경사 확인
-> 아래쪽 방향 선택
-> 한 걸음 이동
-> 새로운 위치에서 다시 경사 확인
선형회귀에서는 w와 b가 좌표축이 됩니다.
가로축 = w
세로축 = b
높이 = SSE(w,b)
SSE는 w와 b에 대한 아래로 볼록한 곡면을 만들기 때문에, 적절한 학습률을 사용하면 최솟값으로 이동할 수 있습니다.

등고선이 길고 좁으면 한 방향으로는 가파르고 다른 방향으로는 완만합니다. 이때 경사하강법 경로가 지그재그로 움직일 수 있습니다. 입력 특성의 스케일을 맞추면 이런 문제를 줄일 수 있습니다.
24. 1차원 함수로 보는 경사하강법
경사하강법을 가장 쉽게 이해하는 방법은 아주 간단한 함수 하나를 직접 따라가 보는 것입니다.
다음과 같은 함수를 생각해 보겠습니다.
f(x) = (x - 2)^2
이 함수는 꼭짓점이 x = 2인 아래로 볼록한 포물선입니다.
최소점: x = 2
최솟값: f(2) = 0
x가 2에서 멀어질수록 함수값은 커집니다.
x = 0 -> f(0) = 4
x = 1 -> f(1) = 1
x = 2 -> f(2) = 0
x = 3 -> f(3) = 1
x = 5 -> f(5) = 9

미분하면 어느 방향으로 가야 하는가?
함수를 미분하면
f'(x) = 2(x - 2)
입니다.
gradient, 1차원에서는 derivative는 함수가 증가하는 방향과 크기를 알려 줍니다.
x > 2:
f'(x) > 0
오른쪽으로 갈수록 함수가 증가하므로 왼쪽으로 이동해야 함
x < 2:
f'(x) < 0
왼쪽으로 갈수록 함수가 증가하므로 오른쪽으로 이동해야 함
x = 2:
f'(x) = 0
더 이상 이동할 필요가 없음
따라서 gradient의 반대 방향으로 이동하면 항상 최소점 방향으로 움직이게 됩니다.
업데이트 식
경사하강법의 업데이트 식은
x_(t+1) = x_t - eta f'(x_t)
입니다.
f'(x) = 2(x-2)를 대입하면
x_(t+1)
= x_t - eta * 2(x_t - 2)
가 됩니다.
여기서 eta는 학습률입니다. 이번에는
x_0 = 5
eta = 0.25
로 시작해 보겠습니다.
실제 반복 계산
첫 번째 step에서
f'(5) = 2(5-2) = 6
x_1 = 5 - 0.25 * 6
= 3.5
입니다.
두 번째 step에서는
f'(3.5) = 2(3.5-2) = 3
x_2 = 3.5 - 0.25 * 3
= 2.75
입니다.
계속 반복하면
x_0 = 5
x_1 = 3.5
x_2 = 2.75
x_3 = 2.375
x_4 = 2.1875
처럼 최소점 2에 가까워집니다.
함수값도 함께 계산해 보면
f(x_0) = f(5) = 9
f(x_1) = f(3.5) = 2.25
f(x_2) = f(2.75) = 0.5625
f(x_3) = f(2.375) = 0.140625
f(x_4) = f(2.1875) = 0.03515625
입니다.
x는 2에 가까워짐
f(x)는 0에 가까워짐

왜 최소점에 가까워지는가?
이 함수에서는 업데이트 식을 직접 정리할 수 있습니다.
x_(t+1)
= x_t - 2eta(x_t - 2)
= (1 - 2eta)x_t + 4eta
최소점 2에서의 차이를 보면 더 간단합니다.
x_(t+1) - 2
= (1 - 2eta)(x_t - 2)
따라서
|1 - 2eta| < 1
이면 차이가 반복해서 작아지고 x_t는 2로 수렴합니다.
정리하면 안정적인 학습률 조건은
0 < eta < 1
입니다.
학습률에 따른 차이
eta가 너무 작음:
x가 2에 아주 천천히 접근
eta = 0.25:
x가 안정적으로 2에 접근
eta = 0.75:
최소점 주변을 번갈아 움직이며 접근
eta = 1:
반대편으로 같은 거리를 이동해 수렴하지 않음
eta > 1:
점점 최소점에서 멀어져 발산
이 간단한 예시는 선형회귀의 SSE에도 그대로 연결됩니다. 선형회귀에서는 x 하나 대신 w와 b가 있고, f(x) 하나 대신 SSE(w,b)라는 곡면을 최소화합니다.
1차원 예시:
f(x) = (x-2)^2
최소점 x = 2
선형회귀:
SSE(w,b) = sum_i (y_i - (w x_i + b))^2
최소점 (w*, b*)
즉, 선형회귀의 경사하강법도 같은 원리입니다.
현재 파라미터 위치 확인
-> SSE의 gradient 계산
-> gradient 반대 방향으로 이동
-> SSE가 줄었는지 확인
-> 반복
25. 숫자로 보는 경사하강법
다음 데이터로 한 번 업데이트해 보겠습니다.
x = [1, 2, 3]
y = [1, 3, 8]
초기 파라미터를
w = 0
b = 0
으로 두면 예측값은
y_hat = [0, 0, 0]
입니다.
초기 SSE
SSE
= (1-0)^2 + (3-0)^2 + (8-0)^2
= 1 + 9 + 64
= 74
초기 gradient
예측값에서 실제값을 뺀 값은
y_hat - y = [-1, -3, -8]
입니다.
w에 대한 gradient는
gradient_w
= 2[1(-1) + 2(-3) + 3(-8)]
= 2[-1 - 6 - 24]
= -62
b에 대한 gradient는
gradient_b
= 2[-1 - 3 - 8]
= -24
입니다.
학습률을 eta = 0.01로 하면
w_new = 0 - 0.01(-62) = 0.62
b_new = 0 - 0.01(-24) = 0.24
입니다.
새로운 예측값은
y_hat_new
= 0.62x + 0.24
= [0.86, 1.48, 2.10]
입니다.
새 SSE는
SSE_new
= (1-0.86)^2 + (3-1.48)^2 + (8-2.10)^2
≈ 37.14
입니다.
한 번의 업데이트만으로도
기존 SSE = 74
새로운 SSE ≈ 37.14
로 줄었습니다.
다음 step에서도 같은 과정을 반복합니다.
gradient 계산
-> w, b 업데이트
-> 예측
-> SSE 확인
26. 학습률이 너무 크거나 작으면?
학습률 eta는 한 번에 움직이는 크기입니다.
학습률이 너무 작음
업데이트 폭이 너무 작음
손실이 천천히 감소
많은 반복이 필요
학습률이 적절함
손실이 안정적으로 감소
최솟값 주변으로 접근
학습률이 너무 큼
최솟값을 지나침
손실이 크게 진동
SSE가 발산
파라미터가 inf 또는 NaN이 됨

실전에서는 처음부터 하나의 학습률을 완벽하게 맞히기보다, 여러 후보를 비교하며 손실 곡선을 확인합니다.
27. Batch Gradient Descent와 SGD
전체 데이터의 SSE gradient를 매번 계산하면 Batch Gradient Descent입니다.
모든 훈련 샘플 사용
-> 전체 gradient 계산
-> 한 번 업데이트
데이터가 아주 많으면 한 번의 업데이트가 느릴 수 있습니다.
SGD는 한 샘플 또는 작은 mini-batch만 사용해 gradient를 추정합니다.
샘플 일부 선택
-> noisy gradient 계산
-> 자주 업데이트
Batch Gradient Descent
장점:
gradient가 안정적
손실 곡선이 비교적 부드러움
작은 데이터셋에 적합
단점:
대규모 데이터에서 한 step이 느림
메모리 비용이 큼
SGD 또는 Mini-batch SGD
장점:
대규모 데이터에 적합
업데이트가 빠름
gradient noise가 탐색에 도움을 줄 수 있음
단점:
손실 곡선이 흔들림
학습률과 batch size에 민감
최솟값 주변에서 계속 움직일 수 있음
딥러닝에서는 보통 Mini-batch SGD를 사용합니다.
28. 선형회귀에서의 정규화
특성이 많거나 서로 강하게 상관되어 있으면 모델이 큰 가중치를 사용해 훈련 데이터에 맞을 수 있습니다. 이때 정규화를 추가할 수 있습니다.
Ridge 회귀
J(beta)
= ||y - X beta||_2^2
+ lambda ||beta||_2^2
L2 패널티는 큰 가중치를 줄입니다.
Lasso 회귀
J(beta)
= ||y - X beta||_2^2
+ lambda ||beta||_1
L1 패널티는 일부 가중치를 정확히 0으로 만들 수 있어 feature selection 효과가 있습니다.
절편에는 정규화를 적용하지 않는 경우가 많습니다.
가중치 w_1, ..., w_d:
정규화 적용
절편 b:
정규화에서 제외하는 경우가 많음
29. 잔차를 확인하는 이유
SSE가 작다는 것만으로 모델이 적절하다고 단정할 수 없습니다. 잔차를 그래프로 확인하면 모델이 놓친 구조를 발견할 수 있습니다.
좋은 선형회귀의 잔차는 대체로 다음 특성을 기대합니다.
잔차의 평균이 0에 가까움
x에 따라 특정한 패턴이 없음
잔차의 분산이 지나치게 변하지 않음
잔차끼리 강한 상관이 없음
잔차에 곡선 패턴이 있음
선형모델이 실제 비선형 관계를 놓쳤을 가능성
x가 커질수록 잔차의 폭이 커짐
이분산성 가능성
로그 변환 또는 다른 모델 검토
일부 점만 잔차가 매우 큼
이상치 또는 데이터 입력 오류 확인

30. 평균 기준, 회귀선, R²를 한 번에 정리
선형회귀에서 평균은 매우 중요한 기준선입니다.
평균 모델:
y_hat_i = y_bar
SSE_baseline = SST
회귀모델은 x를 사용해 평균보다 정교한 예측을 만듭니다.
회귀 모델:
y_hat_i = w x_i + b
SSE_model = SSE
두 모델을 비교하면
평균 기준의 전체 오차 = SST
회귀모델이 남긴 오차 = SSE
모델이 줄인 오차 = SST - SSE = SSR
따라서
R^2 = (SST - SSE) / SST
= SSR / SST
= 1 - SSE/SST
입니다.
이 식을 말로 바꾸면 다음과 같습니다.
R²는 x를 사용한 회귀모델이 평균만 예측하는 기준 모델에 비해 y의 변동을 얼마나 더 설명하는지를 나타내는 비율이다.
31. 선형회귀 학습 전체 흐름
선형회귀의 전체 과정을 정리하면 다음과 같습니다.
1. 입력 x와 정답 y를 준비한다.
2. y_hat = w x + b로 예측한다.
3. 잔차 y - y_hat을 계산한다.
4. SSE 또는 MSE를 계산한다.
5. w와 b에 대한 gradient를 계산한다.
6. w와 b를 gradient의 반대 방향으로 업데이트한다.
7. 손실이 줄어드는지 확인한다.
8. 검증 데이터에서 RMSE와 R²를 확인한다.
9. 잔차 그래프로 놓친 패턴을 확인한다.
파라미터를 직접 계산하는 정규방정식과 반복적으로 업데이트하는 경사하강법은 서로 다른 방법이지만 목표는 같습니다.
정규방정식:
최적해를 수식으로 직접 계산
경사하강법:
gradient를 따라 반복적으로 최적해에 접근
32. 파이썬으로 구현하는 선형회귀와 경사하강법
다음 예시는 외부 머신러닝 라이브러리 없이 NumPy만 사용해 선형회귀를 학습하는 코드입니다.
import numpy as np
# 입력과 정답
x = np.array([1.0, 2.0, 3.0])
y = np.array([1.0, 3.0, 8.0])
# 파라미터 초기화
w = 0.0
b = 0.0
learning_rate = 0.01
epochs = 1000
for epoch in range(epochs):
# 예측
y_hat = w * x + b
# 잔차와 손실
error = y_hat - y
mse = np.mean(error ** 2)
# MSE gradient
grad_w = 2 * np.mean(x * error)
grad_b = 2 * np.mean(error)
# 파라미터 업데이트
w -= learning_rate * grad_w
b -= learning_rate * grad_b
print("w =", w)
print("b =", b)
# 최종 예측
y_hat = w * x + b
sse = np.sum((y - y_hat) ** 2)
sst = np.sum((y - np.mean(y)) ** 2)
r2 = 1 - sse / sst
print("SSE =", sse)
print("R^2 =", r2)
코드에서 중요한 부분은 다음입니다.
error = y_hat - y
grad_w = 2 * mean(x * error)
grad_b = 2 * mean(error)
w -= learning_rate * grad_w
b -= learning_rate * grad_b
평균을 사용한 기준 모델의 SSE도 함께 계산할 수 있습니다.
baseline_prediction = np.full_like(y, np.mean(y))
baseline_sse = np.sum((y - baseline_prediction) ** 2)
print("baseline SSE =", baseline_sse)
R²는 회귀모델이 이 기준 모델보다 얼마나 나아졌는지를 계산합니다.
33. 자주 하는 실수
1. SSE와 SSR의 이름을 반대로 기억
SSE:
Error, 남은 오차
SSR:
Regression 또는 Explained, 설명된 변동
문헌에 따라 SSR을 Residual Sum of Squares로 표기하는 경우도 있어 약어만 보지 말고 정의를 확인해야 합니다. 혼동을 피하려면 다음 표현도 함께 기억하면 좋습니다.
Total Sum of Squares = SST
Explained Sum of Squares = SSR 또는 ESS
Residual Sum of Squares = SSE 또는 RSS
2. 평균 기준을 무시
R²는 절대적인 정확도가 아니라 평균 기준과의 비교입니다.
R^2 = 기준 모델보다 얼마나 좋아졌는가
3. 훈련 R²만 확인
훈련 데이터에서 R²가 높아도 새로운 데이터에서 성능이 낮을 수 있습니다. 검증 세트와 테스트 세트를 분리해야 합니다.
4. feature scaling을 하지 않음
특성마다 크기가 크게 다르면 SSE 곡면의 조건수가 커지고 gradient descent가 느려질 수 있습니다.
표준화 예시:
x_scaled = (x - mean(x)) / std(x)
5. 이상치를 그대로 둠
제곱오차는 큰 오차를 강하게 벌점 줍니다. 이상치가 중요한 관측인지 입력 오류인지 확인해야 합니다.
34. 이번 글의 핵심 요약
선형회귀:
y_hat = w x + b
잔차:
e_i = y_i - y_hat_i
SSE:
sum_i (y_i - y_hat_i)^2
평균 기준:
제곱오차를 최소화하는 상수 예측값은 평균
SST:
sum_i (y_i - y_bar)^2
전체 변동량
SSR:
sum_i (y_hat_i - y_bar)^2
모델이 설명한 변동량
SSE:
sum_i (y_i - y_hat_i)^2
모델이 설명하지 못한 변동량
분해:
SST = SSR + SSE
결정계수:
R^2 = 1 - SSE/SST = SSR/SST
경사하강법:
gradient를 계산하고 그 반대 방향으로 w와 b를 반복 업데이트
선형회귀는 단순히 직선을 그리는 모델이 아닙니다. 평균을 기준으로 전체 변동을 정의하고, 회귀선이 설명한 변동과 남은 오차를 나누며, SSE 또는 MSE를 gradient descent로 줄이는 하나의 완성된 머신러닝 학습 구조입니다.
'ML' 카테고리의 다른 글
| [ML_BASIC] 어떤 Machine Learning Model을 써야 할까? Linear Model부터 Boosting까지 (0) | 2026.09.05 |
|---|---|
| Confusion Matrix를 왜 사용할까? Accuracy의 함정을 숫자 5 분류로 이해하기 (1) | 2026.09.04 |
| 캐글 타이타닉 데이터로 배우는 자주 쓰는 머신러닝 기법 5가지 (0) | 2026.08.30 |