๊ฐ์
๋๋ ๋ฐ์ผํ๋ก 11.4 ML ํ๋ก์ ํธ ๊ณต์ง๊ฐ ์ฌ๋ผ์๋ค!
๋ฌด๋ ค ํฌ์คํฐ ์ธ์ ์ผ๋ก ์งํ๋๋ ํ๋ก์ ํธ์๊ธฐ ๋๋ฌธ์ ์ด์ฌํ ์ค๋นํด์ ๋ฉ์ง ๋ฐํ๋ฅผ ํ๊ณ ์ถ์ ์์ฌ์ด ์์๋ค!
๋ฐฐ์ด ๊ฒ๋ค์ ์ข ํฉํด์ ML ์ ํ์ฉํ ํ๋ก์ ํธ๋ฅผ ์งํํ๋ฉด ๋๊ณ ,
๋ฐฐ์ด ๊ฒ์ ๋ํ ์๋ก์ด ์ ์์ ์ฐ๊ตฌ(Research) ํ๊ณ , ํ์กดํ๋ ์๊ณ ๋ฆฌ์ฆ์ ํฅ๋ฏธ๋ก์ด ๋ฌธ์ ์ ์ ์ฉ์์ผ๋ณธ๋ค. (Development)
๊ทธ๋ฆฌ๊ณ ๋ง์ง๋ง์ผ๋ก ์ฌ๋ฌ๊ฐ์ง ๋ค๋ฅธ ์๊ณ ๋ฆฌ์ฆ๋ค๋ ์ ์ฉํด๊ฐ๋ฉด์ ๋ค์ํ ์ฑ๋ฅ ์ธก์ ์งํ(performance metrics) ์ ๋ํ์ฌ ํ์ฅ ๋น๊ต ์ฐ๊ตฌ๋ฅผ ์งํํ๋ค. (Evaluation)
์ฃผ์ ์ ์
๊ฐ์ด๋๋ผ์ธ ๊ต์์ ๋ค์๊ณผ ๊ฐ์ ํ๋ก์ ํธ ์์๋ค์ ์ฃผ์ จ๋ค.
- Handwritten Alphabet/Digit Recognition
- Predictive Stock/House Price Modeling
- Image Classification with CNNs
- Recommendation System
- Face Recognition
- Traffic Flow Prediction
- Chatbot Development or LLM application
- Object Detection in Images
- Human Activity Recognition
๊ทผ๋ฐ ๊ผญ ์ฌ๊ธฐ์ ๊ณจ๋ผ์ผํ๋๊ฒ ์๋๋ผ, ๋ค๋ฅธ ํฅ๋ฏธ๋ก์ด ์ฃผ์ ๋ฅผ ์ ํํด๋ ๋๋ค๊ณ ํ์ ์ ๋๋ novelty ์ ์๋ฅผ ๋ ๋ฐ๊ณ ์ถ์ด์
ํฅ๋ฏธ๋ก์ ๋ณด์ด๋ ์๋ก์ด ์ฃผ์ ๋ฅผ ์ ํ๋ค. <๋ณ๋น์ ์ฃผ๊ธฐ์ ์ธ ๋ณํ ๋ถ์์ ํตํ ๐ฝ์ธ๊ณํ์ฑ์ฐพ๊ธฐ> ์ด๋ค.
์ด์ฉ๋ค๊ฐ ์ด๋ฐ ์ฃผ์ ๋ฅผ ๊ณจ๋๋๊ณ ํ๋ค๋ฉด,, ์ฌ์ค ์ง๋ 10์์ ๋ฐ์ดํฐ ๋ถ์์ ใท ์๋ ๋ชจ๋ฅด๋ฉด์
์บ๊ธ์ด๋ผ๋ ๋ฐ์ดํฐ ๋ถ์ ๋ํ ๋ชจ์ง ๊ณต๊ณ ๋ฅผ ๋ณด๊ณ ํฅ๋ฏธ๋ก์ ๋ณด์ธ๋ค๋ ์ด์ ๋ก ๋ฌด๋ชจํ ๋์ ์ ํ์๋ค.
์๋๋ ๋ฐ๋ก ๊ทธ ๋ฌธ์ ์ ์บ๊ธ ๋ํ์ด๋ค.. ๐๐
https://www.kaggle.com/competitions/ariel-data-challenge-2024/overview
NeurIPS - Ariel Data Challenge 2024
Derive exoplanet signals from Ariel's optical instruments
www.kaggle.com
์ธ๊ณ ํ์ฑ์ ๋๊ธฐ๋ฅผ ๋ถ์ํ๊ธฐ ์ํ multimodal supervised learning task ๋ฅผ ์ํํ๊ณ
๊ทธ ๊ณผ์ ์์ ๊ด์ธก์ฅ๋น์ ์ํ jitter noise ์๊ณก์ ์ ๊ฑฐํ๋ ๊ฒ์ด ๋ชฉ์ ์ธ ๋ํ์๋ค.
๊ทธ๋ฐ๋ฐ ์๋ฌด๋๋ ๊ฒฝํ์ด ํฐ๋ฌด๋ ์์ด ๋ชจ์๋ผ๋ค๋ณด๋ ์ด๋ป๊ฒ ์ ๊ทผํด์ผํ ์ง์กฐ์ฐจ ์ ๊ฐ์ด ์กํ์ง ์์๊ณ ์จ๊ฐ ์ํ ๊ณต์๋ค๋ง ๋๋ฌดํ๋ ์ฒ์ฒด๊ด๋ จ ๋ ผ๋ฌธ๋ค์ ๋ณด๋ฉฐ ์ข์ ํ๊ณ ํฌ๊ธฐํ๊ฒ ๋์๋ค.. ใ ใ ใ ( ์๋ฌด๋๋ ํ๋ ์ฒ๋ฌธํ์์ ๊ฐ์ฅ ์ด๋ ค์ด ๋ฐ์ดํฐ ๋ถ์ ๋ฌธ์ ์ค ํ๋๋ผ๊ณ ํ๋๊น..^^ )
๋น๋ก ๊ทธ ๋ ์๋ํ๋ ์ฃผ์ ๋ ์คํจํ์ง๋ง, ์ ์ฌํ์ง๋ง ์กฐ๊ธ ๋์ด๋๋ฅผ ๋ฎ์ถฐ์
๋ณ๋น์ ์ฃผ๊ธฐ์ ์ธ ๋ณํ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง๊ณ ์ธ๊ณํ์ฑ์ ์กด์ฌ๋ฅผ ์์ธก(Classification)ํ๋ ๊ฒ์ ๋ชฉํ๋ก ํด๋ณด๋ฉด ์ด๋จ๊นํ๋ ์๊ฐ์ด ๋ค์๋ค!
๋ณ๋น์ ์ฃผ๊ธฐ์ ์ธ ๋ณํ๋ฅผ ๊ฐ์ง๊ณ ์ด๋ป๊ฒ ์ธ๊ณํ์ฑ์ ์กด์ฌ๋ฅผ ์์ธกํ ์ ์์ด ? ๋ผ๊ณ ๋ฌป๋๋ค๋ฉด,
ํ์ฑ์ด ๋ณ ์์ ์ง๋๊ฐ๋ฉด, ๋ณ๋น์ ์ผ๋ถ๊ฐ ๊ฐ๋ ค์ ธ์ ๋ฐ๊ธฐ๊ฐ ์ฝ๊ฐ ๊ฐ์ํ๋ค. ์ฆ, ๋ชจํ์ฑ์ด ์ธ๊ณํ์ฑ์ ๊ฐ์ง๊ณ ์์ผ๋ฉด ๊ทธ ์ธ๊ณํ์ฑ์ด ๋ชจํ์ฑ ์ค์ฌ์ผ๋ก ๊ณต์ ํ๊ธฐ ๋๋ฌธ์ ๊ด์ธก ํ๋ ์ ์ฅ์์๋ ์ฃผ๊ธฐ์ ์ผ๋ก ๊ฐ์ง ๊ฐ๋ฅํ ๋ถ๋ถ์ ๋ง์ ๋น์ ๋ฐ๊ธฐ๊ฐ ๊ฐ์ํ๋ ๊ฒ์ ๊ด์ธกํ ์ ์๋ค.
์ด๋ฌํ ๋ณ์ ์ฃผ๊ธฐ์ ์ธ ๋ฐ๊ธฐ ๋ณํ์ ํจํด์ ๊ฐ์งํ์ฌ ์ต์ข ์ ์ผ๋ก ์ธ๊ณํ์ฑ์ด ์กด์ฌํ๋์ง ์ฌ๋ถ๋ฅผ ๊ด์ธกํ๊ณ ์ ํ๋ ๊ฒ์ด ์ฐ๋ฆฌ์ ๋ชฉ์ ์ด๋ค.
๊ทธ๋ ๊ฒ ๋๋ ๋ด ํ์์ "์ธ๊ณ ํ์ฑ์ ์ฐพ๊ธฐ ์ํ ์ฐ์ฃผ ๋ก์ ์ฌํ" ์ ๋ ๋ฌ๋ค! ๋ ์ธ ๊ธฐ๋ฆฟ ๐
์ธ๊ณ ํ์ฑ ์ฐพ๊ธฐ
๋ฐ์ดํฐ์
NASA ์ผํ๋ฌ ์ฐ์ฃผ๋ง์๊ฒฝ์์ ๊ฐ์ ธ์จ๋ค. ์ด ๋ฐ์ดํฐ์ ์์ 5,050 ๊ฐ๋ ์ธ๊ณํ์ฑ์ด ์๊ณ ์ค์ง 37๊ฐ๋ง ์ธ๊ณ ํ์ฑ์ด ์กด์ฌํ๋ค.
๋น์ ์ฃผ๊ธฐ์ ์ธ ๋ณํ๋ฅผ ๊ด์ฐฐํด์ ์ฃผ๊ธฐ์ฑ์ ์ฐพ์ผ๋ ค๋ฉด ์ถฉ๋ถํ ๋ฐ์ดํฐ ํฌ์ธํธ๊ฐ ํ์ํ๋ค.
ํ์๊ณ ์์ ์๋ ํ์ฑ์ ๊ณต์ ์ 88๋ ~ 165๋ ๊น์ง ๋ค๋ฅด๋ค.
๊ทธ๋ํ ์๊ฐํ
์๊ณ์ด ๋ฐ์ดํฐ์ ์์ ํต์ฐฐ์ ์ป๊ธฐ ์ํด์ ๊ทธ๋ํ๋ฅผ ๊ทธ๋ ค๋ณด์. ๊ฐ๋ก์ถ์ ๊ด์ธก ํ์์ด๊ณ ์ธ๋ก์ถ์ด ๊ด์(Light Flux)์ด๋ค.
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
sns.set()
X = df.iloc[:,1:]
y = df.iloc[:,0] - 1
def light_plot(index):
y_vals = X.iloc[index]
x_vals = np.arange(len(y_vals))
plt.figure(figsize=(15,8))
plt.xlabel('Number of Observations')
plt.ylabel('Light Flux')
plt.title('Light Plot ' + str(index), size=15)
plt.plot(x_vals, y_vals)
plt.show()
๋ถ๋ช ๋ฐ์ดํฐ์ ์ฃผ๊ธฐ์ ์ผ๋ก ๋ํ๋๋ ๋ณ์ ๋ฐ๊ธฐ ์ฆ๊ฐ์ด ์๋ค.
์ด๋ค ํ์ฑ์ ์ฃผ๊ธฐ์ ์ผ๋ก ๋น์ด ๊ฐ์ํ๋ค. ์ธ๊ณ ํ์ฑ์ด ์์ ๊ฐ๋ฅ์ฑ์ด ๋๋ค.
๋ฐ๋ฉด, ์ด๋ค ํ์ฑ์ ๋งค์ฐ ์ ์ ํ ๊ฒ์ ๋ณผ ์ ์๋ค.
ํ์ง๋ง ๊ทธ๋ํ๋ง์ผ๋ก๋ ์ธ๊ณํ์ฑ ์กด์ฌ ์ฌ๋ถ๋ฅผ ํ๋ณํ๊ธฐ์๋ ํ์ค์น ์๋ค.
์ด ๋ฐ์ดํฐ์ ์ ์๊ณ์ด ๋ฐ์ดํฐ์ด์ง๋ง, ๋ค์ ๋ฒ์ ๊ด์์ ์์ธกํ๋ ํ๊ท ๋ฌธ์ ๊ฐ ์๋ ์ธ๊ณ ํ์ฑ์ ๊ฐ์ง ๋ณ์ ๋ถ๋ฅ(Classificatoin)ํ๋ ๋ฌธ์ ์ด๋ค.
๋ชจ๋ธ ์ ์
๋ฌธ์ ํด๊ฒฐ์ ์ํ์ฌ ์ด๋ค ๋ชจ๋ธ์ ์ฌ์ฉํด์ผํ ๊น? ์ฐ๊ด์ฑ์ด ๋์๋ณด์ด๋ ๋ชจ๋ธ๊ตฐ๋ค์ ์กฐ์ฌํด๋ณด์๋ค.
1. ์ ํต์ ์ธ ์๊ณ์ด ๋ถ์ ๋ชจ๋ธ
ARIMA (AutoRegressive Integrated Moving Average)
- ๋ฐ์ดํฐ๊ฐ ๋น๊ต์ ๋จ์ํ๊ณ , ๋ ธ์ด์ฆ๊ฐ ์ ์ ๊ฒฝ์ฐ ์ ํฉ
- ๋ณ๋น์ ๋ฐ๊ธฐ ๋ฐ์ดํฐ์์ ์ฃผ๊ธฐ์ ์ธ ๋ณํ๋ฅผ ๊ฐ์งํ๊ณ ์ด์๊ฐ(Transit)์ ํ์ง
- ํ๊ณ: ๋ณต์กํ ๋น์ ํ ํจํด์ด๋ ๋ค์ค ์ฃผ๊ธฐ๋ฅผ ๋ค๋ฃจ๋ ๋ฐ๋ ๋ถ์กฑ.
2. ๋จธ์ ๋ฌ๋ ๊ธฐ๋ฐ ๋ชจ๋ธ
1) ๋๋ค ํฌ๋ ์คํธ (Random Forest)
- ๋ณ๋น ๋ฐ์ดํฐ์ ํน์ง(๋ฐ๊ธฐ ๋ณํ์ ํฌ๊ธฐ, ์ฃผ๊ธฐ, ๋ ธ์ด์ฆ ๋ฑ)์ ์ถ์ถํ ๋ค ์ด๋ฅผ ๋ถ๋ฅ ๋ฌธ์ ๋ก ์ ๊ทผ
- ๋ฐ์ดํฐ๊ฐ ๋น๊ต์ ์๊ฑฐ๋ ์ค๋ช ๊ฐ๋ฅํ ๋ชจ๋ธ์ด ํ์ํ ๋ ์ ํฉ
- ๋จ์ : ์๊ณ์ด ๋ฐ์ดํฐ ์์ฒด๋ฅผ ์ฒ๋ฆฌํ๊ธฐ์๋ ์ ํฉํ์ง ์์(ํน์ง ์ถ์ถ ๊ณผ์ ํ์)
2) Gradient Boosting ๊ณ์ด (e.g., XGBoost, LightGBM)
- ๋๋ค ํฌ๋ ์คํธ์ ์ ์ฌํ์ง๋ง, ๋ฐ์ดํฐ์์ ๋ ๋ณต์กํ ์ํธ์์ฉ์ ํ์ต
- ํน์ง ์ถ์ถ ํ ๋ฐ๊ธฐ ํจํด์ด ํ์ฑ์ ์ํ ๊ฒ์ธ์ง ์๋์ง ๋ถ๋ฅํ๋ ๋ฐ ์ ํฉ
3. ๋ฅ๋ฌ๋ ๊ธฐ๋ฐ ๋ชจ๋ธ
1) ์ํ ์ ๊ฒฝ๋ง (RNN, LSTM, GRU)
- ์๊ณ์ด ๋ฐ์ดํฐ์ ํจํด์ ํ์ตํ๋ ๋ฐ ํนํ๋ ๋ชจ๋ธ
- LSTM(Long Short-Term Memory)๊ณผ GRU(Gated Recurrent Unit)๋ ๊ธด ์๊ณ์ด ๋ฐ์ดํฐ๋ฅผ ํ์ตํ ์ ์์ด ์ฃผ๊ธฐ์ ์ด๊ณ ๋ณต์กํ ๋ฐ๊ธฐ ๋ณํ๋ฅผ ๊ฐ์งํ๋ ๋ฐ ์ ์ฉ
- ์ฅ์ : ๋ฐ์ดํฐ์ ์๊ฐ์ ์ข ์์ฑ์ ํจ๊ณผ์ ์ผ๋ก ํ์ต
- ๋จ์ : ํ์ต์ ๋ง์ ๋ฐ์ดํฐ์ ์๊ฐ์ด ํ์
2) 1D ํฉ์ฑ๊ณฑ ์ ๊ฒฝ๋ง (1D CNN)
- ์๊ณ์ด ๋ฐ์ดํฐ์์ ์ง์ญ์ ํจํด(ํน์ ๋ฐ๊ธฐ ๋ณํ ํจํด)์ ํ์ต
- ๋ณ๋น์ ๋ฐ๊ธฐ ๋ณํ์์ ํ์ฑ์ Transit ์ ํธ๋ฅผ ๊ฐ์งํ๋ ๋ฐ ์์ฃผ ์ฌ์ฉ
3) ํ์ด๋ธ๋ฆฌ๋ ๋ชจ๋ธ (CNN + LSTM)
- CNN์ผ๋ก ์ง์ญ์ ํจํด(Transit ์ ํธ)์ ํ์ตํ๊ณ , LSTM์ผ๋ก ์ ์ฒด ์๊ณ์ด ํจํด(์ฃผ๊ธฐ์ ๋ณํ)์ ํ์ต
์ฌ์ค XGBoost ๊ฐ ๋๋ถ๋ถ์ ์บ๊ธ ๋ํ์์ ์ฐ์น์ ์ฐจ์งํ ๋งํผ ์ฑ๋ฅ์ด ์ข์ ๋ชจ๋ธ๋ก ์๋ ค์ ธ์๋ค.
๊ทธ๋์ XGBClassifier ๋ฅผ ์ฌ์ฉํด ๋จผ์ ๋ถ๋ฅ ์์ ์ ์ํํด๋ณผ ๊ฒ์ด๋ค.
๋ฐ์ดํฐ ์ค๋น
์ด๊ธฐ XGBClassifier
# XGBRegressor๋ฅผ ์ํฌํธํฉ๋๋ค.
from xgboost import XGBClassifier
# accuracy_score๋ฅผ ์ํฌํธํฉ๋๋ค.
from sklearn.metrics import accuracy_score
# train_test_split๋ฅผ ์ํฌํธํฉ๋๋ค.
from sklearn.model_selection import train_test_split
# ๋ฐ์ดํฐ๋ฅผ ํ๋ จ ์ธํธ์ ํ
์คํธ ์ธํธ๋ก ๋๋๋๋ค.
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=2)
# XGBClassifier๋ฅผ ์ด๊ธฐํํฉ๋๋ค.
model = XGBClassifier(booster='gbtree')
# ํ๋ จ ์ธํธ๋ก ๋ชจ๋ธ์ ํ๋ จํฉ๋๋ค.
model.fit(X_train, y_train)
# ํ
์คํธ ์ธํธ์ ๋ํ ์์ธก์ ๋ง๋ญ๋๋ค.
y_pred = model.predict(X_test)
score = accuracy_score(y_pred, y_test)
print('์ ์: ' + str(score))
์ ์: 0.89
์ด ๋ฐ์ดํฐ์ ์์ ์ธ๊ณ ํ์ฑ์ ๊ฐ์ง ๋ณ์ 37 / ( 5,050 + 37 ) % ๋ฟ์ด๋ค. ์ฆ 10% ๋ ์ฑ ๋์ง ์๋๋ค.
๋ฐ๋ผ์ ๋ฌด์กฐ๊ฑด ์ธ๊ณ ํ์ฑ์ด ์๋ค๊ณ ์์ธกํ๋ ๋ชจ๋ธ์ด ์๋ค๋ฉด ์ด ๋ชจ๋ธ์ด ๋ ๋ซ๋ค๊ณ ๋งํ๊ธฐ ์ด๋ ค์ธ ๊ฒ์ด๋ค.
๋ถ๊ท ํํ ๋ฐ์ดํฐ์ ์์๋ ์ ํ๋๋ก๋ ์ถฉ๋ถํ์ง ์๋ค๋ ๊นจ๋ฌ์์ ์ป๋๋ค.
์ฌ๋ฌ๊ฐ์ง ํ๊ฐ์งํ
์ค์ฐจํ๋ ฌ ๋ถ์
๋ถ๋ฅ ๋ชจ๋ธ์ ์ฑ๋ฅ์ ํ๊ฐํ๊ธฐ ์ํด ์ฌ์ฉ๋๋ ํ๋ก, ์ค์ ๊ฐ๊ณผ ๋ชจ๋ธ์ ์์ธก ๊ฐ ๊ฐ์ ๋น๊ต๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ง๋ค์ด์ง๋ค.
์ด๋ค ์์ธก์ด ์ ํํ๊ณ ์ด๋ค ์์ธก์ด ํ๋ ธ๋์ง์ ๋ํ ์ ๋ณด๋ฅผ ์ ๊ณตํ๋ฏ๋ก ๋ถ๊ท ํํ ๋ฐ์ดํฐ์ ์ ๋ถ์ํ๋ ๋ฐ ์ด์์ ์ด๋ค.
from sklearn.metrics import confusion_matrix
confusion_matrix(y_test, y_pred)
array([[86, 2],
[ 9, 3]])
์ฐ๋ฆฌ๋ ์ฃผ์ด์ง ๋ฐ์ดํฐ์ ์ ๋ํ์ฌ ์ธ๊ณ ํ์ฑ์ ๊ฐ์ง ๋ณ์ ๋ชจ๋ ์ฐพ๋ ๊ฒ์ด ๋ชฉํ์ด๋ค. ๊ฐ๋ฅํ ๋ง์ ์ธ๊ณ ํ์ฑ์ ์ฐพ๋ ๊ฒ์ด ์ข์ผ๋ฏ๋ก ์ฌํ์จ์ ์ค์ํ๊ฒ ๋ณด์. ์ฌํ์จ์ ์ธ๊ณ ํ์ฑ์ ๊ฐ์ง ํ์ฑ ์ค์์ ์ค์ ๋ก ๋ช๊ฐ์ ํ์ฑ์ ์ฐพ์๋์ง๋ฅผ ์๋ ค์ค๋ค.
- ์ ๋ฐ๋ : 3 / (3 + 2) = 60% ํ๋ฅ ๋ก ์ธ๊ณํ์ฑ์ด๋ผ๊ณ ์์ธกํ ๊ฒ์ด ์ค์ ๋ก ์ ๋ต์ด๋ค.
- ์ฌํ์จ (Recall) : 3 / ( 3 + 9) = 25% ํ๋ฅ ๋ก ์์ฑ ์ํ์ ์ฐพ๋๋ค.
- ์ ํ๋ : 89 / 100 = 89% ํ๋ฅ ๋ก ์ถ์ธกํ ๋ต์ด ์ ๋ต์ด๋ค.
classification_report
from sklearn.metrics import classification_report
print(classification_report(y_test, y_pred))
from sklearn.metrics import classification_report
print(classification_report(y_test, y_pred))
precision recall f1-score support
0 0.91 0.98 0.94 88
1 0.60 0.25 0.35 12
accuracy 0.89 100
macro avg 0.75 0.61 0.65 100
weighted avg 0.87 0.89 0.87 100
[0] ์ ์์ฑ ์ํ์ ๋ํ precison, recall ์ด๊ณ [1]์ ์์ฑ ์ํ์ ๋ํ precison, recall ์ด๋ค.
F1 ์ ์๋ ์ ๋ฐ๋์ ์ฌํ์จ์ ์กฐํ ํ๊ท ์ด๋ค. ์ ๋ฐ๋์ ์ฌํ์จ์ ๋ถ๋ชจ๊ฐ ๋ค๋ฅด๋ฏ๋ก ์ด๋ฅผ ๋์ผํ๊ฒ ๋ง๋ค๊ธฐ ์ํด์ ์ฌ์ฉํ๋ค.
์ ๋ฐ๋์ ์ฌํ์จ ๋ชจ๋ ์ค์ํ ๋๋ F1 ์ ์๋ฅผ ์ฌ์ฉํ๋ฉด ์ข๋ค. 0 ~ 1 ์ฌ์ด ๊ฐ์ด๋ฉฐ 1์ด ๊ฐ์ฅ ์ข์ ๊ฐ์ด๋ค.
ROC ๊ณก์
๋ถ๊ท ํ ๋ฐ์ดํฐ ๋ฆฌ์ํ๋ง
์์ classification_report ์์ ๊ต์ฅํ ๋ฎ์ ์ฌํ์จ ์ ์๋ฅผ ๊ธฐ๋กํ๋ ๊ฒ์ ๋ณด์๋ค.
๊ทธ ์ด์ ๋ ์ ์ด์ ์์ฑ ์ํ ๊ฐ์๊ฐ ์์ฑ ์ํ๋ณด๋ค ํฑ์์ด ๋ชจ์๋๊ธฐ ๋๋ฌธ์ด๋ค.
- ํด๋์ค ๋ถ๊ท ํ ๋ฌธ์ ๋, ๋ชฉํ ๋ณ์(Target)์ ํด๋์ค ๋น์จ์ด ํฌ๊ฒ ์ฐจ์ด ๋๋ ๊ฒฝ์ฐ๋ฅผ ๋งํ๋ค. ์๋ฅผ ๋ค์ด, ๋ฐ์ดํฐ์์ Positive ํด๋์ค(1)๊ฐ 10%, Negative ํด๋์ค(0)๊ฐ 90%๋ผ๋ฉด ๋ชจ๋ธ์ Negative ํด๋์ค์ ์น์ฐ์น ์์ธก์ ํ๊ฒ ๋ ๊ฐ๋ฅ์ฑ์ด ๋๋ค.
- scale_pos_weight๋ ์ด๋ฌํ ์ํฉ์ ์ํํ๊ธฐ ์ํด Positive ํด๋์ค์ ๊ฐ์ค์น๋ฅผ ๋ถ์ฌํ์ฌ, Positive ํด๋์ค์ ๋ํ ํ์ต์ ์ค์์ฑ์ ๋์ด๋ ์ญํ
์๋ฅผ ๋ค์ด์ ์์ฑ ์ํ์ด ๋๊ฐ ๋ฟ์ด๋ผ๋ฉด, ๊ทธ ์ค ํ๋๋ง ์ ๋๋ก ๋ชป๋ง์ถฐ๋ 50% ์ฌํ์จ์ ๊ธฐ๋กํ๋ค.
๋ฐ๋ผ์ ๋ฎ์ ์ฌํ์จ ์ ์๋ฅผ ๋ง๋๋๋ฐ ๋ฐ์ดํฐ ๋ถ๊ท ํ ๋ฌธ์ ๋ฅผ ๊ณ ์น๊ธฐ ์ํด ๋ถ๊ท ํ ๋ฐ์ดํฐ๋ฅผ ๋ฆฌ์ํ๋งํ ๊ฒ์ด๋ค.
๋ค์ ํด๋์ค์ ์ํ์ ์ค์ด๊ธฐ ์ํด ๋ฐ์ดํฐ๋ฅผ ์ธ๋์ํ๋ง ํ๊ฑฐ๋ ์์ ํด๋์ค ์ํ์ ๋๋ฆฌ๊ธฐ ์ํด ์ค๋ฒ์ํ๋งํ ์ ์๋ค.
์ธ๋์ํ๋ง
๋ฐ์ดํฐ์์ ๋ค์ ํด๋์ค(majority class)์ ์ํ์ ์ค์ฌ์ ์์ ํด๋์ค(minority class)์ ๊ท ํ์ ๋ง์ถ๋ ๋ฐฉ๋ฒ.
ํด๋์ค ๋ถํฌ๋ฅผ ๊ท ํ ์๊ฒ ๋ง๋ค์ด, ๋ชจ๋ธ์ด ๋ค์ ํด๋์ค์ ์น์ฐ์น์ง ์๋๋ก ํ์ต์ ์ ๋ํ๋ค.
๋ฐ์ดํฐ ํฌ๊ธฐ๋ฅผ ์ค์ด๊ธฐ ๋๋ฌธ์ ์ฒ๋ฆฌ ์๋๊ฐ ๋นจ๋ผ์ง๋ฉฐ, ๊ฐ๋จํ๊ณ ๊ตฌํ์ด ์ฉ์ดํ๋ค.
๊ทธ๋ฌ๋, ๋ค์ ํด๋์ค์ ์ ๋ณด๋ฅผ ์์คํ ๊ฐ๋ฅ์ฑ์ด ์๋ค.
์ธ๋์ํ๋ง ๊ธฐ๋ฒ
- ๋๋ค ์ธ๋์ํ๋ง(Random Under-sampling): ๋ค์ ํด๋์ค ๋ฐ์ดํฐ๋ฅผ ๋ฌด์์๋ก ์ ๊ฑฐ.
- ํด๋ฌ์คํฐ๋ง ๊ธฐ๋ฐ ์ํ๋ง: ํด๋ฌ์คํฐ๋ง์ ํตํด ๋ฐ์ดํฐ๋ฅผ ๊ทธ๋ฃนํํ๊ณ , ๊ฐ ๊ทธ๋ฃน์์ ๋ํ ์ํ์ ์ ํ.
xgb_clf ํจ์๋ ์ธ๋์ํ๋ง ๊ฒฐ๊ณผ๊ฐ ์ด๋ป๊ฒ ๋ณํ๋์ง ์ ์ ์๋๋ก ์ฌํ์จ ์ ์๋ฅผ ๋ฐํํ๋ค.
def xgb_clf(model, nrows):
df = pd.read_csv('exoplanets.csv', nrows=nrows)
# ๋ฐ์ดํฐ๋ฅผ X์ y๋ก ๋๋๋๋ค.
X = df.iloc[:,1:]
y = df.iloc[:,0] - 1
# ๋ฐ์ดํฐ๋ฅผ ํ๋ จ ์ธํธ์ ํ
์คํธ ์ธํธ๋ก ๋๋๋๋ค.
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=2)
# ํ๋ จ ์ธํธ์์ ๋ชจ๋ธ์ ํ๋ จํฉ๋๋ค.
model.fit(X_train, y_train)
# ํ
์คํธ ์ธํธ์ ๋ํ ์์ธก์ ๋ง๋ญ๋๋ค.
y_pred = model.predict(X_test)
score = recall_score(y_test, y_pred)
print(confusion_matrix(y_test, y_pred))
print(classification_report(y_test, y_pred))
return score
nrows ๋ฅผ ๋ฐ๊พธ์ด ๊ฐ๋ฉด์ ์ฌํ์จ ์ ์๊ฐ ์ด๋ป๊ฒ ๋ณํ๋์ง ์ดํด๋ณด์.
xgb_clf(XGBClassifier(), nrows=800)
[[189 1]
[ 9 1]]
precision recall f1-score support
0 0.95 0.99 0.97 190
1 0.50 0.10 0.17 10
accuracy 0.95 200
macro avg 0.73 0.55 0.57 200
weighted avg 0.93 0.95 0.93 200
0.1
์ธ๊ณ ํ์ฑ์ด ์๋ ๋ณ์ ์ฌํ์จ์ ๊ฑฐ์ ์๋ฒฝํ์ง๋ง, ์ธ๊ณ ํ์ฑ์ด ์๋ ๋ณ์ ์ฌํ์จ์ 10%์ ๋ถ๊ณผํ๋ค.
๋ง์ผ ์ธ๊ณ ํ์ฑ์ ์ง๋ ๋ณ๊ณผ ์๋ ๋ณ์ ๊ฐ์๋ฅผ 37๊ฐ๋ก ๋์ผํ๊ฒ ๋ง์ถ๋ฉด ๊ท ํ์ด ๋ง๋๋ค.
xgb_clf(XGBClassifier(), nrows=74)
[[6 2]
[5 6]]
precision recall f1-score support
0 0.55 0.75 0.63 8
1 0.75 0.55 0.63 11
accuracy 0.63 19
macro avg 0.65 0.65 0.63 19
weighted avg 0.66 0.63 0.63 19
0.5454545454545454
์ค๋ฒ์ํ๋ง
๋ฐ์ดํฐ์์ ์์ ํด๋์ค(minority class)์ ์ํ์ ๋๋ ค์ ๋ค์ ํด๋์ค์ ๊ท ํ์ ๋ง์ถ๋ ๋ฐฉ๋ฒ์ด๋ค.
์์ ํด๋์ค ๋ฐ์ดํฐ๋ฅผ ๋๋ ค์ ๋ชจ๋ธ์ด ์์ ํด๋์ค์ ๋ํด ๋ ์ ํ์ตํ๋๋ก ์ ๋ํ๋ค.
๊ธฐ์กด ๋ฐ์ดํฐ๋ฅผ ๋ณด์กดํ๋ฉด์ ๋ชจ๋ธ์ด ์์ ํด๋์ค์ ๋ํ ํ์ต์ ๊ฐํํ ์ ์์ผ๋, ๊ณผ์ ํฉ(overfitting)์ ์ํ์ด ์๋ค.
nrow = 400 ์ผ ๋, ์์ฑ:์์ฑ ๋น์จ์ ์ฝ 10๋ 1์ด๋ค. ๋ฐ๋ผ์ ๊ท ํ์ ๋ง์ถ๊ธฐ ์ํด ์์ฑ ํด๋์ค ์ํ์ 10๋ฐฐ ๋๋ฆฐ๋ค.
์ด๋ฅผ ์ํ ์ ๋ต์ ๋ค์๊ณผ ๊ฐ๋ค.
- ์์ฑ ํด๋์ค ์ํ์ ์ํ๋ฒ ๋ณต์ฌํ ์๋ก์ด df ๋ฅผ ๋ง๋ ๋ค.
- ์๋ก์ด df ์ ์๋ณธ df ๋ฅผ ํฉ์ณ์ 1:1 ๋น์จ์ ๋ง๋ ๋ค.
์ฌ๊ธฐ์ ์ฃผ์ํ ์ ์ด ์๋๋ฐ, ๋ฐ์ดํฐ๋ฅผ ํ๋ จ ์ธํธ์ ํ ์คํธ ์ธํธ๋ก ๋๋๊ธฐ ์ ์ ๋ฆฌ์ํ๋งํ๋ฉด ์ฌํ์จ ์ ์๊ฐ ๋ถํ๋ ค์ง๋ค.
์์ผ๊น? ๋๋๊ธฐ์ ์ ์ค๋ฒ ์ํ๋งํ๊ณ ์ด๋ฅผ ํ๋ จ/ํ ์คํธ ์ธํธ๋ก ๋๋๋ฉด ๋ณต์ฌ๋ณธ์ด ๋ ์ธํธ ๋ชจ๋์ ๋ค์ด๊ฐ ๊ฐ๋ฅ์ฑ์ด ๋๊ธฐ ๋๋ฌธ์ด๋ค.
๋ฐ๋ผ์ ์ด๋ฏธ ํ์ตํ ๋์ผํ ์ํ์ ๋ํด ์์ธก ๊ฒฐ๊ณผ๋ฅผ ์ถ๋ ฅํ๋ฏ๋ก ์ ๋๋ก๋ Test ๋ฅผ ์ํํ๊ณ ์๋ค๊ณ ๋ณด๊ธฐ ์ด๋ ต๊ฒ ๋๋ค.
์ ์ ํ ๋ฐฉ๋ฒ์ ํ๋ จ ์ธํธ์ ํ ์คํธ ์ธํธ๋ฅผ ๋จผ์ ๋๋๊ณ ๊ทธ๋ค์ ๋ฆฌ์ํ๋ง์ ์ํํ๋ ๊ฒ์ด๋ค.
1. x_train ๊ณผ y_train ์ ํฉ์น๋ค.
๋ ๋ฐ์ดํฐํ๋ ์์ ์ธ๋ฑ์ค ๊ฐ์ด ๊ฐ์ ํ๋ผ๋ฆฌ ๋ณํฉ๋๋ค.
df_train = pd.merge(y_train, X_train, left_index=True, right_index=True)
2. np.repeat() ํจ์๋ฅผ ํตํ์ฌ ์๋ก์ด ๋ฐ์ดํฐ ํ๋ ์ newdf ๋ฅผ ๋ง๋ ๋ค.
- ์์ฑ ์ํ์ ๋ํ์ด ๋ฐฐ์ด๋ก ๋ณํํ๋ค.
- ๋ณต์ฌ ํ์ 9๋ฅผ ์ง์ ํ๋ค.
- ํ์ ๊ธฐ์ค์ผ๋ก ๋ณต์ฌํ๊ธฐ ์ํด axis=1 ์ ์ง์ ํ๋ค.
- ์ด ์ด๋ฆ์ ๋ณต์ฌํ๊ณ ๋ฐ์ดํฐ ํ๋ ์์ ์ฐ๊ฒฐํ๋ค.
newdf = pd.DataFrame(np.repeat(df_train[df_train['LABEL']==1].values,
9,axis=0))
newdf.columns = df_train.columns
df_train_resample = pd.concat([df_train, newdf])
df_train_resample['LABEL'].value_counts()
0.0 275
1.0 250
Name: LABEL, dtype: int64
์์ฑ ์ํ๊ณผ ์์ฑ ์ํ ์ฌ์ด ๊ท ํ์ด ๋ง๋๋ก ๋ฐ์ดํฐ๊ฐ ์ฆ๊ฐ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค!
3. ๋ฆฌ์ํ๋ง ๋ ๋ฐ์ดํฐ ํ๋ ์์ X์ y๋ก ๋๋๋ค.
X_train_resample = df_train_resample.iloc[:,1:]
y_train_resample = df_train_resample.iloc[:,0]
4. ๋ชจ๋ธ ํ๋ จ
# XGBClassifier๋ฅผ ์ด๊ธฐํํฉ๋๋ค.
model = XGBClassifier()
# ํ๋ จ ์ธํธ๋ก ๋ชจ๋ธ์ ํ๋ จํฉ๋๋ค.
model.fit(X_train_resample, y_train_resample)
# ํ
์คํธ ์ธํธ์ ๋ํด ์์ธก์ ๋ง๋ญ๋๋ค.
y_pred = model.predict(X_test)
score = recall_score(y_test, y_pred)
5. ์ค์ฐจ ํ๋ ฌ๊ณผ ๋ถ๋ฅ ๋ฆฌํฌํธ ์ถ๋ ฅ
print(confusion_matrix(y_test, y_pred))
print(classification_report(y_test, y_pred))
print(score)
[[86 2]
[ 8 4]]
precision recall f1-score support
0 0.91 0.98 0.95 88
1 0.67 0.33 0.44 12
accuracy 0.90 100
macro avg 0.79 0.66 0.69 100
weighted avg 0.89 0.90 0.88 100
0.3333333333333333
์์ํ ๋ ๋ง๋ ํ ์คํธ ์ธํธ๋ฅผ ์ฌ์ฉํ์ฌ ์ค๋ฒ์ํ๋ง์ผ๋ก 33.3% ์ฌํ์จ์ ๋ฌ์ฑํ์๋ค.
์ฌ์ ํ ๋ฎ์ง๋ง ์ด์ ์ ์ป์ 17%๋ณด๋ค๋ ๋๋ฐฐ ๋์ ์ ์์ด๋ค.
๋ฆฌ์ํ๋ง์ผ๋ก๋ ์ฑ๋ฅ์ด ํฌ๊ฒ ์ฌ๋ผ๊ฐ์ง ์์์ผ๋ฏ๋ก XGBoost์ ๋งค๊ฐ๋ณ์๋ฅผ ํ๋ํด๋ณผ ์ฐจ๋ก์ด๋ค.
XGBClassifier ํ๋
๊ฐ๋ฅํ ์ต์์ ์ฌํ์จ ์ ์๋ฅผ ์ป๋๋ก ํ๋ํ ๊ฒ์ด๋ค.
1. scale_pos_weight ๋งค๊ฐ๋ณ์๋ฅผ ์ฌ์ฉํด ๊ฐ์ค์น๋ฅผ ์กฐ์ ํ๊ณ
2. ๊ทธ๋ฆฌ๋ ์์น๋ก ์ต์์ ๋งค๊ฐ๋ณ์ ์กฐํฉ์ ์ฐพ๋๋ค.
๊ฐ์ค์น ์กฐ์ ํ๊ธฐ
scale_pos_weight์ ๊ฐ์ ๋ค์ ํด๋์ค์ ์์ ํด๋์ค ๊ฐ์ ๋น์จ์ ๊ธฐ๋ฐ์ผ๋ก ์ค์ ๋๋ค.
# ๋ฐ์ดํฐ๋ฅผ X์ y๋ก ๋๋๋๋ค.
X = df.iloc[:,1:]
y = df.iloc[:,0]
# ๋ฐ์ดํฐ๋ฅผ ํ๋ จ ์ธํธ์ ํ
์คํธ ์ธํธ๋ก ๋๋๋๋ค.
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=2)
model = XGBClassifier(scale_pos_weight=10)
model.fit(X_train, y_train)
# ํ
์คํธ ์ธํธ์ ๋ํ ์์ธก์ ๋ง๋ญ๋๋ค.
y_pred = model.predict(X_test)
score = recall_score(y_test, y_pred)
print(confusion_matrix(y_test, y_pred))
print(classification_report(y_test, y_pred))
print(score)
์ฌํ์จ: [0.10526316 0.27777778]
์ฌํ์จ ํ๊ท : 0.1915204678362573
์ด ๊ฒฐ๊ณผ๋ ๋ฆฌ์ํ๋ง์ผ๋ก ์ป์ ๊ฒ๊ณผ ๋์ผํ๋ค.
์ง์ ๊ตฌํํ ์ค๋ฒ ์ํ๋ง ๋ฐฉ๋ฒ์ scale_pos_weight ๋งค๊ฐ๋ณ์๋ฅผ ์ฌ์ฉํ์ฌ ๋ง๋ XGBClassifier์ ๋์ผํ ์์ธก์ ๋ง๋ ๋ค.
ํ์ดํผํ๋ผ๋ฏธํฐ ํ๋ ( grid_search )
ํ์ดํผํ๋ผ๋ฏธํฐ ํ๋์ ํ ๋์๋ ๋๋ค or ๊ทธ๋ฆฌ๋ ์์น๋ฅผ ์ํํ๋ ๊ฒ์ด ํ์ค์ด๋ค. ๋ ํด๋์ค ๋ชจ๋ ๋ ๊ฐ ์ด์์ ํด๋๋ก ๊ต์ฐจ ๊ฒ์ฆ์ ์ํํ๋ฉฐ, ๋๊ท๋ชจ ๋ฐ์ดํฐ์ ์์ ์ฌ๋ฌ ํด๋๋ฅผ ํ ์คํธ ํ๋ ๊ฒ์ด ์ค๋ ๊ฑธ๋ฆฌ๋ฏ๋ก ๋๊ฐ์ ํด๋๋ง ์ฌ์ฉํ๋ค. ์ผ๊ด๋ ๊ฒฐ๊ณผ๋ฅผ ์ํ์ฌ StratifiedFold ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๊ถ์ฅ๋๋ค.
๐ StratifiedFold ๋?
StratifiedKFold๋ scikit-learn ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ์ ๊ณตํ๋ ๊ต์ฐจ ๊ฒ์ฆ ๋ฐฉ๋ฒ ์ค ํ๋๋ก, ํด๋์ค ๋น์จ์ ๊ท ํ ์๊ฒ ์ ์งํ๋ฉฐ ๋ฐ์ดํฐ๋ฅผ ๋ถํ ํ๋ ๋ฐ ์ฌ์ฉ๋๋ค. ๊ฐ ํด๋(Fold) ๋ด์์ ์๋ ๋ฐ์ดํฐ์ ํด๋์ค ๋น์จ์ ์ ์งํ๋๋ก ๋ฐ์ดํฐ๋ฅผ ๋๋๋ค. ์๋ฅผ ๋ค์ด, ์ ์ฒด ๋ฐ์ดํฐ์์ Positive:Negative ๋น์จ์ด 1:9๋ผ๋ฉด, ๊ฐ ํด๋์์๋ ์ด ๋น์จ์ด ์ ์ง๋๋ค.
๊ธฐ์ค ๋ชจ๋ธ
k-fold ๊ต์ฐจ ๊ฒ์ฆ์ผ๋ก ๊ธฐ์ค ๋ชจ๋ธ์ ๋ง๋ ๋ค.
from sklearn.model_selection import GridSearchCV, RandomizedSearchCV,StratifiedKFold, cross_val_score
kfold = StratifiedKFold(n_splits=2, shuffle=True, random_state=2)
model = XGBClassifier(scale_pos_weight=10)
# ๊ต์ฐจ ๊ฒ์ฆ ์ ์๋ฅผ ๊ณ์ฐํฉ๋๋ค.
scores = cross_val_score(model, X, y, cv=kfold, scoring='recall')
# ์ฌํ์จ์ ์ถ๋ ฅํฉ๋๋ค.
print('์ฌํ์จ: ', scores)
# ์ฌํ์จ์ ํ๊ท ์ ์ถ๋ ฅํฉ๋๋ค.
print('์ฌํ์จ ํ๊ท : ', scores.mean())
์ฌํ์จ: [0.10526316 0.27777778]
์ฌํ์จ ํ๊ท : 0.1915204678362573
๊ต์ฐจ ๊ฒ์ฆ์ ํ๋๊น ์ฑ๋ฅ์ด ๋์ฑ ๋๋น ์ก๋ค..ใ ใ ์๋ฌด๋๋ ์์ฑ ์ํ์ด ์ ์ ๋์๋ ์ด๋ค ์ํ์ด ํ๋ จ ์ธํธ์ ํ ์คํธ ์ธํธ์ ํฌํจ๋๋์ง๊ฐ ์ฐจ์ด๋ฅผ ๋ง๋ค ๊ฒ์ด๋ค.
grid_search
def grid_search(params, random=False, X=X, y=y,
model=XGBClassifier(scale_pos_weight=10, random_state=2)):
xgb = model
if random:
grid = RandomizedSearchCV(xgb, params, cv=kfold, n_jobs=-1,
random_state=2, scoring='recall')
else:
# ๊ทธ๋ฆฌ๋ ์์น ๊ฐ์ฒด๋ฅผ ์ด๊ธฐํํฉ๋๋ค.
grid = GridSearchCV(xgb, params, cv=kfold, n_jobs=-1, scoring='recall')
# X_train์ y_train์ผ๋ก ํ๋ จํฉ๋๋ค.
grid.fit(X, y)
# ์ต์์ ๋งค๊ฐ๋ณ์๋ฅผ ์ถ์ถํฉ๋๋ค.
best_params = grid.best_params_
# ์ต์์ ๋งค๊ฐ๋ณ์๋ฅผ ์ถ๋ ฅํฉ๋๋ค.
print("์ต์์ ๋งค๊ฐ๋ณ์:", best_params)
# ์ต์์ ์ ์๋ฅผ ์ถ์ถํฉ๋๋ค.
best_score = grid.best_score_
# ์ต์์ ์ ์๋ฅผ ์ถ๋ ฅํฉ๋๋ค.
print("์ต์์ ์ ์: {:.5f}".format(best_score))
๊ทธ๋ฆฌ๊ณ ๋ ธ๊ฐ๋ค๋ฅผ ๋๋ฆฐ๋ค..
์ต์์ ๋งค๊ฐ๋ณ์: {'gamma': 0.025, 'learning_rate': 0.001, 'max_depth': 2}
์ต์์ ์ ์: 0.53509
์ต์์ ๋งค๊ฐ๋ณ์: {'subsample': 0.3, 'colsample_bytree': 0.7, 'colsample_bynode': 0.7, 'colsample_bylevel': 1}
์ต์์ ์ ์: 0.37865
๊ท ํ ์กํ ์๋ธ์
74๊ฐ ์ํ๋ก ์ด๋ฃจ์ด์ง ๊ท ํ์กํ ์๋ธ์ ์ ์ต์ํ ์์ ๋ฐ์ดํฐ์ด๊ธฐ์ ํ ์คํธํ๊ธฐ๋ ๋น ๋ฅด๋ค.
์ด ์๋ธ์ ์ ๊ทธ๋ฆฌ๋ ์์น๋ฅผ ์ํํ์ฌ ์ต์์ ๋งค๊ฐ๋ณ์๋ฅผ ์ฐพ๋๋ค.
X_short = X.iloc[:74, :]
y_short = y.iloc[:74]
grid_search(params={'max_depth':[1, 2, 3],
'colsample_bynode':[0.5, 0.75, 1]},
X=X_short, y=y_short,
model=XGBClassifier(random_state=2))
์ต์์ ๋งค๊ฐ๋ณ์: {'colsample_bynode': 0.5, 'max_depth': 1}
์ต์์ ์ ์: 0.65205
์ ์ฒด ๋ฐ์ดํฐ๋ก ํ๋ํ๊ธฐ
์ ์ฒด ๋ฐ์ดํฐ๋ก grid_search() ๋ฅผ ํธ์ถํ๋ฉด ๊ต์ฅํ ์ค๋ ๊ฑธ๋ฆฐ๋ค.
์์ฑ ํด๋์ค ๊ฐ์ / ์์ฑ ํด๋์ค ๋ก ๊ฐ์ค์น๋ฅผ ๊ณ์ฐํ๋ค. ๊ทธ๋ฆฌ๊ณ ํด๋น ๊ฐ์ค์น๋ฅผ scale_pos_weight ์ ์ ์ฉํ์ฌ ๋ชจ๋ธ์ ๋ง๋ ๋ค.
weight = int(5050/37)
model = XGBClassifier(scale_pos_weight=weight)
# ๊ต์ฐจ ๊ฒ์ฆ ์ ์๋ฅผ ๊ณ์ฐํฉ๋๋ค.
scores = cross_val_score(model, X_all, y_all, cv=kfold, scoring='recall')
# ์ฌํ์จ์ ์ถ๋ ฅํฉ๋๋ค.
print('์ฌํ์จ:', scores)
# ์ฌํ์จ์ ํ๊ท ์ ์ถ๋ ฅํฉ๋๋ค.
print('์ฌํ์จ ํ๊ท :', scores.mean())
์ ์๊ฐ ์์ฃผ ์ข์ง ์๋ค.
์ฌํ์จ: [0.10526316 0. ]
์ฌํ์จ ํ๊ท : 0.05263157894736842
์ง๊ธ๊น์ง ์ ์ผ ์ข์๋ ๋งค๊ฐ๋ณ์๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ์ดํผํ๋ผ๋ฏธํฐ ํ๋์ ํด๋ณธ๋ค.
์ด ์ ์๋ ์์ ์ธ๋์ํ๋งํ ๋ฐ์ดํฐ์ ์ ๊ฒฐ๊ณผ๋งํผ์ ์๋์ง๋ง ๋ ๋์์ก๋ค.
์ ์ฒด ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ ์ ์๊ฐ ๋ฎ๊ณ ์๊ฐ์ด ์ค๋๊ฑธ๋ ธ์ผ๋ "์ธ๊ณ ํ์ฑ ๋ฐ์ดํฐ์ ์ ์์ ์๋ธ์ ์์ ML ๋ชจ๋ธ์ด ๋ ์ ๋์ํ ๊น์?" ๋ผ๋ ์ง๋ฌธ์ด ์๊ธด๋ค.
๊ฒฐ๊ณผ ํตํฉ
์ง๊ธ๊น์ง ๋ค์๊ณผ ๊ฐ์ ์๋ธ์ ์ ์๋ํด๋ณด์๋ค.
- 5050๊ฐ ์ํ -> ์ฝ 54% ์ฌํ์จ
- 400๊ฐ ์ํ -> ์ฝ 54% ์ฌํ์จ
- 74๊ฐ ์ํ -> ์ฝ 68% ์ฌํ์จ
๊ฐ์ฅ ์ข์ ์ ์๋ฅผ ๋ธ ๋งค๊ฐ๋ณ์๋ learning_rate = 0.001, max_depth=2, colsample_bynode=0.5 ์ด๋ค.
์ธ๊ณ ํ์ฑ์ ๊ฐ์ง 37๊ฐ์ ๋ณ์ ๋ชจ๋ ํฌํจํด ๋ชจ๋ธ์ ํ๋ จํ๋ค. ์ด๋ ํ ์คํธ ์ธํธ์ ๋ชจ๋ธ ํ๋ จ์ ์ฌ์ฉํ ์ํ์ด ํฌํจ๋๋ค๋ ์๋ฏธ์ด๋ค.
์ผ๋ฐ์ ์ผ๋ก ์ด๋ ์ข์ ์๊ฐ์ด ์๋์ง๋ง, ์ด ์์ ์์๋ ์์ฑ ํด๋์ค๊ฐ ๋งค์ฐ ์ ๊ธฐ ๋๋ฌธ์ ์ด์ ์ ๋ณธ ์ ์๋ ์์ฑ ์ํ๋ก ์ด๋ฃจ์ด์ง ๋ ์์ ์๋ธ์ ์ ํ ์คํธ ํ๋ ๋ฐฉ๋ฒ์ ์์๋ณด๋๋ฐ ๋์์ด ๋ ์ ์๋ค.
def final_model(X, y, model):
model.fit(X, y)
y_pred = model.predict(X_all)
score = recall_score(y_all, y_pred)
print(score)
print(confusion_matrix(y_all, y_pred))
print(classification_report(y_all, y_pred))
74๊ฐ ์ํ
final_model(X_short, y_short,
XGBClassifier(max_depth=2, colsample_by_node=0.5,
random_state=2))
1.0
[[3588 1462]
[ 0 37]]
precision recall f1-score support
0 1.00 0.71 0.83 5050
1 0.02 1.00 0.05 37
accuracy 0.71 5087
macro avg 0.51 0.86 0.44 5087
weighted avg 0.99 0.71 0.83 5087
์ธ๊ณ ํ์ฑ์ ๊ฐ์ง 37๊ฐ์ ๋ณ์ ๋ชจ๋ ์๋ฒฝํ๊ฒ ๋ถ๋ฅํ๋ค. ํ์ง๋ง ์ธ๊ณ ํ์ฑ์ด ์๋ 0.29 ์ ์ํ(1,462) ๋ฅผ ์๋ชป ๋ถ๋ฅํ๋ค.
๊ฒ๋ค๊ฐ ์ ๋ฐ๋๋ 2%์ด๋ฉฐ, F1 ์ ์๋ 5%์ด๋ค. ์ฌํ์จ๋ง ํ๋ํ ๋์๋ ์ง๋์น๊ฒ ๋ฎ์ ์ ๋ฐ๋์ F1 ์ ์๊ฐ ์ํ ์์ธ์ด๋ค.
400๊ฐ ์ํ
final_model(X, y,
XGBClassifier(max_depth=2, colsample_bynode=0.5,
scale_pos_weight=10, random_state=2))
1.0
[[4897 153]
[ 0 37]]
precision recall f1-score support
0 1.00 0.97 0.98 5050
1 0.19 1.00 0.33 37
accuracy 0.97 5087
macro avg 0.60 0.98 0.66 5087
weighted avg 0.99 0.97 0.98 5087
์ฌ๊ธฐ๋ ์ฌํ์จ 100%๋ฅผ ๋ฌ์ฑํ์ง๋ง,
์ธ๊ณ ํ์ฑ์ด ์๋ ๊ฒฝ์ฐ์ ์ฌํ์จ์ด 0.19๋ก 149๊ฐ์ ๋ณ์ ์๋ชป ๋ถ๋ฅํ๋ค.
์ด ๊ฒฝ์ฐ ์ธ๊ณ ํ์ฑ์ด ์๋ ๋ณ 37๊ฐ๋ฅผ ์ฐพ๊ธฐ ์ํด์ 190๊ฐ์ ๋ณ์ ๋ถ์ํด์ผํ๋ค.
5,050 ์ํ
final_model(X_all, y_all,
XGBClassifier(max_depth=2, colsample_bynode=0.5,
scale_pos_weight=weight, random_state=2))
1.0
[[5050 0]
[ 0 37]]
precision recall f1-score support
0 1.00 1.00 1.00 5050
1 1.00 1.00 1.00 37
accuracy 1.00 5087
macro avg 1.00 1.00 1.00 5087
weighted avg 1.00 1.00 1.00 5087
๋ชจ๋ ์์ธก, ์ฌํ์จ, ์ ๋ฐ๋๊ฐ 100%๋ก ์๋ฒฝํ๋ค.
ํ์ง๋ง ์ ๋ ํด์ผํ ์ ์, ์๋๋ ๊ฐ๋ ฅํ ๋ชจ๋ธ์ ๋ง๋ค๊ธฐ ์ํด์ ๋ชจ๋ธ์ด ๋ณธ ์ ์๋ ํ ์คํธ ์ธํธ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ํ์์ ์ด์ง๋ง ์ฌ๊ธฐ์์๋ ํ๋ จ ๋ฐ์ดํฐ์์ ์ด ์ ์๋ฅผ ์ป์๋ค. ๋ฐ๋ผ์ ๋ชจ๋ธ์ด ํ๋ จ ๋ฐ์ดํฐ๋ฅผ ์๋ฒฝํ๊ฒ ํ์ตํ๋๋ผ๋ ์๋ก์ด ๋ฐ์ดํฐ์ ์ ์ผ๋ฐํ๋ ๊ฐ๋ฅ์ฑ์ด ๋ฎ๋ค.
๋ฐ์ดํฐ์ ์๋ ๋ฏธ๋ฌํ ํจํด์ ์ก์๋ด๋ ค๋ฉด ๋ ๋ง์ ํธ๋ฆฌ์ ๋ ๋ง์ ํ๋์ด ํ์ํ ์ ์๋ค.
๊ฒฐ๊ณผ ๋ถ์
์ ๋ฐ๋๋ฅผ ์ฌ์ฉํ ์ฌ์ฉ์๋ ์ผ๋ฐ์ ์ผ๋ก 50~70%๋ฅผ ๋ฌ์ฑํ๊ณ , ์ฌํ์จ์ ์ฌ์ฉํ ์ฌ์ฉ์๋ 60~100%๋ฅผ ๋ฌ์ฑํ๋ค.
๋ถ๊ท ํํ ๋ฐ์ดํฐ์ ํ๊ณ๋ฅผ ์๊ณ ์๋ค๋ฉด ๋ชจ๋ธ์ ์ฑ๋ฅ์ ์ต๋ 70% ์ฌํ์จ์ด๋ฉฐ, ์ธ๊ณ ํ์ฑ์ ๊ฐ์ง 37๊ฐ์ ๋ณ๋ก๋ ์๋ช ์ฒด๋ ๋ค๋ฅธ ํ์ฑ์ ์ฐพ๊ธฐ ์ํด ๊ฐ๋ ฅํ ๋จธ์ ๋ฌ๋ ๋ชจ๋ธ์ ๋ง๋ค๊ธฐ์๋ ์ถฉ๋ถํ์ง ์๋ค.
'CS > ์ธ๊ณต์ง๋ฅ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
k-ํ๊ท ์๊ณ ๋ฆฌ์ฆ (k-means clustering) ๊ตฌํ (0) | 2024.10.18 |
---|---|
SVM ์ ํ์ฉํ ์คํธ ๋ถ๋ฅ๊ธฐ ( Spam Classification via SVM ) (1) | 2024.10.17 |
๋์ด๋ธ ๋ฒ ์ด์ฆ๋ฅผ ์ฌ์ฉํ ์คํธ ๋ฉ์ผ ๋ถ๋ฅ๊ธฐ (Spam Classification via Naรฏve Bayes) (3) | 2024.10.17 |
[Tensorflow keras] image generation using Stable Diffusion (0) | 2024.06.24 |
Simple Diffusion Image generate Model (0) | 2024.06.21 |