빅데이터 분석기사 실기 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유형으로 넘어감

정리

  1. 흐름이 곧 점수다. 7단계를 외워서 흔들리지 말 것.
  2. 트리 계열(RandomForest, XGBoost) 만 손에 익혀도 충분히 합격선이 나온다.
  3. 평가지표가 AUC면 predict_proba, 정확도면 predict.
  4. 제출 CSV의 컬럼명·순서·index=False 는 답안의 마지막 안전장치.

다음 글에서는 같은 흐름을 회귀(Regression) 문제에 그대로 적용하는 법을 다룬다. RMSE, R², 평가지표만 바뀌고 뼈대는 99% 동일하다.