011 첫 번째 분류 모델 만들기
키워드: 분류, 첫 번째 모델
개요
이제 FLAML의 기본 개념을 배웠으니, 실제 데이터로 첫 번째 분류 모델을 만들어 보겠습니다. 유방암 진단 데이터세트를 사용해 악성/양성을 분류하는 모델을 처음부터 끝까지 구현합니다.
실습 환경
- Python 버전: 3.11 권장
- 필요 패키지:
flaml[automl], pandas, scikit-learn, matplotlib
pip install flaml[automl] pandas scikit-learn matplotlib
프로젝트 개요
목표
유방암 세포의 특성을 기반으로 악성(malignant) 또는 양성(benign)을 분류
데이터세트
- 이름: Wisconsin Breast Cancer Dataset
- 샘플 수: 569개
- 특성 수: 30개 (세포 핵의 특성)
- 타겟: 0(악성), 1(양성)
Step 1: 라이브러리 임포트
# 011 필수 라이브러리
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 011 FLAML
from flaml import AutoML
# 011 scikit-learn
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.metrics import (
accuracy_score,
classification_report,
confusion_matrix,
roc_auc_score,
roc_curve
)
# 011 경고 무시 (선택)
import warnings
warnings.filterwarnings('ignore')
print("라이브러리 로드 완료!")
Step 2: 데이터 로드 및 탐색
# 011 데이터 로드
data = load_breast_cancer()
# 011 DataFrame으로 변환
df = pd.DataFrame(data.data, columns=data.feature_names)
df['target'] = data.target
# 011 기본 정보 확인
print("="*60)
print("데이터 기본 정보")
print("="*60)
print(f"데이터 크기: {df.shape}")
print(f"\n컬럼 목록:")
for i, col in enumerate(df.columns, 1):
print(f" {i:2d}. {col}")
실행 결과
============================================================
데이터 기본 정보
============================================================
데이터 크기: (569, 31)
컬럼 목록:
1. mean radius
2. mean texture
3. mean perimeter
...
31. target
타겟 분포 확인
print("\n타겟 분포:")
print(df['target'].value_counts())
print(f"\n클래스 비율:")
print(f" 양성(1): {(df['target']==1).mean()*100:.1f}%")
print(f" 악성(0): {(df['target']==0).mean()*100:.1f}%")
실행 결과
타겟 분포:
1 357
0 212
Name: target, dtype: int64
클래스 비율:
양성(1): 62.7%
악성(0): 37.3%
기초 통계량
print("\n기초 통계량 (일부 컬럼):")
print(df[['mean radius', 'mean texture', 'mean perimeter', 'target']].describe())
Step 3: 데이터 전처리
# 011 특성(X)과 타겟(y) 분리
X = df.drop('target', axis=1)
y = df['target']
# 011 결측치 확인
print("결측치 확인:")
print(f" 총 결측치: {X.isnull().sum().sum()}")
# 011 데이터 분할 (80% 학습, 20% 테스트)
X_train, X_test, y_train, y_test = train_test_split(
X, y,
test_size=0.2,
random_state=42,
stratify=y # 클래스 비율 유지
)
print(f"\n데이터 분할 완료:")
print(f" 학습 데이터: {X_train.shape[0]}개")
print(f" 테스트 데이터: {X_test.shape[0]}개")
실행 결과
결측치 확인:
총 결측치: 0
데이터 분할 완료:
학습 데이터: 455개
테스트 데이터: 114개
Step 4: FLAML AutoML 실행
# 011 AutoML 객체 생성
automl = AutoML()
# 011 설정
settings = {
"task": "classification",
"time_budget": 60, # 60초
"metric": "accuracy",
"estimator_list": ["lgbm", "xgboost", "rf", "extra_tree"],
"seed": 42,
"verbose": 1
}
print("="*60)
print("FLAML AutoML 학습 시작")
print("="*60)
print(f"시간 예산: {settings['time_budget']}초")
print(f"최적화 지표: {settings['metric']}")
print(f"탐색 모델: {settings['estimator_list']}")
print()
# 011 학습 실행
automl.fit(X_train, y_train, **settings)
실행 결과
============================================================
FLAML AutoML 학습 시작
============================================================
시간 예산: 60초
최적화 지표: accuracy
탐색 모델: ['lgbm', 'xgboost', 'rf', 'extra_tree']
[flaml.automl.logger: INFO] Iteration 1, current learner lgbm
[flaml.automl.logger: INFO] at 0.3s, best lgbm's error=0.0330, ...
[flaml.automl.logger: INFO] Iteration 2, current learner lgbm
[flaml.automl.logger: INFO] at 0.4s, best lgbm's error=0.0308, ...
...
[flaml.automl.logger: INFO] retrain lgbm for 0.1s
[flaml.automl.logger: INFO] Best ML model: lgbm
Step 5: 학습 결과 확인
print("="*60)
print("학습 결과")
print("="*60)
# 011 최적 모델
print(f"최적 모델: {automl.best_estimator}")
# 011 최적 하이퍼파라미터
print(f"\n최적 하이퍼파라미터:")
for key, value in automl.best_config.items():
print(f" {key}: {value}")
# 011 검증 점수
print(f"\n검증 정확도: {1 - automl.best_loss:.4f}")
실행 결과
============================================================
학습 결과
============================================================
최적 모델: lgbm
최적 하이퍼파라미터:
n_estimators: 63
num_leaves: 4
min_child_samples: 7
learning_rate: 0.2677
log_max_bin: 8
colsample_bytree: 0.9867
reg_alpha: 0.0009
reg_lambda: 0.0087
검증 정확도: 0.9714
Step 6: 테스트 세트 평가
# 011 예측
y_pred = automl.predict(X_test)
y_prob = automl.predict_proba(X_test)[:, 1]
print("="*60)
print("테스트 세트 평가")
print("="*60)
# 011 정확도
accuracy = accuracy_score(y_test, y_pred)
print(f"정확도: {accuracy:.4f}")
# 011 ROC AUC
roc_auc = roc_auc_score(y_test, y_prob)
print(f"ROC AUC: {roc_auc:.4f}")
# 011 분류 리포트
print(f"\n분류 리포트:")
print(classification_report(y_test, y_pred,
target_names=['악성', '양성']))
실행 결과
============================================================
테스트 세트 평가
============================================================
정확도: 0.9737
ROC AUC: 0.9967
분류 리포트:
precision recall f1-score support
악성 0.98 0.95 0.96 43
양성 0.97 0.99 0.98 71
accuracy 0.97 114
macro avg 0.97 0.97 0.97 114
weighted avg 0.97 0.97 0.97 114
Step 7: 결과 시각화
혼동 행렬
# 011 혼동 행렬
cm = confusion_matrix(y_test, y_pred)
plt.figure(figsize=(8, 6))
plt.imshow(cm, interpolation='nearest', cmap=plt.cm.Blues)
plt.title('Confusion Matrix')
plt.colorbar()
classes = ['악성', '양성']
tick_marks = np.arange(len(classes))
plt.xticks(tick_marks, classes)
plt.yticks(tick_marks, classes)
# 011 숫자 표시
for i in range(cm.shape[0]):
for j in range(cm.shape[1]):
plt.text(j, i, format(cm[i, j], 'd'),
ha="center", va="center", fontsize=20,
color="white" if cm[i, j] > cm.max()/2 else "black")
plt.xlabel('예측')
plt.ylabel('실제')
plt.tight_layout()
plt.savefig('confusion_matrix.png', dpi=100)
plt.show()
ROC 곡선
# 011 ROC 곡선
fpr, tpr, _ = roc_curve(y_test, y_prob)
plt.figure(figsize=(8, 6))
plt.plot(fpr, tpr, color='blue', lw=2, label=f'ROC curve (AUC = {roc_auc:.4f})')
plt.plot([0, 1], [0, 1], color='gray', lw=1, linestyle='--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('ROC Curve')
plt.legend(loc="lower right")
plt.tight_layout()
plt.savefig('roc_curve.png', dpi=100)
plt.show()
Step 8: 모델 저장
import pickle
# 011 모델 저장
model_path = 'breast_cancer_classifier.pkl'
with open(model_path, 'wb') as f:
pickle.dump(automl, f)
print(f"모델 저장 완료: {model_path}")
# 011 저장된 모델 테스트
with open(model_path, 'rb') as f:
loaded_model = pickle.load(f)
test_accuracy = accuracy_score(y_test, loaded_model.predict(X_test))
print(f"불러온 모델 정확도: {test_accuracy:.4f}")
전체 코드 (복사용)
"""
FLAML 첫 번째 분류 모델 - 유방암 진단
"""
import pandas as pd
import numpy as np
from flaml import AutoML
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, classification_report, roc_auc_score
import pickle
# 1. 데이터 로드
data = load_breast_cancer()
X, y = data.data, data.target
# 2. 데이터 분할
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
# 3. FLAML 학습
automl = AutoML()
automl.fit(
X_train, y_train,
task="classification",
time_budget=60,
metric="accuracy",
seed=42
)
# 4. 평가
y_pred = automl.predict(X_test)
print(f"최적 모델: {automl.best_estimator}")
print(f"정확도: {accuracy_score(y_test, y_pred):.4f}")
print(classification_report(y_test, y_pred, target_names=['악성', '양성']))
# 5. 저장
with open('model.pkl', 'wb') as f:
pickle.dump(automl, f)
정리
- 유방암 데이터세트로 분류 모델을 만들었습니다.
- FLAML이 60초 내에 lgbm을 최적 모델로 선택했습니다.
- 테스트 정확도 97.37%, ROC AUC 0.9967을 달성했습니다.
- 모델을 pickle로 저장하여 재사용할 수 있습니다.
다음 글 예고
다음 글에서는 첫 번째 회귀 모델 만들기에 대해 알아보겠습니다. 당뇨병 데이터세트를 사용해 회귀 문제를 해결합니다.
FLAML AutoML 마스터 시리즈 #011