My blog
[ML_week3_chap5] 회귀 본문
01 회귀소개
- 여러개의 독립변수와 한 개의 종속 변수 간의 상관관계 모델링하는 기법 ex ) y = w1x1+w2x2
- 지도학습 , 연속형 숫자값 예측 (vs 분류 : 이산값 )
- 독립변수 : 피처 , 입력데이터 / 종속변수 : target , 결과 / 회귀 계수 : 가중치
선형 회귀 모델: 실제 값과 예측값의 차이(오류의 제곱 값)를 최소화하는 직선형 회귀선을 최적화하는 방식
+ 규제 ) 과적합 문제를 해결하기 위해서 회귀 계수에 패널치를 부과
| 일반 선형 회귀 | 규제 X , RSS(실제,예측 차이) 최소화할 수있게 회귀 계수 최적화 |
| 릿지 (L2) | 회귀 계수의 제곱합을 패널티 - 과적합 완화 : 상대적으로 큰 회귀 계수 값 영향 작게하려고 회귀 계수값 작게만듦 |
| 라쏘 (l1) | 회귀 계수의 절대값합 패널티 - 불필요한 변수 0으로 만들기 |
| 엘라스틱넷 | 릿지L2 + 라쏘L1 결합 , L1라쏘로 피처 개수 줄입 + L2릿지로 계수값 크기 조정 |
| 로지스틱회귀 | 분류에서 사용되는 선형모델 |
02 단순 선형 회귀를 통한 회귀 이해
1) 단순 선형 회귀 : y = w₀ + w₁*x
- RSS(잔차 제곱합)를 최소화하는 직선을 찾는 것
- 잔차(오류 값) 합이 최소가 되는 모델 찾기
- 비용 함수가 반환하는 값을 지속해서 감소시키고 최소의 오류값 찾는 것


03 비용 최소화 - 경사 하강법
비용 함수를 정의하고, 이를 최소화하는 과정인 경사 하강법을 사용
1.현재 위치에서 미분
2. 경사가 가파른 쪽의 반대로 이동
3. 기울기가 0에 가까워질 때까지 반복



- 가중치 업데이트 : 새로운 가중치 = 이전 가중치 - 편미분결과값 * 학습률
* 학습률, 한 번에 얼마나 큰 발걸음으로 내려갈지 결정 ( 편미분 값 너무 클수있으니 보정하는 용도)
경사하강법은 모든 데이터에 대해 반복적으로 비용함수 최소화 값을 없데이트해 매우 느림
- 확률적 경사하강법 : 일부 데이터만 이용해 w 업데이트 - 속도는 빠르지만 1개의 데이터로 일희일비로 지그재그 불안정
- 미니 배치 확률적 경사하강법 : 랜덤하게 X,y데이터에서 사이즈만큼만 추출 - 빠름
다중선형 회귀 : y=w₀+w₁X₁+w₂X₂+⋯ 형태
- 파이썬에서는 np.dot 연산을 통해 수많은 변수를 한 번에 계산
- OLS 기반의 회귀 계수 계산은 입력 피처의 독립성에 많은 영향을 받는다. 피처간 상관관계가 높은 경우 분산이 매우 커져서 오류에 민감
- 다중공선성: 변수들끼리 너무 친하면 생김 : 모델의 예측 변동성이 커져 조금만 데이터 바뀌어도 결과가 크게 바뀜
해결 ) 차원축소 (대표변수) , 규제모델 (릿지-영향력 골고루 작게 ,라쏘-불필요한 영향력 0)
04 사이킷런 LinearRegression
-LinearRegression : 예측값과 실제 값의 RSS를 최소화
fit() 메서드로 x,y받으면 회귀 계수 W를 [coef_]속성에 저장 [intercept[] : w0 절편

+ MSE , RMSE에 로그를 적용한 MSLE RMSLE도 사용하지만 사이킷런은 RMSE 제공 X MSE에 루트적용
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
import numpy as np
import pandas as pd
# 1. 데이터 준비 및 분할
y_target = bostonDF['PRICE']
X_data = bostonDF.drop(['PRICE'], axis=1)
X_train, X_test, y_train, y_test = train_test_split(X_data, y_target, test_size=0.3, random_state=156)
# 2. 선형 회귀 학습 및 예측
lr = LinearRegression()
lr.fit(X_train, y_train)
y_preds = lr.predict(X_test)
# 3. 모델 평가 (MSE, RMSE, R2 Score)
mse = mean_squared_error(y_test, y_preds)
rmse = np.sqrt(mse)
# 4 폴드 세트로 교차 검증 수행 (MSE 구하기)
# Scoring을 'neg_mean_squared_error'로 지정하면 음수 값이 반환됨
neg_mse_scores = cross_val_score(lr, X_data, y_target, scoring="neg_mean_squared_error", cv=5)
# RMSE를 구하기 위해 -1을 곱한 후 제곱근(sqrt) 적용
rmse_scores = np.sqrt(-1 * neg_mse_scores)
avg_rmse = np.mean(rmse_scores)
05 다항 회귀와 과적합/과소적합
- 데이터가 휘어져 있거나 복잡한 곡선 형태를 띨 때, 독립변수의 차수를 높여 예측 성능을 높이는 기법
- 다항 회귀는 선형 회귀
사이킷런은 별도의 '다항 회귀 클래스'를 제공하지 않아. 두 단계를 거쳐 구현한다.
- PolynomialFeatures: 기존의 단항 피처를 다항 피처(제곱항, 교차항 등)로 뻥튀기(?) 시킵니다.
- LinearRegression: 변환된 데이터를 가지고 선형 회귀를 돌린다
# 1. 데이터 준비 (피처 RM: 방 개수, LSTAT: 하위 계층 비율)
# X, y 데이터가 준비되어 있다고 가정
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)
# 2. Pipeline을 이용해 변환과 학습을 한 번에 # degree=2는 2차 다항식으로 만들겠다는 뜻
model = Pipeline([
('poly', PolynomialFeatures(degree=2, include_bias=False)),
('linear', LinearRegression())
])
# 3. 모델 학습 및 예측
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
# 4. 결과 확인 (회귀 계수 개수 확인)
print('다항 회귀 계수 개수:', model.named_steps['linear'].coef_.shape
-----
# 학습/테스트 분리
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)
# 다항 특성 변환
poly = PolynomialFeatures(degree=3, include_bias=False)
X_train_poly = poly.fit_transform(X_train)
X_test_poly = poly.transform(X_test)
# 선형회귀 학습 및 예측
lr = LinearRegression()
lr.fit(X_train_poly, y_train)
y_pred = lr.predict(X_test_poly)
다항 회귀를 이용한 과소적합 및 과적합

1) 다항 회귀로 보는 모델의 복잡도
과소적합 (Degree 1): 고편향 저분산
곡선 데이터를 직선으로 예측하려는 경우로 모델이 너무 단순해서 데이터의 기본 패턴조차 잡지 못함. 훈련과 테스트 데이터 모두에서 성능이 낮다.
- 균형 잡힌 모델 (Degree 4):
데이터의 실제 패턴을 가장 잘 따른다 노이즈에 휘둘리지 않고 본질적인 흐름을 잘 파악하여 테스트 데이터에서도 좋은 성능
- 과적합 (Overfitting, Degree 15): 저편향 고분산
데이터의 아주 미세한 노이즈(오차)까지 다 외워버린 상태로 학습 데이터는 완벽히 맞히지만, 조금만 데이터가 달라져도 예측값이 요동칩니다. 회귀 계수가 말도 안 되게 커지며 오차가 폭발
2) 편향-분산 트레이드오프
편향(Bias): 예측값들이 실제 정답에서 얼마나 멀리 떨어져 있는가? (단순한 모델일수록 높음)
분산(Variance): 예측값들이 서로 얼마나 흩어져 있는가? (복잡한 모델일수록 높음)
그러므로 회귀 계수의 크기를 강제로 줄여 분산을 낮추는 규제 기법이 필요함ㄴ
06 규제 선형 모델 - 릿지 라쏘 엘라스틱넷

순히 오차(RSS)만 줄이려고 하면 모델은 학습 데이터에만 집착하게 됩니다(과적합). 이를 방지하기 위해 회귀 계수(W)의 크기를 조절하는 Penalty를 주는 것이 규제 선형 모델의 핵심입니다.

알파가 작으면 : 규제가 약해져 학습 데이터 밀착 (과적합 위험)
알파가 크면 : 규제가 강해져 회귀 계수 W를 작게 만듦 (과소적합 위험)
-> 적절한 알파를 찾아 편향과 분산의 균형을 맞추는 것
| 릿지 (L2규제 W^2) | 계수를 0에 가깝게 줄임 | 모든 피처가 중요하고 골고루 영향을 줄 때 |
| 라쏘 (L1규제 절대값합 ) | 불필요 변수 0 | 실제로 결과값에 영향을 주는 변수만 남기고 싶을 때 |
| 엘라스틱넷 (L1+l2) | 라쏘변수선택 + 릿지 계수 안정화 | 피처가 많고 서로 연관성(상관관계) 높을 때 ( l1_ratio = 1이면 라쏘) |
from sklearn.linear_model import Ridge, Lasso, ElasticNet
from sklearn.model_selection import GridSearchCV
def get_best_params(model, params):
grid = GridSearchCV(model, param_grid=params,
scoring='neg_mean_squared_error', cv=5)
grid.fit(X_data, y_target)
rmse = np.sqrt(-1 * grid.best_score_)
print(f'{model.__class__.__name__} 최적 alpha: {grid.best_params_}, 최적 RMSE: {rmse:.3f}')
# 실행 예시
ridge_params = {'alpha': [0.1, 1, 10, 100]}
lasso_params = {'alpha': [0.07, 0.1, 0.5, 1]}
get_best_params(Ridge(), ridge_params)
get_best_params(Lasso(), lasso_params)
* 선형 회귀를 위한 데이터 변환
- 선형 모델은 데이터가 정규분포 일 때 가장 잘 작동한다 . 데이터에 왜곡이 있다면 다음 변환을 고려한다
1.표준화 정규화 : StandardScaler , MinMaxScaler (항상 성능이 오르진 않음)
2.로그 변환 : 큰 값을 작게 압축하여 데이터 왜곡을 효과적으로 해결 ( np.log1p() (0 또는 음수 오류 방지를 위해 1을 더함)
3. 다항 특성 추가: PolynomialFeatures를 사용하여 비선형 관계를 모델링. (단, 피처 폭발과 과적합 주의)
07 로지스틱 회귀
- 로지스틱 회귀는 선형 회귀의 방식을 기반으로 하되, 출력값을 시그모이드 함수에 통과시켜 0과 1 사이의 확률값으로 변환하는 분류 알고리즘이다
- 선형 회귀는 결과값이 무한대로 뻗어 나갑니다. 하지만 분류(예: 암이다/아니다)는 "예/아니오"라는 확실한 경계가 필요
- 선형 회귀: 종양 크기에 따라 '악성 수치'를 예측 (0.8, 1.2, 5.0 등 무한한 값)
- 로지스틱 회귀: 종양 크기에 따라 '악성일 확률'을 예측 (0.95 → 악성 확률 95%)


| lbfgs | 기본값, 메모리 절약, 병렬 처리 지원 | 다차원 데이터, 일반적인 상황 |
| liblinear | L1, L2 규제 모두 지원 | 데이터량이 적고 차원이 높을 때 |
| sag / saga | 확률적 경사 하강법 기반 | 대용량 데이터셋에서 빠른 수렴 |
C 값 (규제 강도): 선형 회귀의 alpha와 역수 관계입니다. C값이 작을수록 규제가 강해짐
Penalty: 규제 유형 (l1, l2)을 결정
from sklearn.datasets import load_breast_cancer
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import GridSearchCV
# 1. 데이터 로드 및 전처리 (표준화 필수)
cancer = load_breast_cancer()
scaler = StandardScaler()
data_scaled = scaler.fit_transform(cancer.data)
# 2. 로지스틱 회귀 및 하이퍼파라미터 튜닝
params = {
'solver': ['liblinear', 'lbfgs'],
'penalty': ['l2', 'l1'],
'C': [0.1, 1, 5, 10]
}
lr_clf = LogisticRegression()
grid_clf = GridSearchCV(lr_clf, param_grid=params, scoring='accuracy', cv=3)
grid_clf.fit(data_scaled, cancer.target)
print(f'최적 파라미터: {grid_clf.best_params_}')
print(f'최고 정확도: {grid_clf.best_score_:.3f}')
08 회귀 트리
- 분류 트리가 특정 클래스 레이블을 결정하는 것과는 달리, 회귀 트리는 리프 노드에 속한 데이터 값의 평균값을 구해 회귀 예측값을 계산
- 선형 회귀: 전체 데이터를 관통하는 하나의 직선(또는 평면)을 찾음.
- 회귀 트리: 데이터를 여러 개의 독립적인 구역으로 나누고, 각 구역마다 별도의 상수값(평균값)을 적용. 결과 그래프를 계단식 모양
장점 : 전처리 자유로움(스케일링 영향 거의 받지 않음 ) , 비선형성 파악
주의 : depth가 깊으면 작은 노이즈까지 맞춰 과적합 , 불연속성 (데이터 범위 밖 수치 예측 한계 )
'ML' 카테고리의 다른 글
| [ML_week4_chap4] 분류 (0) | 2026.02.10 |
|---|---|
| [ML_week4_chap3] 평가 (0) | 2026.02.10 |
| [ML_week2_chap6] 차원축소 (0) | 2026.01.27 |
| [ML_week2_chap2] 사이킷런 (0) | 2026.01.24 |
| [ML_week1_chap10] 시각화 (0) | 2026.01.19 |