전처리와 데이터 분할
관련 기초 개념
개요
예측 시점과 자료 의미를 보존하는 분할·전처리를 구성한다.
먼저 데이터 구성과 품질 점검, 데이터 분할·특징·전처리의 핵심 개념을 확인하세요.
세부 학습 목표
- 학습·검증·시험의 역할과 무작위·시간·그룹 분할을 선택한다.
- 결측·이상치·표준화·MinMax·범주 인코딩을 입력 의미에 맞춰 적용한다.
- 학습에서만 fit하고 새 범주·필수 열·변환 일관성을 검사한다.
핵심 개요
전처리는 결측 대체·범주 인코딩·스케일링과 같은 변환입니다. 학습과 시험을 나눈 뒤 학습 자료에서만 변환 규칙을 맞추고 다른 자료에는 같은 규칙을 적용합니다.
범주와 열 순서가 바뀌면 모델 입력의 의미도 바뀝니다. 파이프라인과 열 변환기를 사용해 전처리·모델 계약을 함께 관리하면 누출과 불일치를 줄일 수 있습니다.
필요한 용어
- 인코딩: 범주 값을 모델 입력에 맞게 표현하는 변환
- Pipeline: 전처리와 모델 단계를 묶어 실행하는 구성
작동 과정
- 타깃·ID·누출 열을 제외하고 분할합니다.
- 학습 자료에 전처리와 모델을 fit합니다.
- 새 범주·결측·열 순서의 시험 입력을 검사합니다.
변환이 숫자의 의미를 어떻게 바꾸는가
| 처리 | 원리 | 주의 |
|---|---|---|
| 결측 대체 | 학습 자료의 중앙값·최빈값 등으로 채움 | 타깃 결측을 무조건 입력처럼 채우지 않음 |
| 이상값 처리 | 오류 수정·제외·변환 등을 업무 의미로 결정 | 드문 실제 고액을 자동 삭제하지 않음 |
| StandardScaler | (값−학습 평균) / 학습 표준편차 | 분포를 정규분포로 만드는 보장은 없음 |
| MinMaxScaler | 학습 최소·최대 기준으로 범위를 변환 | 새 값은 학습 범위를 벗어날 수 있음 |
| One-hot | 범주마다 별도 표시 열 | 새 범주·열 순서 계약 필요 |
| 순서/라벨 표현 | 범주를 정수로 표현 | 임의 숫자를 크기·거리로 오인할 수 있음 |
-
LabelEncoder는 scikit-learn에서 주로 타깃 y의 라벨 표현에 사용합니다. 입력의 순서 없는 도시는 OneHotEncoder 같은 변환을 비교하고, 실제 순서가 있는 범주는 순서를 명시합니다.
학습 평균 40·표준편차 10이면 값 60은 2입니다. 시험 평균으로 다시 fit하면 같은 값의 표현이 달라집니다. Pipeline은 학습 때 변환을 fit하고 예측 때 같은 규칙을 적용하도록 묶는 수단입니다.
scikit-learn: Preprocessing data · scikit-learn: Common pitfalls
시험에 필요한 자료를 미리 엿보지 않기
-
학습은 가중치·변환을 맞추고, 검증은 설정·중단·임계값을 고르며, 시험은 선택이 끝난 결과를 확인합니다. 전체 자료를 먼저 대체·스케일링한 뒤 나누면 시험 분포를 미리 사용합니다.
-
독립 표본의 분류는 층화 무작위 분할을 비교할 수 있습니다. 미래 예측은 시간 순서, 같은 고객의 반복 기록은 고객 단위 분할을 검토합니다. random_state는 같은 환경에서 분할을 재현할 설정이지 누출 방지 기능이 아닙니다.
가상 예: 한 고객 기록이 학습과 시험에 섞이면 처음 보는 고객의 성능을 과대평가할 수 있습니다. 행 수만 나누지 말고 평가할 대상과 시점을 정의합니다. 시험의 지시된 분할 조건이 있다면 그 계약도 지킵니다.
scikit-learn: train_test_split · scikit-learn: Common pitfalls
풀이 예제
아래 입력과 기록은 직접 만든 교육용 가상 자료입니다.
입력·조건
학습에는 서울·부산, 시험에는 새 범주 대전이 있습니다.
판단·결과
정한 새 범주 처리 정책으로 변환하며 시험 자료를 보고 다시 fit하지 않습니다.
이렇게 판단한 이유
배포 때도 새로운 값이 올 수 있으므로 계약에 오류·미지 범주 처리가 있어야 합니다.
로컬 실행 예제
검증 환경: Python 3.12.14, numpy 2.3.5, pandas 2.2.3, scikit-learn 1.8.0. pip install numpy==2.3.5 pandas==2.2.3 scikit-learn==1.8.0 후 python ml_pipeline.py. 운영 자료는 포함하지 않습니다.
python -m pip install numpy==2.3.5 pandas==2.2.3 scikit-learn==1.8.0
python ml_pipeline.py"""Synthetic classification workflow; assertions verify behavior, not real-world quality."""
import numpy as np
import pandas as pd
import sklearn
from sklearn.compose import ColumnTransformer
from sklearn.impute import SimpleImputer
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import confusion_matrix, precision_recall_fscore_support
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import OneHotEncoder, StandardScaler
x = pd.DataFrame({'age':[20,25,30,np.nan,45,50,55,60,22,27,32,37,42,47,52,57],
'city':['Seoul','Busan']*8})
y = np.array([0,0,0,1,1,1,1,1,0,0,0,0,1,1,1,1])
train, test = train_test_split(np.arange(len(y)), test_size=0.25, random_state=7, stratify=y)
preprocess = ColumnTransformer([
('number', Pipeline([('impute', SimpleImputer(strategy='median')), ('scale', StandardScaler())]), ['age']),
('category', Pipeline([('impute', SimpleImputer(strategy='most_frequent')), ('encode', OneHotEncoder(handle_unknown='ignore'))]), ['city'])])
model = Pipeline([('prepare', preprocess), ('classify', LogisticRegression(random_state=7))])
model.fit(x.iloc[train], y[train])
actual_median = model.named_steps['prepare'].named_transformers_['number'].named_steps['impute'].statistics_[0]
assert actual_median == np.nanmedian(x.iloc[train]['age'])
prediction = model.predict(x.iloc[test])
assert prediction.shape == (4,)
assert confusion_matrix(y[test], prediction, labels=[0,1]).sum() == 4
p,r,f,_ = precision_recall_fscore_support(y[test], prediction, average='binary', zero_division=0)
unknown = pd.DataFrame({'age':[np.nan], 'city':['Daejeon']})
assert model.predict(unknown).shape == (1,)
try:
model.predict(unknown.drop(columns='age'))
except ValueError:
pass
else:
raise AssertionError('missing required column was accepted')
print(f'PASS: train-only preprocessing, unseen category, missing-column rejection; sklearn {sklearn.__version__}')
print(f'Synthetic held-out n=4: precision={p:.3f}, recall={r:.3f}, F1={f:.3f}; not a deployment score')기대 결과: 분할→학습→평가→새 범주·누락 열 검증
2026-10-21 로컬 환경에서 실행했습니다. 가상 자료·소형 CPU 예제의 동작 검사이며 실제 업무 모델의 품질·클라우드·GPU·Office 제품 연동 검증은 아닙니다.
실습 자료
흔한 실패와 복구
시험 자료를 포함해 평균·스케일·범주 목록을 정하지 않습니다. 변환 규칙에 평가 정보가 섞일 수 있습니다.
확인 문제
시험에 처음 본 범주가 나오면?
- 사전에 정한 처리 정책을 적용하고 계약을 검사한다
- 시험을 섞어 인코더를 다시 fit한다
- 열을 임의 삭제한다
풀이 기록 기능을 불러오는 중…
해설 보기
정답: A. 사전에 정한 처리 정책을 적용하고 계약을 검사한다
사전에 정한 처리 정책을 적용하고 계약을 검사한다 시험 자료를 포함해 평균·스케일·범주 목록을 정하지 않습니다. 변환 규칙에 평가 정보가 섞일 수 있습니다.
학습에서 MinMax를 맞춘 뒤 더 큰 새 값이 들어오면?
- 항상 원래 범위 안으로 자동 제한된다
- 정한 범위를 벗어날 수 있으므로 입력·정책을 확인한다
- 시험 자료에 다시 fit하는 것이 항상 안전하다
풀이 기록 기능을 불러오는 중…
해설 보기
정답: B. 정한 범위를 벗어날 수 있으므로 입력·정책을 확인한다
MinMax는 학습 최소·최대를 기준으로 선형 변환합니다. 새 극단값이나 드리프트의 처리는 별도 정책입니다.
참고 자료
- AICE Associate official overview — 공식 렌더링 화면에서 데이터 분석·전처리·AI 모델링의 세부 범위 및 30·30·40점 확인. 패키지 버전·개별 알고리즘의 필수 출제 여부는 확정하지 않음.
- scikit-learn: Common pitfalls — 분할 전후 전처리와 데이터 누출.
- pandas: Introductory tutorials — 표 읽기·선택·집계·조인.
- scikit-learn: Preprocessing data — 표준화·정규화·범주 인코딩과 입력 계약.
- scikit-learn: train_test_split — 무작위 분할·층화·재현 설정.
자료 확인: 2026-10-25. 사례·문항·실습은 자체 제작했습니다. 외부 서비스 호출과 실제 모델 품질 측정은 학습자가 별도 환경에서 수행합니다.
직접 적용하기
교육용 가상 상황
같은 고객의 여러 달 기록으로 다음 달 해지를 예측합니다. 전체 평균으로 결측을 채운 뒤 행을 무작위 분할했습니다. 누출 후보·변환·새 범주 검사를 고치세요.
선택·계산·진단의 근거를 조건과 연결하고, 확인할 결과를 적으세요.
답안 저장 기능을 불러오는 중…
검증 기준과 해설 보기
- 평가 대상에 맞는 고객·시간 경계를 정한다
- 분할 뒤 학습 자료에서만 대체·스케일·인코딩을 fit한다
- 새 범주·필수 열·열 순서와 타깃 시점을 검사한다
새 고객과 미래 시점 중 평가하려는 대상을 먼저 정하고 그룹·시간 경계로 분리합니다. 예측 뒤 생긴 열은 제외합니다. 학습 자료로만 대체·인코딩·스케일을 fit하고 검증·시험에 transform합니다. 새 범주 정책과 누락 열·자료형·열 순서를 검사합니다.
복습하기
- 분할과 전처리 fit 중 무엇이 먼저인가요?
- Pipeline에 무엇을 묶나요?
- 새 범주는 왜 시험하나요?
- 학습에서 MinMax를 맞춘 뒤 더 큰 새 값이 들어오면?
답변 확인 기준
- 분할과 전처리 fit 중 무엇이 먼저인가요?
분할 후 학습 자료에만 fit합니다.
- Pipeline에 무엇을 묶나요?
전처리와 모델의 일관된 실행 흐름을 묶습니다.
- 새 범주는 왜 시험하나요?
실제 새 입력에서 오류·의미 변경이 생길 수 있기 때문입니다.
- 학습에서 MinMax를 맞춘 뒤 더 큰 새 값이 들어오면?
정한 범위를 벗어날 수 있으므로 입력·정책을 확인한다. MinMax는 학습 최소·최대를 기준으로 선형 변환합니다. 새 극단값이나 드리프트의 처리는 별도 정책입니다.