빅데이터 분석기사 실기 2유형 (1) — 분류 모델링 완전정리
배점 40점의 핵심, 2유형 분류 문제 풀이 흐름. 전처리부터 모델 학습, 평가, 제출 csv까지 한 번에.
2유형은 배점이 40점. 합격(60점)을 위한 사실상의 메인 시험이다. 분류든 회귀든 풀이 흐름은 똑같다. 흐름을 외워라.
2유형은 어떤 시험인가?
| 항목 | 내용 |
|---|---|
| 배점 | 40점 (단일 문제) |
| 형식 | 머신러닝 모델 구축 → 테스트 데이터 예측 → CSV 저장 |
| 시간 권장 | 약 1시간 30분 |
| 출제 유형 | 이진 분류, 다중 분류, 회귀 (회귀는 다음 글) |
이번 글은 분류(Classification) 만 다룬다. 회귀는 (2)에서.
2유형 풀이 7단계 — 외워서 그대로 따라간다
1. 데이터 불러오기
2. 데이터 탐색 (shape, info, describe)
3. 전처리 (결측치, 인코딩, 스케일링)
4. train / validation 분리
5. 모델 학습
6. 검증 성능 확인
7. test 예측 → submission.csv 저장
이 7단계는 분류/회귀 공통 뼈대다. 문제마다 바뀌는 건 데이터·평가지표·모델 정도다.
시험장 코드 템플릿 (분류)
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import roc_auc_score, accuracy_score, f1_score
# 1. 데이터 로드
X_train = pd.read_csv("X_train.csv")
y_train = pd.read_csv("y_train.csv")
X_test = pd.read_csv("X_test.csv")
# 2. 빠른 확인
print(X_train.shape, X_test.shape, y_train.shape)
print(X_train.info())
print(y_train.value_counts()) # 클래스 불균형 확인
# 3. ID 컬럼 분리 (제출용으로 보관)
test_id = X_test["ID"]
X_train = X_train.drop(columns=["ID"])
X_test = X_test.drop(columns=["ID"])
y_train = y_train["target"] # 또는 y_train.iloc[:, -1]
첫 30분은 무조건 데이터 구조 파악과 전처리에 쓴다. 모델은 마지막에 한 줄이면 끝난다.
전처리 — 시험에서 꼭 챙길 것
결측치 처리
# 수치형 → 중앙값, 범주형 → 최빈값이 가장 무난한 디폴트
num_cols = X_train.select_dtypes(include="number").columns
cat_cols = X_train.select_dtypes(include="object").columns
for c in num_cols:
median = X_train[c].median()
X_train[c] = X_train[c].fillna(median)
X_test[c] = X_test[c].fillna(median) # test도 train 기준으로
for c in cat_cols:
mode = X_train[c].mode()[0]
X_train[c] = X_train[c].fillna(mode)
X_test[c] = X_test[c].fillna(mode)
반드시 train 기준으로 test도 채워야 한다. test의 median으로 test를 채우면 데이터 누수다.
범주형 인코딩
# 가장 안전한 방식: pd.get_dummies 합쳐서 처리
all_df = pd.concat([X_train, X_test], axis=0)
all_df = pd.get_dummies(all_df, columns=cat_cols)
X_train = all_df.iloc[:len(X_train)]
X_test = all_df.iloc[len(X_train):]
train과 test에 같은 범주가 안 나올 수 있어서, 합쳐서 인코딩하고 다시 자르는 패턴이 가장 안전하다.
스케일링 (필요할 때만)
랜덤포레스트·XGBoost 같은 트리 계열은 스케일링이 필요 없다. 시간 아끼려면 생략한다. 로지스틱 회귀·SVM·KNN을 쓸 때만 적용.
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_train_s = scaler.fit_transform(X_train)
X_test_s = scaler.transform(X_test) # transform만! fit 다시 하면 안 됨
모델 선택 — 시험에서는 단순하게
| 모델 | 장점 | 시험 추천도 |
|---|---|---|
| RandomForest | 전처리 거의 불필요, 안정적 | ★★★★★ |
| XGBoost / LightGBM | 보통 가장 높은 성능 | ★★★★☆ |
| LogisticRegression | 빠름, 베이스라인용 | ★★★ |
| KNN, SVM | 느리고 스케일링 필수 | ★ |
합격선 기준으로는 RandomForest 디폴트 파라미터만 써도 충분히 점수가 나온다. 시간이 남으면 XGBoost로 살짝 끌어올린다.
RandomForest 기본 사용
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import roc_auc_score
X_tr, X_val, y_tr, y_val = train_test_split(
X_train, y_train, test_size=0.2,
random_state=42, stratify=y_train # 분류는 stratify 필수
)
model = RandomForestClassifier(
n_estimators=300,
max_depth=10,
random_state=42,
n_jobs=-1,
)
model.fit(X_tr, y_tr)
# 검증
val_pred_prob = model.predict_proba(X_val)[:, 1]
val_pred = model.predict(X_val)
print("AUC:", roc_auc_score(y_val, val_pred_prob))
print("ACC:", accuracy_score(y_val, val_pred))
평가지표 — 문제에서 시키는 걸 그대로
| 문제 표현 | 사용 함수 | 모델 출력 |
|---|---|---|
| "정확도(accuracy)" | accuracy_score |
predict |
| "F1 점수" | f1_score |
predict |
| "AUC / ROC AUC" | roc_auc_score |
predict_proba |
| "확률값으로 제출" | — | predict_proba |
AUC를 요구하면
predict_proba, 정확도를 요구하면predict. 헷갈리면 점수 통째로 날아간다.
from sklearn.metrics import (
accuracy_score, f1_score, roc_auc_score,
confusion_matrix, classification_report,
)
제출 CSV 만들기 — 형식이 곧 점수
문제마다 제출 형식이 정확히 지정된다. 컬럼명, 순서, 값 형태를 그대로 따라야 한다.
일반적인 두 가지 형식
# 형식 A. 예측 클래스(0/1)로 제출
pred = model.predict(X_test)
submission = pd.DataFrame({
"ID": test_id,
"pred": pred,
})
submission.to_csv("result.csv", index=False)
# 형식 B. 클래스 1의 확률로 제출 (AUC 평가)
pred_prob = model.predict_proba(X_test)[:, 1]
submission = pd.DataFrame({
"ID": test_id,
"pred": pred_prob,
})
submission.to_csv("result.csv", index=False)
index=False반드시. 안 붙이면 맨 앞에 인덱스 컬럼이 추가돼 채점기가 못 읽는다.
XGBoost로 한 단계 올리기 (시간 남을 때)
from xgboost import XGBClassifier
model = XGBClassifier(
n_estimators=500,
max_depth=6,
learning_rate=0.05,
random_state=42,
use_label_encoder=False,
eval_metric="logloss",
)
model.fit(X_tr, y_tr)
prob = model.predict_proba(X_val)[:, 1]
print("AUC:", roc_auc_score(y_val, prob))
LightGBM도 인터페이스가 거의 동일하다 (LGBMClassifier).
클래스 불균형 대응
y.value_counts()로 봤을 때 9:1 이상으로 한쪽이 적으면 대응이 필요하다.
# RandomForest
RandomForestClassifier(class_weight="balanced")
# XGBoost (양성/음성 비율)
neg, pos = (y_train == 0).sum(), (y_train == 1).sum()
XGBClassifier(scale_pos_weight=neg/pos)
단, AUC는 불균형에 비교적 강하므로 시험에서 굳이 안 건드려도 점수는 잘 나온다. 시간 부족하면 패스.
시험장 흐름 요약 (실전 시뮬레이션)
00:00 데이터 3개 read_csv, shape/info 확인 (5분)
00:05 ID 보관, 결측치 처리, 인코딩 (15분)
00:20 train_test_split, RandomForest 학습 (10분)
00:30 검증 점수 확인, 만족스러우면 그대로 제출 (5분)
00:35 여유 있으면 XGBoost로 한 번 더, 점수 비교 (15분)
00:50 제출 csv 저장, 컬럼명·index=False 다시 확인 (5분)
00:55 3유형으로 넘어감
정리
- 흐름이 곧 점수다. 7단계를 외워서 흔들리지 말 것.
- 트리 계열(RandomForest, XGBoost) 만 손에 익혀도 충분히 합격선이 나온다.
- 평가지표가 AUC면 predict_proba, 정확도면
predict. - 제출 CSV의 컬럼명·순서·
index=False는 답안의 마지막 안전장치.
다음 글에서는 같은 흐름을 회귀(Regression) 문제에 그대로 적용하는 법을 다룬다. RMSE, R², 평가지표만 바뀌고 뼈대는 99% 동일하다.