과적합을 막는 방법을 찾다 보면 정규화(Regularization)를 빠르게 만나게 됩니다. L1이니 L2니 하는 이름이 나오는데, 처음엔 그냥 "복잡도를 줄이는 기법" 정도로만 알고 썼습니다. 그런데 두 방법이 파라미터를 다루는 방식이 달라서, 어떤 걸 쓰느냐에 따라 모델의 성격이 달라집니다.
오늘은 L1과 L2가 내부적으로 어떻게 작동하는지, 언제 어떤 걸 선택하는지 정리해보겠습니다. 📐
1. 정규화가 하는 일
정규화는 손실함수에 파라미터 크기에 대한 패널티 항을 추가해서 모델이 지나치게 복잡해지는 걸 막습니다. 패널티가 없으면 모델은 훈련 손실을 줄이기 위해 파라미터를 원하는 만큼 키울 수 있습니다. 특정 피처에 과도하게 의존하는 모델이 만들어지는 이유입니다.
정규화 항을 추가하면 모델은 훈련 손실과 파라미터 크기를 동시에 줄여야 합니다. 두 가지를 함께 최소화해야 하니 자연스럽게 불필요하게 큰 파라미터가 억제됩니다. 패널티를 어떻게 정의하느냐에 따라 L1과 L2로 나뉩니다.
정규화 없음: 훈련 손실만 최소화 → 과적합 가능
L1 정규화: 훈련 손실 + |파라미터| 합산 최소화
L2 정규화: 훈련 손실 + 파라미터² 합산 최소화

2. L1 정규화 (Lasso)
L1 정규화는 파라미터의 절댓값 합산을 패널티로 씁니다. 선형 회귀에 L1을 적용한 걸 Lasso(Least Absolute Shrinkage and Selection Operator) 회귀라고 부릅니다.
L1의 특징은 일부 파라미터를 정확히 0으로 만든다는 점입니다. 패널티 항이 절댓값이라 기울기가 불연속점(0 근처)에서 파라미터를 0으로 수렴시키는 방향으로 작동합니다. 파라미터가 0이 된다는 건 해당 피처가 모델에서 완전히 제거된다는 의미입니다. L1이 자동 피처 선택(Feature Selection) 효과를 낸다고 하는 이유입니다.
피처가 많고 그 중 일부만 실제로 중요할 것 같을 때 L1이 유용합니다. 모델을 학습시키면서 동시에 불필요한 피처를 걸러낼 수 있습니다.
3. L2 정규화 (Ridge)
L2 정규화는 파라미터의 제곱 합산을 패널티로 씁니다. 선형 회귀에 L2를 적용한 걸 Ridge 회귀라고 부릅니다.
L2는 파라미터를 0에 가깝게 줄이지만 완전히 0으로 만들지는 않습니다. 제곱 패널티는 파라미터가 클수록 더 강하게 억제하고, 작아질수록 패널티도 줄어듭니다.
그래서 모든 피처가 조금씩 기여하는 구조를 만듭니다. 피처 간 상관관계가 높은 다중공선성 상황에서 L2가 효과적입니다. 서로 연관된 피처들의 파라미터를 고르게 분산시켜 안정적인 모델을 만듭니다.
4. L1 vs L2 비교
| 항목 | L1 (Lasso) | L2 (Ridge) |
|---|---|---|
| 패널티 형태 | |파라미터| 합산 | 파라미터² 합산 |
| 파라미터 결과 | 일부를 정확히 0으로 | 0에 가깝게 줄이되 0은 아님 |
| 피처 선택 | 자동 피처 선택 가능 | 모든 피처 유지 |
| 다중공선성 | 하나만 선택, 나머지 제거 | 고르게 분산시켜 안정적 |
| 적합한 상황 | 피처 많고 일부만 중요할 때 | 피처 간 상관관계 높을 때 |
| sklearn 파라미터 | alpha (클수록 강한 정규화) | alpha (클수록 강한 정규화) |
5. ElasticNet: L1 + L2
L1과 L2를 동시에 적용하는 방법이 ElasticNet입니다. L1의 피처 선택 효과와 L2의 안정성을 동시에 얻을 수 있습니다.
l1_ratio 파라미터로 두 패널티의 비율을 조절합니다. l1_ratio=1이면 Lasso, l1_ratio=0이면 Ridge와 동일합니다.
어떤 정규화를 쓸지 확신이 없을 때 ElasticNet을 기본값으로 두고 l1_ratio를 교차 검증으로 튜닝하는 방법이 실용적입니다.
from sklearn.linear_model import Lasso, Ridge, ElasticNet
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error
import numpy as np
# 데이터 생성 (피처 50개 중 10개만 실제 영향)
X, y = make_regression(n_samples=200, n_features=50,
n_informative=10, noise=10, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
models = {
'Lasso (L1)': Lasso(alpha=0.1),
'Ridge (L2)': Ridge(alpha=1.0),
'ElasticNet': ElasticNet(alpha=0.1, l1_ratio=0.5)
}
for name, model in models.items():
model.fit(X_train, y_train)
pred = model.predict(X_test)
rmse = np.sqrt(mean_squared_error(y_test, pred))
n_zero = np.sum(model.coef_ == 0)
print(f"{name:15} | RMSE: {rmse:.2f} | 0이 된 파라미터 수: {n_zero}")
6. 다른 모델에서의 정규화
정규화 개념은 선형 모델에만 적용되는 게 아닙니다. 로지스틱 회귀의 C 파라미터는 정규화 강도의 역수입니다. C가 작을수록 강한 정규화입니다. XGBoost의 reg_alpha는 L1, reg_lambda는 L2 정규화에 해당합니다. 신경망에서는 가중치 감쇠(Weight Decay)가 L2 정규화와 동일한 효과를 냅니다.
모델마다 파라미터 이름이 달라서 처음엔 헷갈리는데, 결국 "파라미터가 과도하게 커지는 걸 막는다"는 원리는 동일합니다.
| 모델 | L1 파라미터 | L2 파라미터 | 비고 |
|---|---|---|---|
| Lasso / Ridge | alpha | alpha | 클수록 강한 정규화 |
| 로지스틱 회귀 | C (역수) | C (역수) | 작을수록 강한 정규화 |
| XGBoost | reg_alpha | reg_lambda | 기본값 reg_lambda=1 |
| 신경망 | — | weight_decay | L2와 동일 효과 |
정리
L1과 L2를 처음 배울 때 "둘 다 과적합 막는 거 아닌가?"라는 생각에 아무거나 쓰는 경향이 있습니다. 그런데 피처가 많고 희소한 데이터에서 L1을 쓰면 알아서 중요한 피처만 남겨주는 효과가 있어서 유용합니다. 반대로 피처들이 서로 연관돼 있는 상황에서 L1을 쓰면 연관 피처 중 하나만 살아남고 나머지가 제거되는 문제가 생깁니다. 어떤 데이터인지 파악하고 선택하는 게 맞습니다. 😊
'AI > ML' 카테고리의 다른 글
| [머신러닝] 교차 검증, 공정한 평가 기준 (1) | 2026.06.11 |
|---|---|
| [머신러닝] 과적합, 모델이 외울 때 생기는 일 (0) | 2026.05.31 |
| [머신러닝] 회귀 모델 오차 지표 비교 (0) | 2026.05.29 |
| [머신러닝] 분류 모델 평가 완전 정리 (0) | 2026.05.28 |
| [머신러닝] SVM, 마진을 설계하는 모델 (0) | 2026.05.28 |
HELLO WORLD
안녕하세요. 데이터로 말하는 분석가 모모입니다.
데이터를 구조화하고 분석하는 과정과 실무에 활용되는 도구 중심의 내용을 기록합니다.