AICE Professional 1번 문제 완전 정복 — Tabular 다중 분류

들어가며: 회귀만 대비하면 안 됩니다

AICE Professional 시험의 1번 Tabular 문제는 회귀(Regression)가 나올 수도 있지만, **다중 분류(Multi-class Classification)**가 출제될 가능성도 충분히 있습니다. 이전 글에서 회귀 문제 풀이를 다뤘으니, 이번에는 다중 분류 유형을 정리합니다.

저는 1, 2번을 만점으로 통과했지만 3번 Image 문제에서 불합격한 경험이 있습니다. 1번은 비교적 접근하기 쉬운 문제이므로, 회귀든 분류든 어떤 유형이 나와도 확실하게 만점을 받아 두는 것이 합격 전략의 핵심입니다.


AICE Professional 시험 구조 (복습)

문제유형배점
1번Tabular (정형 데이터)30점
2번Text (텍스트 데이터)35점
3번Image (이미지 데이터)35점

합격 기준은 80점 이상입니다. 한 문제라도 완전히 틀리면 사실상 불합격이므로, 1번에서 확실하게 30점을 확보해야 합니다.


1번 문제: Tabular 다중 분류 — 출제 유형 분석

예상 문제 형태

수치형 변수 여러 개가 주어지고, 이를 기반으로 3개 이상의 클래스 중 하나를 예측하는 다중 분류 문제가 출제됩니다.

회귀 문제와의 핵심 차이점은 다음과 같습니다.

  • target 컬럼이 연속 수치가 아니라 범주형 라벨(문자열 또는 정수)입니다
  • 평가 지표가 RMSE가 아니라 Accuracy, F1-score 등 분류 지표입니다
  • 라벨이 문자열일 경우 LabelEncoder로 인코딩이 필요합니다
  • 제출 시 예측값을 원래 라벨명으로 복원해야 합니다

회귀 vs 다중 분류 — 차이점 한눈에 보기

시험장에서 데이터를 열었을 때, target 컬럼을 보고 바로 판단해야 합니다.

항목회귀다중 분류
target 형태연속 수치 (예: 151.0, 200.5)범주형 (예: ‘cat’, ‘dog’, ‘bird’)
모델RandomForestRegressorRandomForestClassifier
평가 지표RMSEAccuracy, F1-score
라벨 처리불필요LabelEncoder 필요 (문자열 라벨 시)
제출 값예측 수치 그대로원래 라벨명으로 복원

풀이 전략: 6단계 접근법

Step 1. 데이터 로드 및 기본 설정

python

import pandas as pd
import numpy as np
from pathlib import Path

from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import (
    accuracy_score, f1_score, classification_report,
    confusion_matrix, roc_auc_score
)
from sklearn.preprocessing import LabelEncoder, label_binarize
import joblib

# ── 경로 설정 ──
DATA_DIR = Path('/content/drive/MyDrive/Colab Notebooks/data')
TRAIN_CSV = DATA_DIR / '01_train.csv'
TEST_CSV  = DATA_DIR / '01_test_x.csv'

# ── 제출 파일 설정 ──
PHONE = '01012345678'              # 본인 전화번호로 변경
OUT_CSV = DATA_DIR / f'{PHONE}_1.csv'
OUT_PKL = DATA_DIR / f'{PHONE}_1.pkl'

TARGET_COL = 'label'               # 문제에서 제시하는 타겟 컬럼명으로 변경
ID_COL = 'id'                      # ID 컬럼이 있는 경우

# ── 데이터 로드 ──
train = pd.read_csv(TRAIN_CSV)
test  = pd.read_csv(TEST_CSV)

Step 2. 전처리 및 라벨 인코딩

python

# X, y 분리
y_raw = train[TARGET_COL].values     # 문자열 라벨일 수 있음
X = train.drop(columns=[TARGET_COL])

# 결측치 안전장치
if X.isnull().any().any():
    X = X.fillna(X.mean(numeric_only=True))
if test.isnull().any().any():
    test = test.fillna(test.mean(numeric_only=True))

# 라벨 인코딩: 문자열 라벨 → 정수
lbl = LabelEncoder()
y = lbl.fit_transform(y_raw)          # 예: ['cat','dog','bird'] → [0, 1, 2]
class_names = list(lbl.classes_)       # 나중에 원복할 때 사용
print("클래스:", class_names)

회귀 문제에서는 필요 없었던 LabelEncoder가 다중 분류에서는 핵심입니다. 라벨이 이미 정수(0, 1, 2)로 되어 있더라도 LabelEncoder를 적용해 두면, 나중에 inverse_transform()으로 안전하게 원복할 수 있어 실수를 줄일 수 있습니다.

팁: class_names를 반드시 출력해서 확인하세요. 제출 시 이 이름들이 그대로 CSV에 들어갑니다. 오타나 대소문자 차이가 있으면 채점에서 틀릴 수 있습니다.

Step 3. 검증 데이터 분리

python

X_tr, X_va, y_tr, y_va = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)

회귀와 다른 점이 하나 있습니다. stratify=y를 반드시 추가하세요. 다중 분류에서 stratify 없이 분리하면, 특정 클래스가 검증 세트에 아예 빠지거나 비율이 크게 왜곡될 수 있습니다. stratify를 지정하면 원본 데이터의 클래스 비율이 train/validation에 동일하게 유지됩니다.

Step 4. 모델 학습 및 검증

python

clf = RandomForestClassifier(
    n_estimators=500,
    max_depth=None,
    min_samples_leaf=2,
    n_jobs=-1,
    random_state=42
)

# 학습
clf.fit(X_tr, y_tr)

# 예측
va_pred  = clf.predict(X_va)
va_proba = clf.predict_proba(X_va)

# ── 평가 지표 ──
acc = accuracy_score(y_va, va_pred)
f1_macro = f1_score(y_va, va_pred, average='macro')
f1_weighted = f1_score(y_va, va_pred, average='weighted')

print(f'Validation Accuracy     : {acc:.4f}')
print(f'Validation F1 (macro)   : {f1_macro:.4f}')
print(f'Validation F1 (weighted): {f1_weighted:.4f}')

# 클래스별 상세 리포트
print('\nClassification Report:\n',
      classification_report(y_va, va_pred, target_names=class_names))
print('Confusion Matrix:\n', confusion_matrix(y_va, va_pred))

다중 분류에서 확인해야 할 지표를 정리하면 이렇습니다.

지표의미언제 중요한가
Accuracy전체 정답 비율클래스가 균등할 때
F1 (macro)클래스별 F1의 단순 평균클래스 불균형이 있을 때
F1 (weighted)클래스별 F1의 가중 평균다수 클래스 성능도 중요할 때

문제에서 어떤 지표를 기준으로 평가하는지 반드시 확인하세요. 지표에 따라 튜닝 방향이 달라집니다.

(선택) 다중 클래스 ROC-AUC 계산

문제에서 AUC를 요구하는 경우에 대비해, 계산 방법도 알아 두면 좋습니다.

python

if len(class_names) > 2:
    y_va_bin = label_binarize(y_va, classes=clf.classes_)
    auc_macro = roc_auc_score(
        y_va_bin, va_proba, average='macro', multi_class='ovr'
    )
    print(f'Validation ROC-AUC (macro, OVR): {auc_macro:.4f}')

여기서 주의할 점은, predict_proba()의 열 순서가 clf.classes_와 동일하다는 것입니다. label_binarize()에도 같은 classes 순서를 넘겨줘야 확률과 라벨이 올바르게 매칭됩니다.

Step 5. 최종 학습 및 테스트 예측

python

# 전체 데이터로 최종 학습
clf.fit(X, y)

# 테스트 예측
test_pred_int = clf.predict(test)
test_pred_lbl = lbl.inverse_transform(test_pred_int)  # 원래 라벨명으로 복원

inverse_transform()을 잊지 마세요. 모델이 예측한 값은 정수(0, 1, 2)이지만, 제출 파일에는 원래 라벨명(‘cat’, ‘dog’, ‘bird’)을 넣어야 합니다. 이 변환을 빠뜨리고 정수를 그대로 제출하면 채점에서 틀릴 수 있습니다.

Step 6. 제출 파일 저장

python

# CSV 저장
if ID_COL in test.columns:
    sub = pd.DataFrame({ID_COL: test[ID_COL], TARGET_COL: test_pred_lbl})
else:
    sub = pd.DataFrame({'id': np.arange(len(test)), TARGET_COL: test_pred_lbl})

sub.to_csv(OUT_CSV, index=False)
print(f'Wrote: {OUT_CSV}')

# 모델 저장
joblib.dump(clf, OUT_PKL)
print(f'Wrote: {OUT_PKL}')

주의: 제출 CSV의 컬럼명과 라벨 포맷은 문제마다 다를 수 있습니다. 정수를 요구하는지, 문자열 클래스명을 요구하는지 문제 지시사항을 꼼꼼히 읽으세요.


성능이 안 나올 때 — 간단 튜닝 가이드

우선순위조정 항목방법기대 효과
1n_estimators500 → 800 → 1000트리 수 증가로 안정성 향상
2min_samples_leaf2 → 1 → 4과적합/과소적합 균형 조절
3max_depthNone → 20 → 12트리 깊이 제한으로 일반화
4class_weight'balanced' 추가클래스 불균형 대응
5max_features1.0 → 0.7 → ‘sqrt’각 트리가 보는 변수 비율 축소

클래스 불균형이 심한 경우, class_weight='balanced'를 추가하면 소수 클래스에 더 높은 가중치를 부여해서 성능이 개선될 수 있습니다. 이 한 줄 추가만으로 F1 (macro)가 크게 오르는 경우가 있으니, 반드시 시도해 보세요.

python

clf = RandomForestClassifier(
    n_estimators=500,
    max_depth=None,
    min_samples_leaf=2,
    class_weight='balanced',       # 이 한 줄 추가
    n_jobs=-1,
    random_state=42
)

실전 체크리스트

시험장에서 제출 전, 이 순서대로 확인하세요.

  1. target 컬럼을 확인했는가? (연속 수치 → 회귀, 범주형 → 분류)
  2. LabelEncoder로 라벨을 인코딩했는가?
  3. train_test_splitstratify=y를 넣었는가?
  4. 검증 Accuracy/F1이 문제에서 요구하는 기준을 넘겼는가?
  5. 최종 학습은 전체 데이터로 했는가?
  6. inverse_transform()으로 예측값을 원래 라벨명으로 복원했는가?
  7. 제출 CSV의 컬럼명과 라벨 포맷이 문제 요구사항과 일치하는가?
  8. pkl 파일이 정상 저장되었는가?

마무리

1번 Tabular 문제는 회귀든 다중 분류든, RandomForest 하나로 충분히 만점을 노릴 수 있는 문제입니다. 다만 분류 문제가 나왔을 때 당황하지 않으려면, 회귀와의 차이점을 명확히 알아 두어야 합니다.

핵심을 세 가지로 요약하면 이렇습니다. LabelEncoder로 인코딩하고, stratify로 분리하고, inverse_transform으로 복원하세요. 이 세 단계만 빠뜨리지 않으면 30점은 확보할 수 있습니다.

관련 글 보기

  • AICE Professional 1번 문제 완전 정복 — Tabular 회귀

    AICE Professional 시험 1번 Tabular 회귀 문제 풀이법을 실전 경험을 바탕으로 정리했습니다. RandomForestRegressor로 RMSE 83 이하를 달성하는 5단계 접근법, 하이퍼파라미터 튜닝 가이드, 제출 시 주의사항까지 한 번에 확인하세요. 시험 준비에 실질적으로 도움이 되는 코드와 체크리스트를 제공합니다.

  • AICE Professional 3번 문제 완전 정복 — Image 다중 분류

    AICE Professional 시험 3번 Image 다중 분류 문제 풀이법을 실전 경험을 바탕으로 정리했습니다. MobileNetV2 전이학습과 2단계 파인튜닝으로 접근하는 8단계 풀이 전략, 이진 분류와 다중 분류의 핵심 차이점, 제출 시 주의사항까지 코드와 체크리스트로 한 번에 확인하세요.

  • AICE Professional 3번 문제 완전 정복 — Image 이진 분류

    AICE Professional 시험 3번 Image 이진 분류 문제를 실전 경험과 실패 분석을 바탕으로 정리했습니다. MobileNetV2 전이학습, 2단계 파인튜닝, 전처리 일관성 확보까지 7단계 풀이 전략과 실전 체크리스트를 코드와 함께 제공합니다. Accuracy 95% 달성을 위한 튜닝 가이드도 포함되어 있습니다.

  • AICE Professional 2번 문제 완전 정복 — Text 이진 분류

    AICE Professional 시험 2번 Text 이진 분류 문제 풀이법을 실전 만점 경험을 바탕으로 정리했습니다. 다중 분류 코드에서 출력층, 손실 함수, 예측 후처리 네 군데만 변경하면 됩니다. sigmoid 출력 처리, 임계값 설정, ravel() 주의사항까지 코드와 체크리스트로 확인하세요.

  • AICE Professional 2번 문제 완전 정복 — Text 다중 분류

    AICE Professional 시험 2번 Text 다중 분류 문제 풀이법을 실전 만점 경험을 바탕으로 정리했습니다. 텍스트 전처리, Tokenizer 사용법, Embedding + BiLSTM 모델 구성, 시퀀스 패딩까지 8단계 접근법을 코드와 함께 상세히 설명합니다. 튜닝 가이드와 실전 체크리스트도 포함되어 있습니다.

  • AICE Professional 1번 문제 완전 정복 — Tabular 이진 분류

    AICE Professional 시험 1번 Tabular 이진 분류 문제 풀이법을 실전 경험을 바탕으로 정리했습니다. RandomForestClassifier를 활용한 6단계 접근법, 회귀·이진·다중 분류 유형별 비교표, ROC-AUC 계산 시 주의사항, 클래스 불균형 대응 튜닝 가이드까지 코드와 체크리스트로 확인하세요.