빅데이터분석기사

빅분기 실기 작업형2 정리

_jju 2026. 5. 17. 14:27

빅데이터분석기사 실기 작업형2 문제는 데이터셋이 csv파일로 주어지고, 데이터 전처리하고, 모델 학습시키고 하이퍼 파라미터 튜닝 등 해서 test데이터에 대해 예측값 생성하고 파일로 저장하는 머신러닝 문제이다. 여기서 전처리를 어떻게 하냐에 따라서, 어떤 모델을 선택하냐에 따라서, 하이퍼파라미터튜닝을 어떻게 하냐에 따라서 예측 성능이 달라지는데 이 예측 성능에 따라 점수를 매긴다고 한다.

 

졸업작품.. 넥스원 산학협력 과제... 이런거 할 때 항상 파이썬으로 했어서 모델학습 코드가 익숙하긴 하지만 이제 모든 라이브러리랑 함수를 다 외워서 써야해!


먼저 대략적으로 순서를 읊어보자면,

  1. EDA (탐색적데이터분석)
  2. 데이터전처리, 피처엔지니어링
    결측치, 이상치 처리
    인코딩
    스케일링
  3.  검증데이터 분리
  4. 모델학습
  5. 모델평가
  6. 가장 좋은 결과를 내는 모델을 찾을 때까지 4, 5번 반복
  7. 그 모델로 test집합 예측, csv파일로 만들기

이렇게 되겠다.


1st. EDA (탐색적데이터분석)

이 단계에서 하는건 말그대로 데이터를 분석하는 것이다. 칼럼의 수는 몇개인지, 데이터의 크기가 어떤지, 데이터 타입은 어떻게 되는지, 결측치가 있는지, 이상치가 있는지 등을 파악해야 데이터 전처리 단계에서 뭘할지 정할 수 있기 때문이다. 

# 데이터의 상위 5개 행을 출력해서 실제 데이터 형태 확인
train.head()

# 컬럼명, 데이터 타입, 결측치 개수 등 전체 구조 확인
train.info()

# 숫자형 컬럼들의 기초 통계량(평균, 표준편차, 최소/최대값 등) 확인
train.describe()
# 문자형 컬럼들의 데이터 통계 확인
train.describe(include="O")

# 각 컬럼별 결측치(NaN) 개수 확인
train.isnull().sum()
train.isna().sum()

# 특정 컬럼의 값들이 각각 몇 개씩 존재하는지 확인
train['컬럼명'].value_counts()

위의 함수들로 데이터 분석을 진행할 수 있다. 

 

이 단계에서 판단할 수 있는 것은,

  • 타겟에 영향을 안미치는 쓸데 없는 칼럼(예를 들어 뭐 회원ID라든가)이 있네? -> drop해야겠다.
  • unique값이 너무 커서 거의 count에 준하네? -> drop해야겠다. 
  • 문자형 데이터인데 unique값이 꽤 크네? -> 원핫인코딩하면 칼럼 너무 많아지겠다. 라벨인코딩 해야겠다. 
  • 결측치, 이상치가 있네? -> 얘네 처리해야겠다. 
  • 스케일링 해줘야 할 변수가 있는데 최대값 혹은 최솟값이 이상치라서 다른 값들이랑 너무 큰 차이가 나네? -> MinMaxScaler로 스케일링하면 일반적인 값들이 0.00023 이런식으로 너무 작아지거나 0.9998 이런식으로 너무 커지게 되니까 Standard Scaler 사용해야겠다. 

이정도가 되겠다.


2nd. 데이터 전처리 및 피처 엔지니어링

모델을 학습시킬 train데이터도, 모델에 넣어볼 test데이터도 모두 전처리 해줘야한다. 

전처리가 끝나고나면 train데이터의 결측치, test데이터읙 결측치가 모두 채워져있어야 하고 칼럼의 변동이 있었다면 test에서도 같은 변동이 있어야 했을 것!

 

1. 필요없는 칼럼 삭제

# 1. 제출에 필요하다면 없애기 전에 따로 저장해놔야 한다.
test_id = X_test['ID']

# 2. axis 안적으면 행에서 찾게 된다. 적어서 칼럼임을 명시!
X_train = X_train.drop('ID', axis=1)
X_test = X_test.drop('ID', axis=1)

 

2. 결측치 처리

# 수치형 변수의 결측치를 중앙값으로 대체
# train의 중앙값으로 test까지 채워야 함!!!!!!!
median_val = X_train['수치형컬럼'].median()
X_train['수치형컬럼'] = X_train['수치형컬럼'].fillna(median_val)
X_test['수치형컬럼'] = X_test['수치형컬럼'].fillna(median_val)

# 범주형 변수의 결측치를 최빈값으로 대체
mode_val = X_train['범주형컬럼'].mode()[0]
X_train['범주형컬럼'] = X_train['범주형컬럼'].fillna(mode_val)
X_test['범주형컬럼'] = X_test['범주형컬럼'].fillna(mode_val)

물론 수치형을 중앙값 말고 최빈값으로 채울 수도 있고 평균값으로 채울 수도 있다. 크게 달라지지 않을 것 같지만 mode, mean으로 바꿔서 다시 학습시켜보고 최적의 경우를 제출하는게 좋긴하겠다.

 

mode() 함수는 시리즈를 뱉는다. 시리즈 형태를 그대로 fillna에 넣게 되면 두 시리즈의 인덱스를 맞춰서 넣도록 동작하게 된다. 우리가 원하는건 그냥 str을 null자리에 넣는 것이기에, str형태로 만들어주기 위해서 mode()[0]를 붙이는 것!!!

 

그리고 절대 test의 데이터로 test의 데이터를 전처리 하면 안된다!!! train의 데이터로 test를 전처리해야한다. 모델은 train의 데이터로 학습하고 예측하기에, test데이터의 결측치가 train데이터의 결측치와 같은 값으로 채워져있어야 모델이 학습된 값을 뱉게 된다. 

 

# train데이터에만 이상치가 약간 있고 test데이터에는 이상치가 없는 경우
# train데이터에서 몇개 행은 버린다 생각하고 drop해도 된다!

train = train.dropna()

train데이터에만 이상치가 몇개 있고 test데이터에는 없을 경우에는, train데이터에서 결측치 있는 몇개 행은 그냥 학습에 포함 안시키고 버린다 생각하고 drop해도 된다. 하지만 절대 test데이터는 1개의 행도 드롭하면 안된다!!!!! 얘를 예측해야하니까!!!!!

 

3. 이상치 처리

# clip(): 0보다 작으면 0으로, 100보다 크면 100으로 강제 고정
X_train['Age'] = X_train['Age'].clip(0, 100)
X_test['Age'] = X_test['Age'].clip(0, 100)

클립함수를 외워두자.

 

4. 문자열 변수(범주형 변수) 인코딩

인코딩 방법은 두개를 알아두자. 하나는 라벨인코딩, 하나는 원핫인코딩

# 라벨 인코딩
from sklearn.preprocessing import LabelEncoder

cat_cols = ['문자열컬럼1', '문자열컬럼2']

for col in cat_cols:
    le = LabelEncoder()
    # train과 test의 문자열을 모두 커버하기 위해 train 기준 학습(fit)후 적용(transform)
    X_train[col] = le.fit_transform(X_train[col])
    X_test[col] = le.transform(X_test[col])

# 원-핫 인코딩
# 자동으로 object 타입만 찾아서 0과 1의 열로 쪼개줌, 너무 편하긴 함
X_train = pd.get_dummies(X_train)
X_test = pd.get_dummies(X_test)

원핫 인코딩은 get_dummies()로 알아서 문자형 변수 인코딩해줘서 편하긴 한데

unique값 클 경우에는 칼럼수 너무 많아지는 사태가 발생돼서 아무래도 라벨인코딩이 더 추천되긴 한다.

 

라벨인코딩은 문자열컬럼 내가 직접 지정해서 반복문 돌려야 한다. train기준으로 학습시킨 라벨링은 test에 적용해야하니까 제발 fit_transform()함수는 오직 train에만! test에는 transform()함수만!

 

5. 스케일링

사실 작업형2에선 거의 트리모델(랜덤포레스트나 XGBoost, LightGBM)만 쓰기 때문에 굳이 스케일링이 필요가 없다. 다만 로지스틱 회귀같은 선형모델이나 KNN같은 거리기반모델 같은걸 쓰게 되면 숫자가 큰 컬럼에 과하게 치중돼서 학습되기 때문에 스케일링이 필수적이겠다. 일단 어떻게 하는지만 보고 지나가자. 작업형1이나 3에 나올 수도 있다.

from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()

# 주의: 수치형 컬럼들만 묶어서 스케일링 진행
num_cols = ['수치형컬럼1', '수치형컬럼2']

# train 데이터로 fit 및 transform, test 데이터는 transform만!
X_train[num_cols] = scaler.fit_transform(X_train[num_cols])
X_test[num_cols] = scaler.transform(X_test[num_cols])

스케일러의 경우 여러칼럼을 동시에 계산할 수 있게 만들어져서 라벨인코더랑 다르게 num_cols 시리즈 넣어도 된다. 라벨인코더는 너무 귀찮지만 반복문 돌려야 한다...


3rd. 검증데이터 분리

from sklearn.model_selection import train_test_split

X_tr, X_val, y_tr, y_val = train_test_split(train.drop('price', axis=1), train['price'],
                                            test_size=0.2, random_state=0)

train_test_split() 함수에서 첫번째 인자는 x_train, 두번째 인자는 정답 칼럼인 y_train, 세번째는 몇퍼센트를 검증집합으로 만들건지, random_state값은 지정해줘야 다른 모델로 바꿨을때도 같은 검증집합이 나온다.

 

그리고 불균형 데이터일 때는 이런식으로 stratify 옵션을 설정해줘야 한다.

target = train.pop('타겟 컬럼')

train_test_split(train,target, test_size=0.2, random_state=0, stratify=target)

4th. 모델 학습

분류모델은 Classification 사용! 회귀모델은 Regression 사용!

전부 트리 모델을 쓰면 된다. 

 

  • 랜덤포레스트
# Random Forest 모델 학습
from sklearn.ensemble import RandomForestClassifier

rf_model = RandomForestClassifier(random_state=0)
rf_model.fit(X_train, y_train)
y_pred = rf_model.predict(X_val)

n_estimators(나무개수) : 100이 기본값, 200, 300으로 설정할 수도 있지만 데이터 많을 경우에는 너무 느려짐

max_depth(트리깊이) : 3~12, 데이터 컬럼 수가 적을 때는 적게, 데이터 컬럼 수가 많을 때는 많게해서 깊이 학습

random_state 

  • LightGBM
# LightGBM 모델 학습
from lightgbm import LGBMClassifier

lgbm_model = LGBMClassifier(random_state=42)
lgbm_model.fit(X_train, y_train)
y_pred = lgbm_model.predict(X_Val)
  • Decision Tree
# Decision Tree 모델 학습
from sklearn.tree import DecisionTreeClassifier

dt_model = DecisionTreeClassifier(random_state=0)
dt_model.fit(X_train, y_train)
y_pred = dt_model.predict(X_val)
  • XGBoost
# XGBoost 모델 학습
from xgboost import XGBClassifier

xgb_model = XGBClassifier(random_state=0)
xgb_model.fit(X_train, y_train)
y_pred = xgb_model.predict(X_val)

 

만약 회귀모델이라면 Classifier을 Regressor로 바꾸면 된다.

 

그리고 마찬가지로 불균형데이터라면 이 옵션을 모델에 넣어주도록 하자.

class_weight='balanced'

 


5th. 모델 평가

from sklearn.metrics import 함수이름

# 분류 평가 

# 정확도(Accuracy) 검증
# 전체 데이터 중 맞게 예측한 비율 확인
accuracy_score(y_valid, y_pred)

# 정밀도(Precision) 검증
# 모델이 1이라고 예측한 것 중 실제 1의 비율 확인
precision_score(y_valid, y_pred)

# 재현율(Recall) 검증
# 실제 1인 데이터 중 모델이 맞춘 비율 확인
recall_score(y_valid, y_pred)

# F1 Score 검증
# Precision과 Recall의 조화평균 확인
f1_score(y_valid, y_pred)

# ROC-AUC 검증
# 분류 모델의 전체적인 성능 평가 (1에 가까울수록 좋음)
roc_auc_score(y_valid, y_pred_proba)

# Confusion Matrix(혼동행렬) 확인
# 실제값과 예측값 비교 결과 확인
confusion_matrix(y_valid, y_pred)

# Classification Report 확인
# Precision, Recall, F1-score 등을 한 번에 확인
print(classification_report(y_valid, y_pred))

# 회귀 평가

# R-Squared(R²) 검증
# 회귀 모델이 데이터를 얼마나 잘 설명하는지 확인
r2_score(y_valid, y_pred)

# MAE(평균 절대 오차) 검증
# 예측값과 실제값 차이의 절대값 평균 확인
mean_absolute_error(y_valid, y_pred)

# MSE(평균 제곱 오차) 검증
# 오차를 제곱해서 평균낸 값 확인
mean_squared_error(y_valid, y_pred)

6th. 모델 바꿔가면서 값 제일 좋은 녀석 선택

7th. test집합 예측, csv파일로 만들기

pred = model.predict(test)
# 분류문제에서 roc_auc가 평가지표라면 predict_proba()[:, 1] 이용!

submit = pd.DataFrame({'pred':pred})
submit.to_csv("result.csv", index=False)

# pd.read_csv("result.csv")로 확인해보면 된다.

 

'빅데이터분석기사' 카테고리의 다른 글

기출풀이  (0) 2026.06.18
작업형3 추가적으로  (0) 2026.06.14
작업형2 문풀  (0) 2026.06.14
작업형 제1유형 헷갈리는 내용 정리  (0) 2026.06.10
1과목 - 빅데이터 분석 기획  (2) 2026.03.16