๋ฌ๋์คํผ์ฆ ์์ ์ ๋ฆฌ
<์ด์ ๊ธ>
https://silvercoding.tistory.com/70
[FIFA DATA] 2019/2020 ์์ฆ Manchester United ์ ์ด๋ค ์ ์๋ฅผ ์์ ํด์ผ ํ๋๊ฐ?, EDA ๊ณผ์
๋ฌ๋์คํผ์ฆ ์์ ์ ๋ฆฌ < ์ด์ ๊ธ > https://silvercoding.tistory.com/69 https://silvercoding.tistory.com/67 https://silvercoding.tistory.com/66 https://silvercoding.tistory.com/65 https://silvercoding...
silvercoding.tistory.com
1. ๋ฐ์ดํฐ ์๊ฐ & ๋ฐ์ดํฐ ๋ถ๋ฌ์ค๊ธฐ
<Rossmann Store Sales>
https://www.kaggle.com/c/rossmann-store-sales/data?select=test.csv
Rossmann Store Sales | Kaggle
www.kaggle.com
ํด๋น ๋งํฌ์ ์บ๊ธ ๋ํ์์ ์ฌ์ฉ๋์๋ ๋ก์ค๋ง ๋ฐ์ดํฐ์ด๋ค.
- train.csv - historical data including Sales
- test.csv - historical data excluding Sales
- sample_submission.csv - a sample submission file in the correct format
- store.csv - supplemental information about the stores
๋ณธ ํฌ์คํ ์์๋ ์ถ์๋ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ์ฌ ์์ ์ ๋งค์ถ ์์ธก์ ์งํํ๋ค.
(๋ฐ์ดํฐ: ๋ฌ๋์คํผ์ฆ ์ ๊ณต)
import os
import pandas as pd
os.chdir('../data')
train = pd.read_csv("lspoons_train.csv")
test = pd.read_csv("lspoons_test.csv")
store = pd.read_csv("store.csv")
lspoons_train.csv - ํ์ต ๋ฐ์ดํฐ
lspoons_test.csv - ์์ธกํด์ผ ํ test ๋ฐ์ดํฐ
store.csv - ์์ ์ ๋ํ ์ ๋ณด๊ฐ ๋ด๊ธด ๋ณด์กฐ ๋ฐ์ดํฐ
train.head()
์ปฌ๋ผ ์ ๋ณด
- id
- Store: ๊ฐ ์์ ์ id
- Date: ๋ ์ง
- Sales: ๋ ์ง์ ๋ฐ๋ฅธ ๋งค์ถ
- Promo: ํ๋งค์ด์ง ํ์ฌ ์งํ ์ฌ๋ถ
- StateHoliday: ๊ณตํด์ผ ์ฌ๋ถ/ ๊ณตํด์ผ X-> 0, ๊ณตํด์ผ-> ๊ณตํด์ผ์ ์ข ๋ฅ(a, b, c)
- SchoolHoliday: ํ๊ต ํด์ผ์ธ์ง ์ฌ๋ถ
์์ ์ปฌ๋ผ๋ค์ ์ฌ์ฉํ์ฌ Sales(๋งค์ถ) ์ ์์ธกํ๋ ๋ชจ๋ธ์ ์์ฑํ๋ค.
- ๋ถ์ ์ ์ฐจ ์๋ฆฝ
1. ๋ฒ ์ด์ค ๋ชจ๋ธ๋ง ( feature engineering - ๋ณ์์ ํ - ๋ชจ๋ธ๋ง )
2. 2์ฐจ ๋ชจ๋ธ๋ง ( store ๋ฐ์ดํฐ merge - feature engineering - ๋ณ์ ์ ํ - ๋ชจ๋ธ๋ง )
3. ํ๋ผ๋ฏธํฐ ํ๋
... ๋ชจ๋ธ๋ง ๋ฐ๋ณต ( ์ด ํ ๋ชจ๋ธ๋ง์ ์์จ, ๊นํ ์ ๋ฆฌ )
1. ๋ฒ ์ด์ค ๋ชจ๋ธ๋ง
: ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ๋ชจ๋ธ์ ๋ง๋ ๋ค. (๊ฒฐ์ธก๊ฐ ์ฒ๋ฆฌ, ์ํซ ์ธ์ฝ๋ฉ)
ํผ์ณ ์์ง๋์ด๋ง์ด๋?
- ์์ธก์ ์ํด ๊ธฐ์กด์ input ๋ณ์๋ฅผ ์ด์ฉํ์ฌ ์๋ก์ด input ๋ณ์ ์์ฑ
- ๋จธ์ ๋ฌ๋ ์์ธก ์ฑ๋ฅ ์ฌ๋ฆด ์ ์๋ ๋ฐฉ๋ฒ
train.info()
๊ฒฐ์ธก๊ฐ์ ์๋ ๊ฒ์ ์ ์ ์๊ณ , object ํ์ ์ธ Date, StateHoliday ์ปฌ๋ผ์ ์ ์ฒ๋ฆฌ ํด์ค๋ค.
- StateHoliday column one-hot encoding
train = pd.get_dummies(columns=['StateHoliday'],data=train)
test = pd.get_dummies(columns=['StateHoliday'],data=test)
get_dummies ํจ์๋ฅผ ์ฌ์ฉํ์ฌ StateHoliday ์ปฌ๋ผ์ ์ํซ์ธ์ฝ๋ฉ ํด์ค๋ค.
print("train_columns: ", train.columns, end="\n\n\n")
print("test_columns: ", test.columns)
์๋ก ์์ฑ๋ ์นผ๋ผ์ ๋ณด๋ฉด train์๋ b, c ๊ฐ ์์ง๋ง test์๋ b, c ๊ฐ ์กด์ฌํ์ง ์๋๋ค. ์ด ๊ฒฝ์ฐ ํ์ต ๊ณผ์ ์์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๋ค.
test['StateHoliday_b'] = 0
test['StateHoliday_c'] = 0
๋ฐ๋ผ์ ๊ฐ์ ์นผ๋ผ์ test ๋ฐ์ดํฐ์ ์ ์์ฑํด ์ค๋ค.
- feature engineering using Date column
train['Date']
Date ์นผ๋ผ์ ๋ ์งํ ํํ๋ก ๋์ด ์์ง๋ง dtype์ด object์ด๋ฏ๋ก ๋ ์ง๋ก์์ ์๋ฏธ๊ฐ ์๋ค.
train['Date'] = pd.to_datetime( train['Date'] )
test['Date'] = pd.to_datetime( test['Date'] )
๋ฐ๋ผ์ pandas์์ ๋ ์ง ๊ณ์ฐ์ ํธ๋ฆฌํ๊ฒ ํด์ฃผ๋ to_datetime ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ๋ ์งํ ๋ณ์๋ก ๋ณํํด ์ค๋ค.
# ์์ผ ์ปฌ๋ผ weekday ์์ฑ
train['weekday'] = train['Date'].dt.weekday
test['weekday'] = test['Date'].dt.weekday
# ๋ ๋ ์ปฌ๋ผ year ์์ฑ
train['year'] = train['Date'].dt.year
test['year'] = test['Date'].dt.year
# ์ ์ปฌ๋ผ month ์์ฑ
train['year'] = train['Date'].dt.year
test['year'] = test['Date'].dt.year
- ๋ฒ ์ด์ค๋ผ์ธ ๋ชจ๋ธ๋ง
from xgboost import XGBRegressor
train.columns
xgb = XGBRegressor( n_estimators= 300 , learning_rate=0.1 , random_state=2020 )
xgb.fit(train[['Promo','SchoolHoliday','StateHoliday_0','StateHoliday_a','StateHoliday_b','StateHoliday_c','weekday','year','month']],
train['Sales'])
XGB ๋ชจ๋ธ์ ์ฌ์ฉํ์ฌ ํ์ต์ ์์ผ ์ค๋ค.
from sklearn.model_selection import cross_val_score
cross_val_score(xgb, train[['Promo', 'weekday', 'month','year', 'SchoolHoliday']], train['Sales'], scoring="neg_mean_squared_error", cv=3)
cross validation ์ผ๋ก ์ค๋ฅ์จ์ ๊ตฌํด๋ณด์๋๋ ์์ ๊ฐ์ด ๋์๋ค. ์ถ๊ฐ ์์ ์ผ๋ก ์ค๋ฅ์จ์ ์ค์ฌ๋๊ฐ ๋ณด์!
cf. ์บ๊ธ ์ ์ถ ํ์ผ ๋ง๋ค๊ธฐ
test['Sales'] = xgb.predict(test[['Promo','SchoolHoliday','StateHoliday_0','StateHoliday_a','StateHoliday_b','StateHoliday_c','weekday','year','month']])
test ๋ฐ์ดํฐ์ ์ผ๋ก ํ์ต๋ ๋ชจ๋ธ์ ๋ฃ์ด ์์ธก์ ์งํํ๋ค.
test[['id','Sales']].to_csv("submission.csv",index=False)
- ๋ณ์ ์ ํ
xgb.feature_importances_
feature_importances_ ๋ฅผ ์ฌ์ฉํ์ฌ ๋ณ์์ ์ค์๋๋ฅผ ์ ์ ์๋ค.
input_var = ['Promo','SchoolHoliday','StateHoliday_0','StateHoliday_a','StateHoliday_b','StateHoliday_c','weekday','year','month']
input_var์ Sales๋ฅผ ์ ์ธํ ์ธํ ๋ณ์๋ฅผ ์ ์ฅํด ์ค๋ค.
imp_df = pd.DataFrame({"var": input_var,
"imp": xgb.feature_importances_})
imp_df = imp_df.sort_values(['imp'],ascending=False)
imp_df
๋ณ์ ์ค์๋ ๋ฐ์ดํฐํ๋ ์์ ์์ฑํ ํ ๋์ ์์๋๋ก ์ ๋ ฌ์ ํด ์ค๋ค. Promo๊ฐ ์๋์ ์ผ๋ก ๋ณ์์ค์๋๊ฐ ๋์ ๊ฒ์ ๋ณผ ์ ์๋ค. State_Holiday๋ ๋์ฒด์ ์ผ๋ก ๋ฎ์ ๊ฒ์ผ๋ก ๋ณด์ธ๋ค.
import matplotlib.pyplot as plt
plt.bar(imp_df['var'],imp_df['imp'])
plt.xticks(rotation=90)
plt.show()
ํ๋์ ๋ณด๊ธฐ์ํด ๊ทธ๋ํ๋ฅผ ๊ทธ๋ ค ๋ณด์๋๋ SchoolHoliday ์ดํ ์ปฌ๋ผ๋ค์ ๋ณ ์๋ฏธ๊ฐ ์์ด ๋ณด์ธ๋ค.
cross_val_score(xgb, train[['Promo', 'weekday', 'month','year', 'SchoolHoliday']], train['Sales'], scoring="neg_mean_squared_error", cv=3)
๋ชจ๋ ์ปฌ๋ผ์ ์ฌ์ฉํ์ ๋ ๋ณด๋ค ์ค๋ฅ์จ์ด ์ค์ด๋ค์๋ค. ๊ทธ๋ ๋ค๋ฉด ์ปฌ๋ผ์ ๋ช๊ฐ ์ฌ์ฉํ๋ ๊ฒ์ด ๊ฐ์ฅ ์ค๋ฅ์จ์ ์ค๊ฒ ํ๋์ง ์คํํด ๋ณธ๋ค.
import numpy as np
score_list=[]
selected_varnum=[]
for i in range(1,10):
selected_var = imp_df['var'].iloc[:i].to_list()
scores = cross_val_score(xgb,
train[selected_var],
train['Sales'],
scoring="neg_mean_squared_error", cv=3)
score_list.append(-np.mean(scores))
selected_varnum.append(i)
print(i)
plt.plot(selected_varnum, score_list)
๋ณ์์ ๊ฐ์ ๋ณ๋ก cross validation์ ์ํํ ๊ฒฐ๊ณผ 2๊ฐ์ผ ๋ ๊ฐ์ฅ ๋ฎ์ ๊ฒ์ ๋ณผ ์ ์๋ค.
์์ธก๋ณ์๊ฐ 2๊ฐ์ผ ๋ cross validation์ ์ํํ๋ค.
cross_val_score(xgb, train[['Promo', 'weekday']], train['Sales'], scoring="neg_mean_squared_error", cv=3)
๋๋ฒ์งธ ๋นผ๊ณ ๋ ๋ชจ๋ ์ค์ด๋ ๊ฒ์ ๋ณผ ์ ์๋ค. ์์ธก๋ณ์๊ฐ 2๊ฐ์ผ ๋ ๋ชจ๋ธ ํ์ต์ ํ ํ, ํ ์คํธ ๋ฐ์ดํฐ๋ก ์ ์ถํ ์บ๊ธ ์ค์ฝ์ด๋ ๋ ์ค์ด๋ค์๋ค. (๋ฐ๋ณต์์ ์ด๋ฏ๋ก ํฌ์คํ ์์ ์๋ต)
2. 2์ฐจ ๋ชจ๋ธ๋ง
- store ๋ฐ์ดํฐ ํฉ๋ณ
store
store ๋ฐ์ดํฐ์ : ๊ฐ ์์ ์ ๋ํ ํน์ง์ ์ ๋ฆฌํ ๊ฒ
์ปฌ๋ผ ์๋ฏธ
- Store: ์์ ์ ์ ๋ํฌํ id
- Store Type: ์์ ์ ์ข ๋ฅ
- Assortment: ์์ ์ ์ข ๋ฅ
- CompetitionDistance: ๊ฐ์ฅ ๊ฐ๊น์ด ๊ฒฝ์์ ์ฒด ์์ ๊ณผ์ ๊ฑฐ๋ฆฌ
- CompetitionOpenSinceMonth: ๊ฐ์ฅ ๊ฐ๊น์ด ๊ฒฝ์์ ์ฒด ์คํ ์
- CompetitionOpenSinceYear: ์คํ ๋ ๋
- Promo2: ์ง์์ ์ธ(์ฃผ๊ธฐ์ ์ธ) ํ๋งค์ด์ง ํ์ฌ ์ฌ๋ถ
- Promo2SinceWeek/ promo2SinceYear: ํด๋น ์์ ์ด promo2๋ฅผ ํ๊ณ ์๋ค๋ฉด ์ธ์ ์์ํ๋์ง
- PromoInterval: ์ฃผ๊ธฐ๊ฐ ์ด๋ป๊ฒ ๋๋์ง
train = pd.merge(train, store, on=['Store'], how='left')
test = pd.merge(test, store, on=['Store'], how='left')
Store ์ปฌ๋ผ์ ๊ธฐ์ค์ผ๋ก train, test ๋ฐ์ดํฐ์ ๊ณผ store ๋ฐ์ดํฐ์ ์ ํฉ๋ณํด ์ค๋ค.
- CompetitionOpen ์ปฌ๋ผ ์์ฑ
: ๊ฒฝ์์ ์ฒด๊ฐ ์ธ์ ๊ฐ์ฅํ๋์ง (ํด๋น ๊ฐ๊ฒ ์ด์ ๊ฐ์ฅ: ์์, ์ดํ ๊ฐ์ฅ: ์์)
train['CompetitionOpen'] = 12*( train['year'] - train['CompetitionOpenSinceYear'] ) + \
(train['month'] - train['CompetitionOpenSinceMonth'])
test['CompetitionOpen'] = 12*( test['year'] - test['CompetitionOpenSinceYear'] ) + \
(test['month'] - test['CompetitionOpenSinceMonth'])
ํด๋น ๊ฐ๊ฒ๊ฐ ๊ฐ์ฅํ ๋ ๋์์ ๊ฒฝ์์ ์ฒด๊ฐ ๊ฐ์ฅํ ๋ ๋๋ฅผ ๋บ ํ 12๋ฅผ ๊ณฑํ๋ฉด ๊ฐ์ ์๋ก ๋ณํํ ์ ์๋ค. ์ด๋ฅผ ํด๋น ๊ฐ๊ฒ ๊ฐ์ฅ ๋ฌ์์ ๊ฒฝ์์ ์ฒด ๊ฐ์ฅ ๋ฌ์ ์ฐจ์ด์ ๋ํด์ฃผ๋ฉด ํด๋น ๊ฐ๊ฒ๋ฅผ ๊ธฐ์ค์ผ๋ก ์ธ์ ๊ฐ์ฅํ๋์ง ์ ์ ์๋ค.
- PromoOpen ์ปฌ๋ผ ์์ฑ
: ํด๋น ๊ฐ๊ฒ ๊ฐ์ฅ ํ ๋ช๊ฐ์ ํ์ ํ๋ก๋ชจ์ 2๊ฐ ์์๋์๋์ง
train['WeekOfYear'] = train['Date'].dt.weekofyear # ํ์ฌ ๋ ์ง๊ฐ ๋ช๋ฒ์งธ ์ฃผ์ธ์ง
test['WeekOfYear'] = test['Date'].dt.weekofyear
ํ๋ก๋ชจ์ 2์ ๋ํ ๋ ์ง ์ ๋ณด๊ฐ ๋ ๋(Year)์ ์ฃผ(Week)๋ก ๋์ด์๊ธฐ ๋๋ฌธ์ Date์ปฌ๋ผ์์ ๋ ์ง๊ฐ ๋ช๋ฒ์งธ ์ฃผ์ธ์ง ๊ณ์ฐํ์ฌ WeekOfYear ์ปฌ๋ผ์ ์ ์ฅํด ์ค๋ค.
train['PromoOpen'] = 12* ( train['year'] - train['Promo2SinceYear'] ) + \
(train['WeekOfYear'] - train['Promo2SinceWeek']) / 4
test['PromoOpen'] = 12* ( test['year'] - test['Promo2SinceYear'] ) + \
(test['WeekOfYear'] - test['Promo2SinceWeek']) / 4
์ด์ ๊ณผ ๊ฐ์ด ๋ ๋๋ฅผ ๊ฐ์์๋ก ๋ฐ๊ฟ์ฃผ๊ณ , ์ฃผ๋ฅผ 4๋ก ๋๋์ด ๊ฐ์์๋ก ๋ณํํด ์ค๊ฒ์ ๋ํ์ฌ ๊ฐ์ฅ ํ ๋ช๊ฐ์ ๋ค์ ํ๋ก๋ชจ์ 2๊ฐ ์งํ๋์๋์ง์ ๋ํ ๊ฐ์ ์๊ฐ ๋์ค๊ฒ ๋๋ค.
- ์ํซ์ธ์ฝ๋ฉ ( get_dummies() )
train.dtypes
๋ฐ์ดํฐํ์ ์ ํ์ธ ํด ๋ณด๋ฉด object์ธ ์ปฌ๋ผ์ด 3๊ฐ์ง ์๋ค. 3๊ฐ์ ์ปฌ๋ผ์ get_dummies๋ฅผ ์ด์ฉํ์ฌ ์ํซ์ธ์ฝ๋ฉ ํด์ค๋ค.
train = pd.get_dummies(columns=['StoreType'],data=train)
test = pd.get_dummies(columns=['StoreType'],data=test)
train = pd.get_dummies(columns=['Assortment'],data=train)
test = pd.get_dummies(columns=['Assortment'],data=test)
train = pd.get_dummies(columns=['PromoInterval'],data=train)
test = pd.get_dummies(columns=['PromoInterval'],data=test)
train.columns
test.columns
train column๊ณผ test column ์ด ๋์ผํ ๊ฒ์ ํ์ธํ์๋ค.
- ๋ชจ๋ธ๋ง
input_var = ['Promo', 'SchoolHoliday',
'StateHoliday_0', 'StateHoliday_a', 'StateHoliday_b', 'StateHoliday_c',
'weekday', 'year', 'month', 'CompetitionDistance',
'Promo2',
'CompetitionOpen', 'WeekOfYear',
'PromoOpen', 'StoreType_a', 'StoreType_b', 'StoreType_c', 'StoreType_d',
'Assortment_a', 'Assortment_b', 'Assortment_c',
'PromoInterval_Feb,May,Aug,Nov', 'PromoInterval_Jan,Apr,Jul,Oct',
'PromoInterval_Mar,Jun,Sept,Dec']
ํ์์๋ ์ปฌ๋ผ์ ์ญ์ ํ๊ณ input_var์ ์ ์ฅํด ์ค๋ค.
set(train) - set(input_var)
(์ฐธ๊ณ ) input_var์ ๋ค์ด๊ฐ์ง ์์ ์ปฌ๋ผ๋ค ๋ชฉ๋ก์ด๋ค.
xgb = XGBRegressor( n_estimators=300, learning_rate= 0.1, random_state=2020)
xgb.fit(train[input_var],train['Sales'])
์๊ณผ ๋์ผํ๊ฒ xgb ๋ชจ๋ธ์ ์ฌ์ฉํ๋ค.
cross_val_score(xgb, train[input_var], train['Sales'], scoring="neg_mean_squared_error", cv=3)
store ๋ฐ์ดํฐ์ ์ ํฉ๋ณํ์ฌ ์ ์ฒ๋ฆฌ ํ ๋ชจ๋ธ๋ง์ ํ๋๋ ์ค๋ฅ์จ์ด ๋ํญ ํ๋ฝํ์๋ค.
- ๋ณ์์ค์๋
imp_df = pd.DataFrame({'var':input_var,
'imp':xgb.feature_importances_})
imp_df = imp_df.sort_values(['imp'],ascending=False)
plt.bar(imp_df['var'],
imp_df['imp'])
plt.xticks(rotation=90)
plt.show()
๋ณ์์ค์๋๋ฅผ ์๊ฐํ ํด๋ณด์๋๋, ๋ชจ๋ ๋ณ์๋ฅผ ์ฌ์ฉํ๋ ๊ฒ๋ณด๋ค ์ ํํด์ ํ์ตํ๋ ๊ฒ์ด ์ข์ ๊ฒ ๊ฐ๋ค๊ณ ํ๋จ๋๋ค.
score_list=[]
selected_varnum=[]
for i in range(1,25):
selected_var = imp_df['var'].iloc[:i].to_list()
scores = cross_val_score(xgb,
train[selected_var],
train['Sales'],
scoring="neg_mean_squared_error", cv=3)
score_list.append(-np.mean(scores))
selected_varnum.append(i)
print(i)
plt.plot(selected_varnum, score_list)
์ง์์ ์ผ๋ก ํ๋ฝํ๋ ๊ฒฝํฅ์ ๋ณด์ด์ง๋ง 17๊ฐ ์ดํ๋ก ๋น์ทํ ๊ฒ ๊ฐ์ด ๋ณด์ธ๋ค. ๋ฐ๋ผ์ 17๊ฐ๊น์ง ์ ํํ์ฌ ํ์ต์ ์งํํด ๋ณธ๋ค.
input_var = imp_df['var'].iloc[:17].tolist()
xgb.fit(train[input_var],
train['Sales'])
cross_val_score(xgb, train[input_var], train['Sales'], scoring="neg_mean_squared_error", cv=3)
์ ์ฒด์ ์ผ๋ก ์ค๋ฅ์จ์ด ์ค์ด๋ค์๋ค.
3. ํ๋ผ๋ฏธํฐ ํ๋
estim_list = [100,200,300,400,500,600,700,800,900]
score_list = []
for i in estim_list:
xgb = XGBRegressor( n_estimators=i, learning_rate= 0.1, random_state=2020)
scores = cross_val_score(xgb, train[input_var], train['Sales'], scoring="neg_mean_squared_error", cv=3)
score_list.append(-np.mean(scores))
print(i)
plt.plot(estim_list,score_list)
plt.xticks(rotation=90)
plt.show()
n_estimators๋ฅผ ๋ฐ๊ฟ๊ฐ๋ฉฐ ์ค๋ฅ์จ์ ๊ณ์ฐํ ๊ฒ์ ์๊ฐํ ํด๋ณด์๊ณ , n_estimators=400์ผ๋ก ํ๋ ๊ฒ์ด ์ ๋นํด ๋ณด์ธ๋ค.
xgb = XGBRegressor( n_estimators=400, learning_rate= 0.1, random_state=2020)
xgb.fit(train[input_var],
train['Sales'])
cross_val_score(xgb, train[input_var], train['Sales'], scoring="neg_mean_squared_error", cv=3)
400์ผ๋ก ๋ณ๊ฒฝํ์๋๋ ์ค๋ฅ์จ์ด ๋ฎ์์ก๋ค.
์์ฝ๊ฒ๋ ํ๋ผ๋ฏธํฐ ํ๋์ ํ ์ดํ๋ก ์บ๊ธ์์ ํ ์คํธ ๋ฐ์ดํฐ์ ์ ์ค๋ฅ์จ์ด ๋ ๋๊ฒ ๋์๋ค. ์ด์ธ์ ๊ฒฐ์ธก๊ฐ, ์ด์์น ๋ฑ feature engineering์ ์ง์์ ์ผ๋ก ์๋ํด ๋ณด์์ผ๊ฒ ๋ค. (์ถํ github ์ ๋ก๋ ์์ )