ML,DL,LangChain/02_EDA와 MLP

데이터 분리와 피쳐 스케일링

  • -
scikit-learn 데이터 분할 및 피처 스케일링 가이드

이번 포스트에서는 머신러닝 모델의 일반화 성능을 좌우하는 핵심 첫 단추, scikit-learn을 활용한 데이터 분할(Train/Test Split)을 완벽하게 마스터해본다.

 

📑 데이터 분할: "족보만 달달 외운 학생은 진짜 시험에서 망한다!"

머신러닝 모델을 훈련할 때 가장 흔히 범하는 실수가 있다. 바로 가지고 있는 데이터를 전부 다 공부(학습)시키는 데 써버리는 것이다. 이럴 경우 모델은 학습 데이터에만 과도하게 최적화되는 과적합(Overfitting)에 빠지게 된다. 수능 시험을 보기 전에 기출문제와 답만 통째로 외워버린 셈이다.

이를 완벽하게 해결하기 위해 우리는 데이터를 용도별로 철저하게 칼로 쪼개듯 분할해야 한다. 각 데이터셋의 역할과 특징은 다음과 같이 정리할 수 있다.

데이터셋 추천 비율 핵심 목적 비유 (수학 공부)
Train Set (훈련용) 70% ~ 80% 모델의 가중치와 편향을 학습시켜 규칙을 깨우치게 함 기본서 개념 공부 및 연습 문제 반복 풀이
Validation Set (검증용) 10% ~ 20% 하이퍼파라미터를 튜닝하며 최적의 모델 구조 결정 모의고사를 통한 실력 점검 및 피드백
Test Set (평가용) 10% ~ 20% (혹은 30%) 학습에 쓰이지 않은 "처음 보는" 데이터로 최종 성능 측정 실제 실력을 평가받는 단 한 번의 수능 시험
📂 원본 데이터가 Train과 Test로 분할되는 흐름
전체 데이터셋 (100%) Train Set (70%) 📖 Test Set (30%) 🎯

🎨 그림으로 이해하는 데이터 분할 메커니즘

그냥 무작위로 데이터를 나누다 보면 특정 클래스가 한쪽으로 쏠리는 현상이 발생해 모델의 학습이 왜곡될 수 있다. 이를 방지하기 위해 사용하는 원리와 Stratify(계층적 샘플링) 유무의 결정적인 차이를 시각적으로 확인해본다.

⚖️ Stratify (계층 분할)의 묘수와 차이점
원본 클래스 비율 (레드 70% : 화이트 30%) Red (70%) White (30%) ❌ 일반 무작위 분할 (비율이 깨져 편향됨) Train Set: Test Set: ✅ Stratify=y 계층 분할 (클래스 원본 비율 7:3 유지!) Train Set: Test Set:

🛠️ scikit-learn 실무 분할 템플릿 코드

우리가 진행한 와인 데이터셋 실습(Chapter 1-1)에서 실제로 사용된 정석 코드이다. `train_test_split`을 호출할 때 test_sizestratify 옵션이 어떻게 구성되는지 꼭 눈으로 익혀둔다.

data_split.py Python 3.11
# 1. 사이킷런의 머신러닝 데이터 분리 라이브러리 탑재하기
from sklearn.model_selection import train_test_split

# 2. 독립변수(X)와 타겟변수(y)를 학습 70% : 테스트 30% 비율로 분리하기
# stratify=y 옵션을 명시하여 클래스 쏠림 현상을 예방한다!
X_train, X_test, y_train, y_test = train_test_split(
    X, y,
    test_size=0.3,       # 평가용 테스트 셋 비율을 30%로 지정
    random_state=42,     # 난수 기준점을 고정하여 매 실행마다 동일한 분리 보장
    stratify=y           # 타겟 변수(y)의 클래스 비율을 균등하게 지켜서 쪼개기
)

# 3. 분리 완료된 데이터 형태(Shape) 출력으로 확인해보기
print(f"학습셋 크기: {X_train.shape}, 테스트셋 크기: {X_test.shape}")
⚠️ 주의할 점 (Caution)!
stratify=y 옵션은 타겟의 비율을 맞추는 기능이므로 분류(Classification) 문제에만 유효하다. 집값 예측 같은 회귀(Regression) 문제에서는 연속적인 숫자가 들어가기 때문에 이 옵션을 설정하면 ValueError 에러가 터지니 반드시 제외해 주어야 한다!

올바른 분할을 마쳤다면, 머신러닝 알고리즘이 변수별 눈금의 크기 차이로 인해 헷갈리지 않도록 해주는 표준화 스케일링(StandardScaler) 단계를 연이어 수행해야 한다.

⚖️ 피처 스케일링: 표준화(Standardization) vs 정규화(Normalization)

머신러닝 변수들의 눈금 크기를 맞춰주는 스케일링(Scaling)에는 크게 두 가지 정석적인 방법이 있다. 바로 표준화(Standardization)정규화(Normalization)이다.

이해를 돕기 위해, 고기 300g과 소금 1스푼의 비유를 통해 피처 스케일링이 왜 필수적인지 시각적으로 확인해본다.

🍳 요리 레시피로 이해하는 피처 스케일링 (단위 통일의 중요성)
❌ 스케일링 전 (숫자 크기 비교) 고기 (300g): 절댓값: 300 소금 (1스푼): 절댓값: 1 🤖 모델의 착각: "고기(300)만 챙겨야지!" ✅ 스케일링 후 (공평한 가치 변환) 고기 (표준화 변환값): 정규화 점수: 0.8 소금 (표준화 변환값): 정규화 점수: 0.7 ⚖️ 모델의 판단: "둘 다 공평하게 중요하군!"

실무 와인 데이터셋에서도 알코올 도수(10 내외)와 프롤린(1000 내외)의 절댓값 단위 차이가 매우 심하므로, 위 예시처럼 알고리즘의 편향을 사전에 막기 위해 반드시 특성 스케일을 일치시켜주어야 한다.

스케일링 비교 표준화 (Standardization) 정규화 (Normalization)
핵심 정의 평균을 0, 표준편차를 1로 맞춰 표준정규분포 형태로 특성을 재정렬함 모든 특성의 최소값을 0, 최대값을 1로 고정하여 특정 범위로 고르게 압축함
수학적 공식 z = (x - 평균) / 표준편차 x_new = (x - 최소) / (최대 - 최소)
변환 후 범위 정해진 경계가 없음 (대부분 -3 ~ 3 사이에 골고루 안착함) 0 ~ 1 사이 (변환된 피처의 절대 최저는 0, 최고는 1이 됨)
이상치 영향 영향 적음 (이상치 하나 때문에 평범한 데이터 분포가 왜곡되지 않음) 영향 매우 큼 (극단적으로 크거나 작은 값 하나가 전체 스케일을 0 근처로 납작하게 찌그러뜨림)
주요 알고리즘 선형 회귀, 로지스틱 회귀, 서포트 벡터 머신(SVM) 등 분포 기반 모델 인공신경망(딥러닝), K-최근접 이웃(KNN), K-평균 군집화(K-Means) 등 거리 및 크기 기준 모델

🔍 StandardScaler는 어떻게 작동하는가?

실습에서 주력으로 사용한 StandardScaler는 데이터를 평균이 0, 표준편차가 1인 표준정규분포 형태로 변환한다. 수식은 다음과 같이 간단하다.

z = (x - μ) / σ

여기서 μ(뮤)는 해당 특성의 평균값이고, σ(시그마)는 표준편차이다. 사이킷런의 스케일러 메서드는 이 수식을 기반으로 2단계에 걸쳐 작동한다.

  • fit() 단계: 훈련 데이터(X_train)의 모든 열을 훑으며 열별 평균(μ)과 표준편차(σ)를 계산하여 메모리에 저장한다. 아직 데이터 변환은 일어나지 않는다.
  • transform() 단계: 저장된 평균(μ)과 표준편차(σ)를 변환 공식에 대입하여 실제 데이터를 새로운 스케일 값(z)으로 연산하여 반환한다.

🛠️ scikit-learn 실무 스케일러 템플릿 코드

scaler.py Python 3.11
# 1. 사이킷런의 전처리 모듈에서 표준화 및 정규화 도구 임포트하기
from sklearn.preprocessing import StandardScaler, MinMaxScaler

# 2. 스케일러 객체 생성하기
scaler = StandardScaler()

# 3. 훈련 데이터(X_train) 기준으로 스케일 정보 계산(fit) 및 변환(transform) 한 번에 실행하기
X_train_norm = scaler.fit_transform(X_train)

# 4. 테스트 데이터(X_test)는 훈련 데이터의 스케일 기준을 그대로 적용하여 변환(transform)만 수행하기
X_test_norm = scaler.transform(X_test)
⚠️ 실무 단골 감점/오류 포인트: 테스트 데이터에는 fit()을 절대 금지한다!
테스트 데이터(X_test)에는 절대로 fit()이나 fit_transform()을 수행하면 안 된다. 테스트 데이터는 미래의 보지 못한 가상의 환경을 평가하기 위한 것이므로, 훈련 데이터로 구축한 스케일 기준(훈련셋의 평균과 표준편차)을 그대로 대입해서 평가해야 한다. 만약 테스트 데이터에 fit()을 새로 하게 되면 테스트셋만의 독립적인 평균과 표준편차가 계산되어 대입되므로 변수간 상호 크기 왜곡이 일어나며 모델 예측이 완전히 어긋나게 된다. 반드시 훈련셋으로만 fit을 한 뒤 테스트셋에는 transform()만 적용해야 한다!

'ML,DL,LangChain > 02_EDA와 MLP' 카테고리의 다른 글

Pytorch 활용  (0) 2026.08.06
Linear Regression vs Logistic Regression  (0) 2026.08.05
SequentialMLP 데이터 흐름  (1) 2026.03.12
PyTorch 개론  (0) 2026.03.10
모델 학습 전체 파이프 라인  (0) 2026.03.10
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.