(파이썬) 빅데이터 분석기사 실기 - 제2유형, 분류
Page content
작업형 2유형 최종정리
- 작업형1 : 3문제 (30점), 데이터 전처리
작업형2 : 1문제 (40점), 분류/회귀 예측 모델링
- 작업형3 : 2문제 (30점), 가설 검정
주요 라이브러리
- palmerpenguins : 팔머펭귄 데이터셋의 목표는 iris 데이터셋의 대안으로 데이터 탐색 및 시각화를 위한 데이터셋 제공.
- scikit-learn : 머신러닝을 위한 라이브러리
- lightgbm : LightGBM은 Microsoft에서 개발한 오픈 소스 기계 학습 라이브러리로, 대용량 데이터셋에서 빠른 속도와 높은 성능을 제공하는 것이 특징
주의
- 각 코드에 대한 설명은 별도로 하지 않습니다.
데이터 불러오기
import pandas as pd
from palmerpenguins import load_penguins
penguins = load_penguins()
penguins['ID'] = penguins.reset_index().index + 1
penguins.head()
- 컬럼의 순서를 변경하도록 한다.
cols = penguins.columns.tolist()
cols = cols[-1:] + cols[:-1]
print(cols)
[결과]
['ID', 'species', 'island', 'bill_length_mm', 'bill_depth_mm', 'flipper_length_mm', 'body_mass_g', 'sex', 'year']
penguins = penguins[cols]
penguins
데이터 가공
- 지금까지 열린 대회에서는 결측치가 존재 하지 않았던 것으로 기억
- 만약 잘못된 정보라면 알려주세요
- 결측치를 제거한다.
- sex 컬럼의 데이터는 male 1, female 0 이렇게 변환하기 위해 LabelEncoder를 사용한다.
from sklearn.preprocessing import LabelEncoder
# 결측치 제거
penguins = penguins.dropna().reset_index(drop=True)
# sex 성별 0과 1로 변경하기
le = LabelEncoder()
le.fit(penguins['sex'])
penguins['sex'] = le.transform(penguins['sex']) # male 1, female 0
penguins
데이터셋 분리
- 기사시험과 같이 데이터셋을 만들기 위해 데이터셋을 분리하고 저장한다.
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
le.fit(penguins['sex'])
penguins['sex'] = le.transform(penguins['sex']) + 1
y = penguins['sex']
X = penguins.drop(['sex'], axis=1)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=42
)
X_train.to_csv("penguin_clf_X_train.csv", index=False)
X_test.to_csv("penguin_clf_X_test.csv", index=False)
y_train.to_csv("penguin_clf_y_train.csv", index=False)
y_test.to_csv("penguin_clf_y_test.csv", index=False)
분류모형 만들기 정리
- 기본적으로 아래 데이터셋 불러오기는 제공된다.
import pandas as pd
X_train = pd.read_csv("penguin_clf_X_train.csv")
X_test = pd.read_csv("penguin_clf_X_test.csv")
y_train = pd.read_csv("penguin_clf_y_train.csv")
ID 제거
X_train_id = X_train.pop("ID")
X_test_id = X_test.pop("ID")
데이터 확인
X_train.head()
y_train.head()
X_test.head()
결측치 확인
X_train.isnull().sum()
[결과]
species 0
island 0
bill_length_mm 0
bill_depth_mm 0
flipper_length_mm 0
body_mass_g 0
year 0
dtype: int64
X_test.isnull().sum()
[결과]
species 0
island 0
bill_length_mm 0
bill_depth_mm 0
flipper_length_mm 0
body_mass_g 0
year 0
dtype: int64
y_train.isnull().sum()
[결과]
sex 0
dtype: int64
y_train.head()
컬럼 분리
- 범주형 컬럼과 숫자형 컬럼으로 분리
import numpy as np
cat_cols = X_train.select_dtypes(exclude = np.number).columns.tolist()
num_cols = X_train.select_dtypes(include = np.number).columns.tolist()
print(cat_cols, num_cols)
[결과]
['species', 'island'] ['bill_length_mm', 'bill_depth_mm', 'flipper_length_mm', 'body_mass_g', 'year']
- year은 num_cols에서 제거한다.
num_cols.remove("year")
num_cols
[결과]
['bill_length_mm', 'bill_depth_mm', 'flipper_length_mm', 'body_mass_g']
데이터셋 분리
from sklearn.model_selection import train_test_split
X_tr, X_val, y_tr, y_val = train_test_split(
X_train, y_train['sex'],
stratify = y_train['sex'],
test_size=0.3,
random_state=42
)
X_tr.shape, X_val.shape, y_tr.shape, y_val.shape
[결과]
((163, 7), (70, 7), (163,), (70,))
모형 만들기
- pipeline을 활용하여 모형을 만들면, 매우 쉽게 작성할 수 있다.
- OrdinalEncoder를 추가할 때는 아래와 같이 작성한다.
ord_encoder
영역만 살펴본다.
from sklearn.preprocessing import OrdinalEncoder
from sklearn.compose import ColumnTransformer
column_transformer = ColumnTransformer([
("scaler", StandardScaler(), num_cols),
("ohd_encoder", OneHotEncoder(), cat_cols)
("ord_encoder", OrdinalEncoder(categories=[["Adelie", "Gentoo", "Chinstrap"]]), ['species'])
], remainder="passthrough")
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.utils.fixes import loguniform
from sklearn.metrics import roc_auc_score
from lightgbm import LGBMClassifier
from sklearn.model_selection import RandomizedSearchCV
param_grid = {
"clf__learning_rate": loguniform(0.0001, 0.1),
"clf__n_estimators" : np.arange(100, 500),
"clf__max_depth" : np.arange(3, 30, 2),
"clf__num_leaves" : np.arange(30, 50),
"clf__min_split_gain" : np.arange(0, 1.1, 0.1),
"clf__subsample" : np.arange(0.1, 0.9, 0.1)
}
column_transformer = ColumnTransformer([
("scaler", StandardScaler(), num_cols),
("ohd_encoder", OneHotEncoder(), cat_cols)
], remainder="passthrough")
pipeline = Pipeline([
("preprocessing", column_transformer),
("clf", LGBMClassifier(random_state=42))
])
random_search = RandomizedSearchCV(
estimator=pipeline,
param_distributions = param_grid,
n_iter = 10,
scoring="roc_auc",
cv=5,
verbose=-1,
n_jobs=-1
)
random_search.fit(X_tr, y_tr)
[결과]
RandomizedSearchCV(cv=5,
estimator=Pipeline(steps=[('preprocessing',
ColumnTransformer(remainder='passthrough',
transformers=[('scaler',
StandardScaler(),
['bill_length_mm',
'bill_depth_mm',
'flipper_length_mm',
'body_mass_g']),
('ohd_encoder',
OneHotEncoder(),
['species',
'island'])])),
('clf',
LGBMClassifier(random_state=42))]),
n_jobs=-1,
param_distributions={'...
451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463,
464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476,
477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489,
490, 491, 492, 493, 494, 495, 496, 497, 498, 499]),
'clf__num_leaves': array([30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
47, 48, 49]),
'clf__subsample': array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8])},
scoring='roc_auc', verbose=-1)
평가확인
def get_score(model, X_tr, X_val, y_tr, y_val):
tr_pred = model.predict(X_tr) # 만약 확률로 구할시, predict_proba()[:, 1]
val_pred = model.predict(X_val)
tr_score = roc_auc_score(y_tr, tr_pred)
val_score = roc_auc_score(y_val, val_pred)
return f"train: {tr_score}, validation: {val_score}"
get_score(random_search, X_tr, X_val, y_tr, y_val)
[결과]
'train: 0.9689759036144577, validation: 0.8839869281045751'
평가 제출
final_preds = random_search.predict(X_test)
result = pd.DataFrame({
"ID" : X_test_id,
"preds": final_preds
})
result