이번 글에서는 사이킷런(Scikit-learn)이 제공하는 내장 데이터와 라이브러리를 활용해,
기본적인 분류 모델의 흐름을 실습해 보는 과정을 정리하려고 한다.
모든 모델을 다루지는 않지만, 대표적인 분류 알고리즘들을 이용해 데이터 불러오기 → 학습 → 예측 → 평가까지의 과정을 따라가 보며,
머신러닝의 전체적인 흐름을 이해하는 데 도움이 되었으면 한다.
해당 실습 코드는 아이펠 모두의연구소의 [머신러닝 활용 다양한 데이터 다루기] 모듈 강의를 기반으로 작성되었습니다.
* 코드의 동작과 의미는 함께 이해할 수 있도록 주석으로 설명을 덧붙였다.
1️⃣ 라이브러리 불러오기
먼저 사용할 데이터 셋을 확인한다.
사이킷런에서는 다양한 예제 데이터 셋을 내장 형태로 제공하고 있어, 실습에 바로 활용할 수 있다.
# 사이킷런 내장데이터 확인
import sklearn.datasets
sklearn.datasets.__all__ # load로 된 부분이 데이터셋
이번 실습에서는 유방암 진단 데이터 셋을 사용하였다.
이 데이터는 이진 분류(Binary Classification) 문제에 해당하며, 간단한 분류 실습에 적합하다.
# 데이터 불러오기
from sklearn.datasets import load_breast_cancer
다음은 전처리에 필요한 라이브러리들이다.
머신러닝에서 범주형 데이터는 수치형으로 변환해줘야 하며,
수치형 데이터는 스케일 차이를 줄여줘야 머신러닝 모델이 잘 작동하는 경향이 있어 필요한 도구들이다.
# 인코딩: 범주형 데이터 -> 수치형 변환
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import OneHotEncoder
# Feature Scaling: 수치형 데이터의 스케일 차이를 줄여주는 정규화 도구
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import MinMaxScaler
데이터를 분리하는 도구를 통해 학습용과 테스트용 데이터를 나누는 것도 필수이다.
# 데이터 분리
from sklearn.model_selection import train_test_split
이제 본격적으로 모델을 학습하고, 예측하며, 평가하는 데 필요한 도구들을 불러온다.
# 분류 모델 불러오기
from sklearn.tree import DecisionTreeClassifier # 의사결정나무
from sklearn.ensemble import RandomForestClassifier # 랜덤포레스트
from xgboost import XGBClassifier # XGBoost
# 교차검증 - 성능의 일반화 가능성을 확인할 수 있는 검증 도구
from sklearn.model_selection import KFold, StratifiedKFold, cross_val_scor
# 평가 지표 - 모델의 성능을 다양한 관점에서 평가할 수 있는 지표들
# 정확도, 정밀도, 재현율, f1_score, ROC-AUC 불러오기
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, roc_auc_score
2️⃣ 데이터 구성 함수 정의
이번 단계에서는 유방암 진단 데이터를 불러와 데이터프레임 형태로 변환한 뒤, 학습용과 테스트용 데이터로 분할하는 함수를 정의한다.
def make_dataset():
# 사이킷런에서 유방암 진단 데이터셋 로드
iris = load_breast_cancer()
# 데이터셋을 판다스 DataFrame으로 변환하고, 컬럼 이름 지정
df = pd.DataFrame(iris.data, columns=iris.feature_names)
# target(정답 레이블) 컬럼 추가
df['target'] = iris.target
# 학습용/테스트용 데이터 분리 (test_size=0.5: 절반씩 나눔)
X_train, X_test, y_train, y_test = train_test_split(
df.drop('target', axis=1), # 입력 데이터
df['target'], # 정답 레이블
test_size=0.5, # 테스트 데이터 비율
random_state=1004) # 재현 가능한 결과를 위한 랜덤 시드 고정
return X_train, X_test, y_train, y_test
# 함수 호출하여 학습/테스트 데이터 생성
X_train, X_test, y_train, y_test = make_dataset()

유방암 진단 데이터 셋은 이렇게 DataFrame 형태로 정리되며, target이라는 정답 컬럼도 함께 포함된다.
아래 분할된 데이터의 구조를 확인해 보면, 학습용과 테스트용 데이터가 잘 나누어졌음을 알 수 있다.
X_train.shape, X_test.shape, y_train.shape, y_test.shape

이처럼 데이터를 구성하는 단계는 실습의 기반이 되는 준비 단계로,
앞으로 모델을 학습하고 평가하는 데 필요한 데이터를 마련한다.
3️⃣ 데이터 전처리
머신러닝에서 전처리는 중요한 단계이지만, 모든 데이터에 반드시 동일하게 적용되는 것은 아니다.
데이터의 특성과 분석 목적에 따라, 필요한 전처리만 선택적으로 적용하는 것이 중요하다.
이번 실습에서는 실제 유방암 진단 데이터에 전처리를 적용하진 않았지만,
“어떻게 전처리를 할 수 있는지”를 보여주는 예시 코드를 함께 정리해 보았다.
3.1 범주형 데이터 인코딩
object 타입으로 된 컬럼이 있을 경우, LabelEncoder를 사용해수치형으로 변환하여 매핑한다.
# 레이블 인코딩
cols = df.select_dtypes(include='object').columns
for col in cols:
le = LabelEncoder()
df[col] = le.fit_transform(df[col])
또는 OneHotEncoder로 범주형 컬럼을 이진 벡터로 변환한다.
분석 모델에 따라 인코딩 방식을 선택하여 진행해야 한다.
# 원-핫 인코딩
cols = df.select_dtypes(include='object').columns # 범주형 컬럼 선택
ohe = OneHotEncoder(sparse=False) # 원-핫 인코딩 객체 생성
cat = ohe.fit_transform(df[cols]) # 선택한 컬럼에 원-핫 인코딩 수행
df_cat = pd.DataFrame(cat, columns=ohe.get_feature_names_out()) # DataFrame으로 변환
df = pd.concat([df, df_cat], axis=1) # 원-핫 인코딩된 DataFrame을 기존 DataFrame과 병합
df = df.drop(cols, axis=1) # 기존 범주형 컬럼 삭제(인코딩된 값으로 대체되었기 때문)
# 위의 모든 과정을 Pandas를 통해 간단히 처리하기
df = pd.get_dummies(df) # 단, train과 test 데이터 셋의 컬럼 개수가 달라질 수 있는 점 유의
[참고] Label Encoder vs One Hot Encoder
| 항목 | LabelEncoder | OneHotEncoder |
| 용도 | 범주형 데이터를 숫자(label)로 변환 | 범주형 데이터를 이진 벡터로 변환 |
| 출력 형식 | 정수 (0, 1, 2, ...) | 배열/행렬 (0과 1로 구성된 다차원 벡터) |
| 예시 출력 | ['A', 'B', 'C'] → [0, 1, 2] | ['A', 'B', 'C'] → [[1,0,0], [0,1,0], [0,0,1]] |
| 단점 | 모델이 숫자의 크기를 순서로 오해할 수 있음 | 차원이 늘어나므로 계산 자원이 더 필요함 |
| 라이브러리 | sklearn.preprocessing.LabelEncoder | sklearn.preprocessing.OneHotEncoder |
3.2 수치형 데이터 스케일링
수치형 변수 간 스케일 차이가 클 경우, 모델의 성능에 영향을 줄 수 있다.
이때는 스케일링(정규화 또는 표준화)을 통해 데이터를 균일한 범위로 조정한다.
StandardScaler: 평균 0, 표준편차 1로 데이터를 표준화해 준다.
# 표준화
cols = ['가격', '호수', '칼로리'] # 표준화를 적용할 수치형 컬럼 목록 지정 예시
scaler = StandardScaler() # 표준화 도구 생성 → 평균 0, 표준편차 1로 변환
# fit_transform: 한 번에 학습과 변환을 수행
# 1) fit() → 데이터의 평균과 표준편차 계산 (학습)
# 2) transform() → 해당 값들을 기준으로 데이터 변환 (적용)
df[cols] = scaler.fit_transform(df[cols]) # 표준화 적용 후 원본 DataFrame에 반영
MinMaxScaler: 데이터를 0~1 사이 값으로 변환한다. 범위 제한이 필요한 경우 유용하다.
# 정규화
scaler = MinMaxScaler()
df[cols] = scaler.fit_transform(df[cols])
✅ 전처리 순서에 대한 팁
오늘 실습한 유방암 데이터에는 데이터 전처리를 따로 해주지 않아,
테스트 데이터를 먼저 분리한 후 전처리에 대한 내용을 다루었지만!!
실제 데이터에 전처리를 적용할 때는 보통 전처리를 먼저 수행한 뒤, 그 결과를 기반으로 train/test 데이터를 분리하는 것을 권장한다.
그 이유는 전처리를 따로 하면 학습 데이터 기준으로 평균, 표준편차 등의 기준값이 만들어지고,
테스트 데이터에는 그 기준을 그대로 적용해야 일반화된 평가가 가능하기 때문이다.
⭐️⭐️ 권장 순서 ⭐️⭐️
전체 데이터 → 전처리 → train/test 분할 → 학습/평가
4️⃣ 모델 학습 / 예측 / 평가
전처리와 데이터 분리까지 완료되었다면, 이제 본격적으로 모델을 학습시키고 예측을 수행해 볼 수 있다.
model = DecisionTreeClassifier(random_state=0) # 의사결정나무 모델 정의
model.fit(X_train, y_train) # 학습
pred = model.predict(X_test) # 예측
분류 문제에서는 단순히 맞췄는가뿐 아니라, 어떤 관점에서 얼마나 잘 맞췄는지를 다양한 지표로 평가할 수 있다.
# 평가모듈(실제값, 예측값)
accuracy_score(y_test, pred) # 정확도: 전체 중 맞춘 비율
precision_score(y_test, pred) # 정밀도: 양성 예측 중 실제 양성 비율
recall_score(y_test, pred) # 재현율: 실제 양성 중 맞춘 비율
f1_score(y_test, pred) # f1 score: 정밀도와 재현율의 조화 평균
이진 분류에서는 ROC AUC Score도 중요한 평가 지표입니다.
이는 단순 예측 결과가 아니라, 분류 확률 기반으로 모델의 전체적인 분류 성능을 평가한다.
# roc_auc 평가 사용
pred_proba = model.predict_proba(X_test) # 예측할 때 _proba 로 확률 결과값을 받아오기
roc_auc_score(y_test, pred_proba[:,1]) # pred 결과가 2개라 1개만 지정 [전체, 인덱스1]
이러한 다양한 평가지표들을 활용하면,
단순히 정답률이 높은 모델을 넘어 안정적이고 성능이 좋은 모델을 선택할 수 있게 된다.
[참고] 최적의 파라미터 탐색 - GridSearchCV
모델마다 성능에 영향을 주는 다양한 하이퍼파라미터가 존재한다.
이때 GridSearchCV를 활용하면, 주어진 파라미터 조합을 바탕으로 최적의 모델 설정을 자동으로 탐색할 수 있다.
⚠️ GridSearchCV는 가능한 모든 조합을 탐색하기 때문에, 파라미터 범위가 넓거나 데이터셋이 클 경우 시간이 매우 오래 걸릴 수 있다.
# GridSearchCV: 하이퍼파라미터 튜닝을 위한 도구
from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import RandomForestClassifier # 랜덤 포레스트를 예시로 사용
# 실험할 하이퍼파라미터 조합을 딕셔너리 형태로 정의
# 모델에 따라 하이퍼파라미터는 다름
param_grid = {
'n_estimators': [50, 100, 150], # 트리 개수
'max_depth': [3, 5, 10], # 트리의 최대 깊이
'criterion': ['gini', 'entropy'], # 분할 기준
'min_samples_split': [1, 2, 3, 5, 10], # 내부 노드를 분할하기 위한 최소 샘플 수
'min_samples_leaf': [1, 2, 3, 5, 10] # 리프 노드가 되기 위한 최소 샘플 수
}
# 랜덤포레스트 분류기 객체 생성
model = RandomForestClassifier()
# 그리드서치 객체 생성: 모델, 파라미터 조합, 교차검증 횟수(cv=5)
grid_search = GridSearchCV(model, param_grid, cv=5)
# 학습 데이터를 사용해 그리드서치 수행 (모든 조합 실험)
grid_search.fit(X_train, y_train)
# 가장 성능이 좋았던 파라미터 출력
print("최적 파라미터:", grid_search.best_params_)
# 가장 좋은 파라미터 조합에서의 평균 교차검증 점수 출력
print("최적 모델 성능:", grid_search.best_score_)
💡 정리
이번 글에서는 기본적인 분류 알고리즘을 구현하는 흐름과 코드를 정리해 보았다.
| 단계 | 내용 | 사용 도구/기법 |
| 데이터 불러오기 | 사이킷런 유방암 진단 데이터셋 활용 | load_breast_cancer() |
| 데이터 전처리 | - 범주형: 수치 변환 - 수치형: 스케일 조정 |
LabelEncoder, OneHotEncoder, get_dummies StandardScaler, MinMaxScaler |
| 모델 학습/예측 | 다양한 분류 모델로 학습 및 예측 수행 | DecisionTreeClassifier, RandomForestClassifier, XGBClassifier 등 |
| 성능 평가 | 예측 결과 평가 | accuracy_score, roc_auc_score 등 |
| 모델 최적화 | 하이퍼파라미터 조정 | GridSearchCV |
✎ 마무리
이번 실습에서는 머신러닝의 전체 흐름을 코드로 따라가며
데이터 준비 → 모델 학습 → 예측 → 평가의 과정을 경험해 보았다.
모든 분류 모델을 다루진 않았지만, 대표적인 모델들을 적용해 보고 그들의 성능을 비교하며 기본적인 감을 익힐 수 있었다.
오늘 다룬 내용은 말 그대로 머신러닝의 가장 기초적인 뼈대에 해당하며,
실무에서는 훨씬 더 깊이 있는 데이터 탐색과 정제, 분석이 선행되어야 한다.
또한 단순히 평가지표 1개만 보는 것이 아니라 다양한 평가지표와 교차 검증을 포함한 성능 검증도 거의 필수로 이루어진다.
그렇지만 복잡한 작업은 결국 이 기본 흐름에서 차근차근 확장해 나갈 수 있을 것이고,
지금의 기초 과정을 충분히 이해하고 익히는 것이 앞으로의 학습에 도움이 될 거라 생각한다!🤓
참고 자료
- 모두의 연구소
'데싸 이모저모 > 머신러닝' 카테고리의 다른 글
| 머신러닝 | 파이썬으로 따라가는 분류 실습 - 신용카드 사기 거래 탐지편 (1) | 2025.05.31 |
|---|---|
| 머신러닝 | 분류(Classification) 알고리즘 (2) | 2025.05.29 |
| 머신러닝 | ML의 시작: 사이킷런(Scikit-learn) 활용하기 (1) | 2025.05.28 |
| 머신러닝 | 머신러닝의 흐름 한 장 요약 노트 (1) | 2025.05.27 |