본문 바로가기
정보/IT 지식 정보

정규화 vs 표준화, 그리고 L1 규제데이터 스케일링의 모든 것 [8편]

by 안다니. 2026. 3. 30.
반응형
스케일링

특성마다 스케일이 다르면 왜 문제가 되는지, 어떻게 해결하는지 코드로 확인합니다

시리즈: 머신러닝 밑바닥부터 구현하기
1~7편: 퍼셉트론 → ... → 범주형 데이터 인코딩
7편: 인코딩 · 8편: 스케일링과 규제 · 9편: 특성 선택

Wine 데이터셋 소개

이번 편부터는 Wine 데이터셋을 사용합니다. 이탈리아의 세 지역에서 생산된 와인 178개의 화학적 특성 13가지를 담고 있고, 3개 클래스로 분류하는 것이 목표입니다.

df_wine = pd.read_csv(url, header=None)
# 13개 특성: Alcohol, Malic acid, Ash, ...
# 3개 클래스: Class 0, 1, 2

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=0, stratify=y)
데이터 분할 결과
훈련 세트: 124개 (13개 특성) / 테스트 세트: 54개 (13개 특성)

13개 특성의 스케일이 제각각입니다. Alcohol은 11~15 범위이고, Proline은 200~1600 범위입니다. 이런 상태로 경사 하강법 기반 모델(로지스틱 회귀, SVM 등)에 넣으면 학습이 제대로 되지 않습니다.

정규화 — Min-Max 스케일링

정규화(Normalization)는 모든 값을 0~1 범위로 변환합니다. 각 특성의 최솟값을 0으로, 최댓값을 1로 맞추고 나머지 값은 비례적으로 배치합니다.

from sklearn.preprocessing import MinMaxScaler

mms = MinMaxScaler()
X_train_norm = mms.fit_transform(X_train)
X_test_norm = mms.transform(X_test)
Alcohol 특성 변환 결과
변환 전: 최솟값 11.41, 최댓값 14.83
변환 후: 최솟값 0.0, 최댓값 1.0

표준화 — StandardScaler

표준화(Standardization)는 각 특성의 평균을 0, 표준편차를 1로 변환합니다. 정규분포와 유사한 형태로 만들어줍니다.

from sklearn.preprocessing import StandardScaler

stdsc = StandardScaler()
X_train_std = stdsc.fit_transform(X_train)
X_test_std = stdsc.transform(X_test)
Alcohol 특성 변환 결과
변환 전: 평균 13.03, 표준편차 0.82
변환 후: 평균 ≈ 0.0, 표준편차 ≈ 1.0

정규화 vs 표준화, 언제 뭘 쓰나?

반응형
정규화 (Min-Max) 값을 0~1로 한정
이상치(outlier)에 민감
신경망, 이미지 처리에서 주로 사용
범위가 정해진 데이터에 적합
표준화 (Standard) 평균 0, 표준편차 1로 변환
이상치에 상대적으로 강건
경사 하강법 기반 모델에 적합
대부분의 머신러닝에서 기본 선택
실무 팁
뭘 써야 할지 모르겠으면 표준화(StandardScaler)를 기본으로 쓰세요. 대부분의 머신러닝 알고리즘에서 안정적으로 동작합니다. 단, 결정 트리나 랜덤 포레스트는 스케일링이 불필요합니다.

L1 규제 — 불필요한 특성을 자동으로 제거

Wine 데이터셋에는 특성이 13개입니다. 이 중 분류에 쓸모없는 특성이 있다면? L1 규제(Lasso)는 학습 과정에서 불필요한 특성의 가중치를 정확히 0으로 만들어 자동으로 특성을 선택합니다.

from sklearn.linear_model import LogisticRegression

lr = LogisticRegression(penalty='l1', C=1.0,
                        solver='liblinear', random_state=1)
lr.fit(X_train_std, y_train)
L1 규제 적용 결과
훈련 정확도: 100% / 테스트 정확도: 100%

가중치 확인 시, 여러 특성의 가중치가 정확히 0.0인 것을 확인할 수 있습니다. L1 규제가 해당 특성들을 "불필요"하다고 판단하여 자동으로 제거한 것입니다.
L1 규제 vs L2 규제
L1(Lasso): 가중치를 정확히 0으로 만듦 → 특성 선택 효과
L2(Ridge): 가중치를 0에 가깝게 줄이되 0으로 만들지는 않음 → 모든 특성 유지

특성 수를 줄이고 싶으면 L1, 전체적으로 안정화하고 싶으면 L2를 사용합니다.

C 값에 따른 가중치 변화 시각화

규제 강도를 조절하는 C 값을 변화시키면서 가중치가 어떻게 변하는지 관찰할 수 있습니다.

weights, params = [], []
for c in np.arange(-4., 6.):
    lr = LogisticRegression(
        penalty='l1', C=10.**c,
        solver='liblinear', random_state=0)
    lr.fit(X_train_std, y_train)
    weights.append(lr.coef_[1])
    params.append(10**c)
시각화 결과
C가 작을수록(규제가 강할수록) 거의 모든 가중치가 0에 수렴합니다. C가 커질수록 가중치가 자유롭게 발산하며, 중요한 특성의 가중치가 먼저 살아나는 것을 확인할 수 있습니다. 이 그래프를 통해 어떤 특성이 분류에 중요한지 직관적으로 파악할 수 있습니다.

8편 핵심 정리

정규화(Min-Max)는 0~1 범위로, 표준화(Standard)는 평균 0/표준편차 1로 변환합니다.

대부분의 경우 표준화를 기본으로 사용하되, 결정 트리 계열은 스케일링이 불필요합니다.

L1 규제는 불필요한 특성의 가중치를 0으로 만들어 자동으로 특성을 선택합니다.

다음 편에서는 더 체계적인 특성 선택 방법인 순차 후진 선택 알고리즘을 다룹니다.

다음 글 예고
👉 9편: 순차 후진 선택(SBS)으로 최적의 특성 조합 찾기
13개 특성 중 몇 개를 써야 최고 성능이 나오는지, 자동으로 탐색하는 알고리즘을 구현합니다.

머신러닝 밑바닥부터 구현하기 시리즈 [8편]

반응형

댓글