머신러닝 기초 (9) - 선형 모델: 선형 회귀와 로지스틱 회귀
선형 회귀와 로지스틱 회귀를 "특성의 가중합"이라는 하나의 뼈대로 묶어, 계수(coef_) 해석과 시그모이드 결정경계, 규제(Ridge, Lasso, C)를 최소한의 코드로 확인하고 선형 가정의 한계까지 짚는 9편입니다.
머신러닝 기초 시리즈의 9편입니다. 8편의 “회귀 평가: RMSE, R², 잔차”에 이어집니다.
선형 모델이라는 하나의 뼈대
1편에서 선형 회귀와 로지스틱 회귀를 fit/predict로 한 번씩 돌려봤습니다. 그때는 두 모델이 정확히 무엇을 계산하는지는 미뤄 뒀습니다. 이번 편은 그 내부를 엽니다.
두 모델은 이름도 다르고 쓰임(회귀/분류)도 다르지만 같은 뼈대를 공유합니다. 특성마다 가중치를 곱해 전부 더하는 선형 결합입니다. 선형 회귀는 그 합을 곧바로 예측값으로 쓰고, 로지스틱 회귀는 그 합을 확률로 한 번 더 변환합니다. 뼈대가 하나이므로 계수를 읽는 법도, 규제를 거는 법도, 한계도 나란히 이해할 수 있습니다.
선형 회귀: 특성의 가중합
선형 회귀의 예측은 각 특성에 계수를 곱해 더하고 절편을 얹은 값입니다.
1
예측 = w1*x1 + w2*x2 + ... + wn*xn + b
여기서 계수 w가 각 특성이 예측에 기여하는 방향과 크기입니다. 계수가 양수면 그 특성이 커질수록 예측이 커지고, 음수면 반대입니다. 절편 b는 모든 특성이 0일 때의 기준값입니다.
내장 당뇨 데이터로 계수를 직접 꺼내 봅니다. 특성 10개(나이, 성별, BMI, 혈압, 혈청 수치 등)로 1년 뒤 진행 정도를 예측하는 회귀 문제입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
from sklearn.datasets import load_diabetes
from sklearn.linear_model import LinearRegression
d = load_diabetes()
X, y = d.data, d.target # 특성 10개는 이미 표준화되어 있음
model = LinearRegression()
model.fit(X, y) # 계수를 한 번에 계산 (반복 없음)
round(model.intercept_, 2) # 절편 b = 152.13
model.coef_.round(1)
# [ -10. -239.8 519.8 324.4 -792.2 476.7 101. 177.1 751.3 67.6]
# age sex bmi bp s1 s2 s3 s4 s5 s6
bmi의 계수가 519.8로 양수이므로, BMI가 클수록 진행도 예측이 올라간다고 읽습니다. 이 데이터의 특성은 이미 표준화되어 있어(각 열이 같은 스케일로 맞춰져 있음) 계수의 크기를 특성끼리 직접 비교할 수 있고, s1, s5, bmi가 예측에 크게 관여한다는 것도 바로 보입니다.
여기서 계수를 특성 중요도로 읽을 때 흔한 함정이 하나 있습니다.
계수 크기로 “어느 특성이 더 중요한가”를 비교하려면 특성들이 같은 스케일이어야 한다. 원본 단위가 제각각인 데이터에서는 큰 계수가 그저 그 특성의 단위가 작아서일 수 있다. 표준화는 12편에서 다룬다.
한 가지 더. s1은 -792, s2는 +477처럼 서로 상관이 큰 혈청 특성들의 계수가 큰 반대 부호로 튀어 있습니다. 이는 특성 간 상관이 강할 때 계수가 불안정해지는 전형적인 증상이며, 뒤에서 다룰 규제가 이를 눌러 줍니다.
계수는 어떻게 정해지는가
fit이 고른 계수는 예측과 정답의 오차, 즉 MSE를 최소화하는 값입니다(손실 함수는 2편). MSE는 (y − 예측)을 제곱해 평균한 값입니다.
선형 회귀에는 이 최솟값을 반복 없이 한 번에 구하는 공식이 있습니다. 정규방정식이라 부르는 닫힌 해이고, LinearRegression이 위에서 계수를 즉시 내놓은 것도 이 때문입니다. 물론 3편의 경사하강법으로도 같은 답에 도달할 수 있으며, 특성이나 샘플이 아주 많아 닫힌 해 계산이 부담스러울 때는 경사하강 쪽이 실용적입니다.
로지스틱 회귀: 선형 결합을 확률로
분류는 “얼마인가”가 아니라 “어느 쪽인가”를 맞히는 문제입니다(회귀, 분류 구분은 1편). 그런데 선형 결합의 결과는 범위 제한이 없는 실수라 확률로 바로 쓸 수 없습니다. 로지스틱 회귀는 이 값을 시그모이드 함수에 통과시켜 0과 1 사이로 눌러 확률로 만듭니다.
1
2
3
4
5
6
import numpy as np
def sigmoid(z):
return 1 / (1 + np.exp(-z))
sigmoid(np.array([-2.0, 0.0, 2.0])) # [0.119 0.5 0.881]
선형 결합 z = w1*x1 + ... + wn*xn + b가 클수록 확률이 1에, 작을수록 0에 가까워지고, z = 0에서 정확히 0.5입니다. 확률이 0.5를 넘으면 한쪽 라벨, 넘지 못하면 다른 쪽 라벨로 판정합니다. 이 0.5의 경계, 즉 z = 0이 되는 지점이 결정경계이며 선형 결합이 0인 면이므로 언제나 직선(고차원에서는 평면)입니다.
내장 유방암 데이터로 확률을 직접 봅니다. 특성 30개로 악성(0), 양성(1)을 맞히는 이진 분류입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from sklearn.datasets import load_breast_cancer
from sklearn.linear_model import LogisticRegression
bc = load_breast_cancer()
Xc, yc = bc.data, bc.target
bc.target_names # ['malignant' 'benign']. 0=악성, 1=양성
clf = LogisticRegression(max_iter=5000) # 스케일 차가 커 반복 횟수를 늘림
clf.fit(Xc, yc)
clf.classes_ # [0 1]
clf.predict_proba(Xc[:3]).round(3)
# [[1. 0.] 각 행이 [P(악성), P(양성)]. 세 샘플 모두 악성 쪽 확신
# [1. 0.]
# [1. 0.]]
clf.predict(Xc[:3]) # [0 0 0]. 확률이 큰 쪽 라벨
predict_proba는 각 클래스의 확률을, predict는 그중 큰 쪽 라벨을 돌려줍니다. 위 세 샘플은 악성 확률이 거의 1이라 판정이 명확합니다. 경계 부근의 샘플을 보면 확률의 의미가 더 분명해집니다.
1
2
3
4
i = 215
clf.predict_proba(Xc[i:i+1]).round(3) # [[0.487 0.513]]. 결정경계 바로 옆
clf.predict(Xc[i:i+1]) # [1]. 0.513 > 0.5 이므로 양성
yc[i] # 0. 실제는 악성 (경계 부근의 오분류)
확률이 0.5 언저리인 샘플은 모델도 확신이 없다는 뜻이고, 오분류도 이런 경계 부근에서 나옵니다. 판정 기준을 0.5가 아닌 다른 값으로 옮기면 결과가 달라지는데, 이 임계값 조정과 분류 성능 측정은 7편에서 다뤘습니다.
이름은 “회귀”지만 로지스틱 회귀는 분류기다. 회귀라 불리는 이유는 로그 오즈(log(p/(1−p)))를 특성의 선형식으로 회귀하기 때문이다. 그 선형식을 시그모이드로 되돌리면 확률이 된다.
선형 회귀와 달리 로지스틱 회귀는 계수를 한 번에 구하는 닫힌 해가 없어 반복 최적화로 풉니다. 위에서 max_iter를 늘린 것은 그 반복이 수렴하도록 여유를 준 것입니다.
규제: 계수를 억누르기
특성이 많거나 서로 상관이 크면 계수가 과하게 커지며 훈련 데이터에 과대적합하기 쉽습니다(4편). 규제는 손실에 “계수 크기에 대한 벌점”을 더해 계수가 커지는 것을 억눌러 일반화를 돕습니다. 규제의 원리는 6편에서 다뤘고, 여기서는 선형 모델에 어떻게 붙는지만 확인합니다.
회귀 쪽에는 규제를 건 버전이 따로 있습니다. Ridge는 계수 제곱합(L2)을, Lasso는 계수 절댓값합(L1)을 벌점으로 씁니다. 특히 Lasso는 일부 계수를 정확히 0으로 만들어 특성 선택 효과까지 냅니다.
1
2
3
4
from sklearn.linear_model import Lasso
Lasso(alpha=1.0).fit(X, y).coef_.round(1)
# [ 0. -0. 367.7 6.3 0. 0. -0. 0. 307.6 0.] ← 10개 중 7개가 0
alpha가 규제 강도이고, 클수록 벌점이 세져 계수가 더 눌립니다. 두 벌점을 함께 쓰는 ElasticNet도 있습니다.
분류 쪽 LogisticRegression은 기본적으로 규제가 켜져 있고, 강도를 C로 조절합니다. C는 규제 강도의 역수라 값이 작을수록 규제가 강합니다.
1
2
3
4
5
6
for C in [0.01, 1.0, 100.0]:
clf = LogisticRegression(max_iter=5000, C=C).fit(Xc, yc)
print(C, round(np.linalg.norm(clf.coef_), 2), round(clf.score(Xc, yc), 4))
# 0.01 0.28 0.9508 규제 강함: 계수가 작게 유지됨
# 1.0 2.67 0.9578
# 100.0 28.46 0.9772 규제 약함: 계수가 커지고 훈련 정확도↑ (과적합 위험)
C를 키우면 규제가 약해져 계수가 커지고 훈련 정확도가 오르지만, 그 상승분이 새 데이터로 이어지는지는 별개입니다. 적절한 C나 alpha는 교차검증으로 고릅니다(5편).
선형 모델의 강점과 한계
선형 모델의 가장 큰 강점은 해석 가능성입니다. 계수 하나하나가 “이 특성이 예측을 어느 방향으로 얼마나 움직이는가”를 그대로 말해 줍니다. 학습과 예측이 빠르고, 특성 수에 비해 데이터가 적어도 비교적 안정적이며, 규제까지 갖춰져 있어 어떤 문제든 처음 세워 보는 베이스라인으로 알맞습니다.
한계는 이름 그대로 선형 가정입니다. 예측을 특성의 가중합으로만 만들기 때문에, 특성과 타깃의 관계가 곡선이거나 특성들이 서로 맞물려 작동하는(상호작용) 구조는 그대로는 담지 못합니다. 제곱항이나 특성 곱을 직접 만들어 넣어 어느 정도 우회할 수 있지만, 어떤 항이 필요한지 사람이 일일이 지정해야 한다는 부담이 남습니다.
다음 편의 결정트리는 여기서 방향을 바꿉니다. 데이터를 특성값 기준으로 잘게 나누는 방식이라, 곡선 관계도 상호작용도 사람이 항을 설계하지 않아도 스스로 잡아냅니다. 대신 선형 모델이 가진 매끈한 해석 가능성 일부를 내주게 되는데, 그 맞바꿈을 다음 편에서 봅니다.
정리
| 개념 | 한 줄 요약 |
|---|---|
| 선형 회귀 | 예측 = 특성의 가중합 + 절편. 계수가 각 특성의 기여 방향과 크기 |
| 계수 해석 | 크기 비교는 특성이 같은 스케일일 때만. 상관 큰 특성은 계수가 불안정 |
| 계수 계산 | 선형 회귀는 정규방정식(닫힌 해), 대안은 경사하강 |
| 로지스틱 회귀 | 선형 결합을 시그모이드로 확률화. 이름과 달리 분류기 |
| 결정경계 | 확률 0.5(z=0)가 되는 면. 선형 모델이라 항상 직선/평면 |
| 규제 | Ridge(L2), Lasso(L1), ElasticNet, 분류는 C(규제의 역수) |
| 강점 / 한계 | 해석 쉽고 빠른 베이스라인 / 선형 가정으로 비선형과 상호작용에 약함 |
다음 편에서는 선형 가정을 벗어나, 데이터를 조건으로 나눠 비선형 관계를 담는 결정트리를 다룹니다.