릿지 회귀는 선형 회귀(Linear Regression)에 L2 정규화(Tikhonov 정규화)를 적용하여 오버피팅(Overfitting)을 방지하는 방법입니다.
L2 정규화는 모델의 손실 함수에 가중치 벡터(모델의 파라미터 )의 L2 노름(제곱합)을 추가로 포함시키는 방식입니다.
일반 선형 회귀의 목적 함수에 패널티(regularization term)를 추가한 형태
: 정규화의 강도를 조절하는 하이퍼파라미터로, 이 값을 조정해 가중치의 크기를 제어합니다.
: 일반 선형 회귀와 동일
: 가중치에 페널티를 적용
: 각 피처의 가중치 제곱을 패널티로 추가. 따라서 가중치 값이 커질수록 페널티가 커지고 모델이 이를 줄이려 노력합니다.
장점
과적합 방지
다중공선성 문제 완화
단점
from sklearn.linear_model import Ridge
ridge = Ridge(alpha=1.0) # alpha는 λ와 동일
ridge.fit(X_train, y_train)
y_pred = ridge.predict(X_test)
라쏘 회귀는 선형 회귀 모델에 L1 정규화를 적용하는 회귀 기법입니다. L1 정규화는 특정 피처의 가중치를 0으로 축소할 수 있어, 결과적으로 피처 셀렉션(feature selection) 역할을 수행합니다.
장점
불필요한 피처 제거 → 피처 선택 가능
과적합 방지
단점
피처 간 상관관계가 높은 경우, 어느 피처를 제거할지 랜덤하게 작동할 수 있음.
높은 차원 데이터(피처 개수가 샘플 수보다 많은 경우)에서 성능이 제한될 수 있음.
from sklearn.linear_model import Lasso
lasso = Lasso(alpha=0.1) # alpha는 λ와 동일
lasso.fit(X_train, y_train)
y_pred = lasso.predict(X_test)
: L1 정규화 강도
: L2 정규화 강도
두 규제 항목의 가중치를 동시에 조정하여 더 유연하고 안정적인 모델 학습 가능.
장점
피처 선택 가능 (L1)
과적합 방지 및 다중공선성 완화 (L2)
고차원 데이터에서 효과적
단점
from sklearn.linear_model import ElasticNet
elastic_net = ElasticNet(alpha=1.0, l1_ratio=0.5) # l1_ratio는 L1(Lasso)의 가중치 비율
elastic_net.fit(X_train, y_train)
y_pred = elastic_net.predict(X_test)
alpha: 전체 정규화 강도
l1_ratio: 이면 릿지 회귀와 같고, 이면 라쏘 회귀와 같음. 는 L1과 L2를 균등하게 결합.
| 모델 | 정규화 방식 | 장점 | 단점 |
|---|---|---|---|
| 릿지 회귀 (Ridge Regression) | L2 | 과적합 방지, 다중공선성 완화 | 피처를 선택하지 못함 (모든 피처 유지) |
| 라쏘 회귀 (Lasso Regression) | L1 | 과적합 방지, 불필요한 피처 제거 가능 (피처 선택 기능) | 피처 간 상관관계가 높은 경우 동작 불안정 |
| 엘라스틱 넷 (Elastic Net) | L1 + L2 | 과적합 방지, 피처 선택 가능, 상관관계 높은 피처에서도 잘 동작 | 하이퍼파라미터 튜닝(α, l1_ratio)의 복잡성 증가 |
릿지 회귀 (Ridge Regression): 피처가 많고 다중공선성이 큰 경우, 하지만 모든 피처를 보존해야 하는 경우.
다중공선성(Multicollinearity)은 회귀 분석(특히 선형 회귀)에서 발생하는 문제로, 독립 변수(피처)들 간에 높은 상관관계가 있는 경우를 말합니다.
라쏘 회귀 (Lasso Regression): 불필요한 피처를 제거하고 싶거나, 중요한 피처만 남기고 싶을 때.
엘라스틱 넷 (Elastic Net): 고차원 데이터에서 L1, L2 방식의 조합으로 안정적 학습이 필요할 때.
예제 데이터는 sklearn의 보스턴 주택 데이터셋(또는 사용자가 직접 준비한 데이터)을 사용
Ridge, Lasso, ElasticNet 회귀를 학습하고 각 알고리즘이 데이터를 모델링한 결과를 시각화할 준비를 합니다.
# 필요한 라이브러리 불러오기
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import Ridge, Lasso, ElasticNet
from sklearn.datasets import make_regression
# 샘플 데이터 생성 (선형 회귀용)
X, y = make_regression(n_samples=100, n_features=1, noise=20, random_state=42) # 1차원 데이터셋
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 스케일링 (특히 Lasso나 ElasticNet은 스케일링이 중요함)
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
X, y = make_regression(n_samples=100, n_features=1, noise=20, random_state=42)
위 코드는 sklearn.datasets의 make_regression 함수로 샘플 선형 회귀 데이터를 생성합니다.
n_samples=100: 데이터 샘플 100개 생성.
n_features=1: 입력 변수(피처) 1개 사용.
noise=20: 출력값(y)에 랜덤 노이즈를 추가(값이 클수록 산포 증가).
random_state=42: 결과를 재현 가능하게 만드는 난수 시드값.
X: 입력 데이터 (크기: (100, 1))
y: 출력 데이터 (크기: (100,))
이 데이터는 기울기와 노이즈가 포함된 선형 회귀 문제를 학습하기 위한 가상의 데이터셋입니다.
y = X * 계수 + 노이즈 형태입니다.import matplotlib.pyplot as plt
plt.scatter(X, y, label="Data with noise", color="blue")
plt.title("Synthetic Regression Data")
plt.xlabel("X")
plt.ylabel("y")
plt.legend()
plt.show()

# Ridge 회귀
ridge = Ridge(alpha=1.0)
ridge.fit(X_train, y_train)
ridge_preds = ridge.predict(X_test)
# Lasso 회귀
lasso = Lasso(alpha=0.1)
lasso.fit(X_train, y_train)
lasso_preds = lasso.predict(X_test)
# ElasticNet 회귀
elastic_net = ElasticNet(alpha=1.0, l1_ratio=0.5)
elastic_net.fit(X_train, y_train)
elastic_preds = elastic_net.predict(X_test)
데이터 분포와 회귀선 시각화
# 테스트 데이터 시각화
plt.figure(figsize=(12, 6))
# 실제 데이터 분포
plt.scatter(X_test, y_test, color='gray', label='Actual Data', alpha=0.6)
# Ridge 회귀선
plt.plot(X_test, ridge_preds, color='blue', label='Ridge Regression')
# Lasso 회귀선
plt.plot(X_test, lasso_preds, color='green', label='Lasso Regression')
# ElasticNet 회귀선
plt.plot(X_test, elastic_preds, color='red', label='ElasticNet Regression')
# 그래프 스타일
plt.title("Comparison of Ridge, Lasso, and ElasticNet Regression")
plt.xlabel("X")
plt.ylabel("y")
plt.legend()
plt.grid(True)
plt.show()

잔차(residual) 분석
# 잔차 계산
ridge_residuals = y_test - ridge_preds
lasso_residuals = y_test - lasso_preds
elastic_residuals = y_test - elastic_preds
# 잔차 시각화
plt.figure(figsize=(12, 6))
plt.scatter(ridge_preds, ridge_residuals, color='blue', alpha=0.6, label='Ridge Residuals')
plt.scatter(lasso_preds, lasso_residuals, color='green', alpha=0.6, label='Lasso Residuals')
plt.scatter(elastic_preds, elastic_residuals, color='red', alpha=0.6, label='ElasticNet Residuals')
# 그래프 스타일
plt.axhline(y=0, color='black', linestyle='--', linewidth=1)
plt.title("Residuals of Ridge, Lasso, and ElasticNet Regression")
plt.xlabel("Predicted Values")
plt.ylabel("Residuals")
plt.legend()
plt.grid(True)
plt.show()

가중치(weight) 비교 시각화 (각 모델의 계수 비교)
# 가중치(회귀 계수) 시각화
ridge_coef = ridge.coef_
lasso_coef = lasso.coef_
elastic_coef = elastic_net.coef_
plt.figure(figsize=(8, 4))
x_labels = ['Feature 1']
plt.bar(x_labels, ridge_coef, color='blue', alpha=0.6, label='Ridge Coefficients')
plt.bar(x_labels, lasso_coef, color='green', alpha=0.6, label='Lasso Coefficients')
plt.bar(x_labels, elastic_coef, color='red', alpha=0.6, label='ElasticNet Coefficients')
plt.title("Comparison of Coefficients: Ridge, Lasso & ElasticNet")
plt.ylabel("Coefficient Value")
plt.legend()
plt.grid(True)
plt.show()

모델의 성능 평가 (MSE, R²)
📌 R² 값의 의미
1.0에 가까울수록 모델이 데이터를 잘 설명하고 있다는 의미입니다.
- R² = 1이면, 모든 데이터가 완벽하게 예측되었다는 뜻입니다(모델이 최적의 성능을 보임).
0에 가까울수록 설명력이 떨어지는 모델입니다.- R² = 0이면, 모델이 데이터를 전혀 설명하지 못하고 있다는 뜻입니다(단순 평균 수준의 예측).
R²가 음수일 수도 있습니다.
- 이 경우 모델이 타깃 변수를 예측하는 데 완전히 실패했음을 뜻합니다. 모델의 예측이 단순히 평균값을 사용하는 것보다 나쁠 정도로 부정확하다는 의미입니다.
from sklearn.metrics import mean_squared_error, r2_score
# 성능 평가 함수
def evaluate_model(name, y_true, y_pred):
mse = mean_squared_error(y_true, y_pred)
r2 = r2_score(y_true, y_pred)
print(f"{name} - MSE: {mse:.2f}, R²: {r2:.2f}")
# 각 모델 평가
evaluate_model("Ridge", y_test, ridge_preds)
evaluate_model("Lasso", y_test, lasso_preds)
evaluate_model("ElasticNet", y_test, elastic_preds)
