๐คณ ์์ ํฌ์คํ ์์ 'ํน์ฑ๊ณตํ(feature engineering)'์ด ๋ฌด์์ธ์ง์ ๋ํด ๊ฐ๋ตํ๊ฒ ๊ฐ๋ ํ์ต์ ํ์๋ค.
FE - Feature Engineering
1. Concepts * In real world, data is really messy - we need to clean the data * FE = a process of extracting useful features from raw data using math, statistics and domain knowledge - ์ฆ, ๋๋ฉ..
sh-avid-learner.tistory.com
๐โ๏ธ ์ฐ๋ฆฌ๊ฐ ์ค์ํ์ data๋ฅผ ๊ฐ์ง๊ณ ๋ชจ๋ธ๋งํ๋ machine learning์ ์ธ๊ณ์์ ๋ฌด์ํ ๋ง์ feature๋ฅผ ๋ง๋ ํ ๋ฐ, ์ด ๋ชจ๋ feature๋ฅผ modeling์ ๋์ ํ๋ฉด model์ด ํฐ์ง๋ค..? ๊ธฐ์กด ์ฐ๋ฆฌ๊ฐ ์ํ๋ ๋ฐฉ์์ model์ ์ฑ๋ฅ์ด ์๋์ฌ ํ๋ฅ ์ด ๋๋ค. ์ต๋ํ ์ค์ํ feature๋ง ๋จ๊ฒจ๋๊ฑฐ๋, ๊ธฐ์กด์ ์ฃผ์ด์ง feature๋ค ์ผ๋ถ๋ฅผ domain knowledge์ ์ํด ์ฌ์กฐํฉํด ์ค์ํ feature๋ฅผ ๋ง๋๋ feature๋ฅผ ์ด์ฉํ ์ฌ๋ฌ ์์ ์ ํจ์ผ๋ก์จ ์ฐ๋ฆฌ๋ modeling์ ์ฑ๋ฅ์ ๋์ผ ์ ์๋ค๊ณ ๋ณธ๋ค.
๐ ์ด๋ฒ ํฌ์คํ ์ ํตํด ์ฐ๋ฆฌ๋ feature selection - ์ฆ '์ค์ํ ํน์ฑ๋ง ๋ฝ์๋ด๋ ์ฌ๋ฌ๊ฐ์ง ๋ฐฉ๋ฒ' ์ค ๊ทธ ์ฒซ๋ฒ์งธ, selectKBest()๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๋ํด ์์๋ณด๋ ค ํ๋ค!
โท selectKBest docu โ
class sklearn.feature_selection.SelectKBest(score_func=<function f_classif>, *, k=10)
๐ sklearn์์ ์ ๊ณตํ๋ feature_selection module์์๋ ๋ค์ํ ํํ์ method๋ฅผ ์ ๊ณตํด์ค๋ค. ๊ทธ ์ค selectKBest()๋ univariate feature selection์ ์ผ๋ถ๋ถ์ผ๋ก ๋ชจ๋ feature๋ค ๊ฐ๊ฐ ํ ๊ฐ์ฉ target์ ์ํฅ์ ์ค๋ค๊ณ ๊ฐ์ (๊ฐ feature๋ค์ด target๊ณผ์ ์ฐ๊ด์ฑ์ ๋ ๋ฆฝ์ ์ผ๋ก ํ๊ฐ๋จ)ํ ๋(๊ทธ๋์ univariate์ด๋ค. multivariate์ด๋ฉด scoringํ ๋ ๋ ๊ฐ ์ด์์ ๋ณ์๊ฐ ๋์์ target์ ์ํฅ์ ์ค๋ค๊ณ ๊ฐ์ ํ๊ณ ์์ํ๋ค), ์ด ๋์ ์ํฅ ์ ๋๋ฅผ, ์ํ๋ scoring method๋ก ์ ์๋ฅผ ๋งค๊ฒจ์ ๊ฐ์ฅ ์ ์๊ฐ ๋๊ฒ ๋์จ feature๋ค k๊ฐ๋ง (default๋ 10๊ฐ) ์ ํํ๋ ํจ์์ด๋ค.
'Univariate feature selection works by selecting the best features based on univariate statistical tests. It can be seen as a preprocessing step to an estimator. Scikit-learn exposes feature selection routines as objects that implement the transform method'
selectKBest removes all but the K highest scoring features
๐ ์ฌ๊ธฐ์ target ์์ฑ์ ๋ฐ๋ผ, ์ฆ regression์ธ์ง classification์ธ์ง์ ๋ฐ๋ผ ์ ์ฉํ๋ score_func๊ฐ ๋ค๋ฅด๋ค
→ regression) f_regression / mutual_info_regression
→ classification) chi2 / f_classif / mutual_info_classif
'The methods based on F-test estimate the degree of linear dependency between two random variables'
= f-๋ถํฌ๋ฅผ ๊ฐ์ ํ๊ณ ๋ ๋ณ์๊ฐ์ ์ ํ์ ์์กด์ฑ ์ ๋๋ฅผ ์ฐ์ถํ๋ (์์ f_๊ฐ ๋ถ์ผ๋ฉด) scoring method์ด๋ค.
<<๋ค์ํ score_func>>
Q. categorical type data๊ฐ ์์ผ๋ฉด selectKBest๋ฅผ ์ํํ ์ ์์๊น?
A. ์ด๋ ต๋ค
→ ๊ฐ์ข docu์ ๋ง์ article๋ค Q&A๋ฅผ ์ฐพ์๋ดค์ง๋ง, categorical data type์ ๋ฐ๋ก one-hot ๋๋ ordinal ๋ฑ๋ฑ encoded๋๋ ๊ณผ์ ์ด ๊ฑฐ์น์ง ์๋๋ค๋ฉด selectKBest ์ํ์ด ์ด๋ ค์.
→ ๋ฐ๋ผ์ selectKBest ๊ณผ์ ์ด์ ์ ๋จผ์ encodingํ๋ ์ ์ฒ๋ฆฌ ๊ณผ์ ์ ๊ฑฐ์น๊ณ ๋ ๋ค ์ํ ์ถ์ฒ!
→ ์๋ฌ๋ ์๋์ ๊ฐ์ด ๋ธ
'ValueError: Unable to convert array of bytes/strings into decimal numbers with dtype='numeric'
FutureWarning: Arrays of bytes/strings is being converted to decimal numbers if dtype='numeric'. This behavior is deprecated in 0.24 and will be removed in 1.1 (renaming of 0.26). Please convert your data to numeric values explicitly instead.
X = check_array('
(+) numeric data๋ผ๋ฉด discrete & continuous ๋ชจ๋ selectKBest ์ํ ๊ฐ๋ฅ
-- ์ง์ ์์์ ํจ๊ป! --
โ ์ํ๋ scoring method์ kBest๋ฅผ import
from sklearn.feature_selection import f_regression, SelectKBest
โก selector ๊ฐ์ฒด ์ ์ (์ฆ ์ด๋ค method๋ก ๋ช ๊ฐ๋ฅผ ๋ฝ์ ๊ฑด์ง ๋ฝ์ผ๋ ค๋ '์ผ์ข ์ ์๋ด์(๊ฐ์ฒด)' ๋ง๋ค๊ธฐ)
selector = SelectKBest(score_func=f_regression, k=10)
โข ํด๋น ์๋ด์๋ฅผ ๊ฐ์ง๊ณ train, test (val๋ ์๋ค๋ฉด ๋ชจ๋) ๋๋ ์ ์ฒด data์ ์ ์ฉ
(์ฒ์์๋ fit_transform → transform - fit๋ ํ ๋ฒ๋ง ํด์ selectํ๋ ๋ฐฉ๋ฒ์ ์ ์ฉ์ํค๋ฉด ์ดํ transform๋ง ์ํํ๋ฉด ๋จ!)
## ํ์ต๋ฐ์ดํฐ์ fit_transform
X_train_selected = selector.fit_transform(X_train, y_train)
## ํ
์คํธ ๋ฐ์ดํฐ๋ transform
X_test_selected = selector.transform(X_test)
โฃ ๊ฐ์๋ feature๋ค ๊ฒฐ๊ณผ data shape() ํ์ธ
(์ด์ X_train_selected๋ก modeling์ ์ํํ๋ฉด ๋๋ค.)
X_train_selected.shape, X_test_selected.shape
++ selector ์ ์ฉํ method ์ดํด๋ณด๊ธฐ ++
get_support()
** ์ค์! get_support()๋ ์ด๋ค ํน์ฑ๋ค์ด ์ ํ๋์๋ ์ง, ์ ํ๋๋ฉด True, ์๋๋ฉด False๋ฅผ ๋ฐํํด์ค๋ค. ๋ฐ๋ผ์ ํด๋น method๋ฅผ ํตํด ์ด๋ค ํน์ฑ๋ค์ด ์ ํ๋์๋ ์ง ์ ์ ์๋ค.
selected_mask = selector.get_support()
all_names = X_train.columns
## ์ ํ๋ ํน์ฑ๋ค
selected_names = all_names[selected_mask]
## ์ ํ๋์ง ์์ ํน์ฑ๋ค
unselected_names = all_names[~selected_mask]
๊ทธ ์ธ fit()์ transform()์ ํ์ฉํด์ X์ y๋ฅผ ์ง์ด๋ฃ์ด ์๋ง๋ feature๋ค์ ์ ํํ๋ค
++ ์ถ๊ฐ) ๊ฐ์ฅ score๊ฐ ๋๊ฒ ๋์จ attribute ์ถ๋ ฅํ๊ธฐ
<< numpy.argmax()>> ์ฌ์ฉ!
selector.feature_names_in_[selector.scores_.argmax()]
<<top n๊ฐ์ score๋์จ attribute ์ถ๋ ฅํ๋ ค๋ฉด .argsort()[-n:]>>
selector.feature_names_in_[selector.scores_.argsort()[-n:]]
#n๊ฐ์ top score features
<<๋ค์์ n๊ฐ์ ๊ฐ์ฅ ์ ์ score๋ค์ด ๋์จ attribute ์ถ๋ ฅํ๋ ค๋ฉด .argsort()[:n]>>
selector.feature_names_in_[selector.scores_.argsort()[:n]]
#score๊ฐ ์ ์ n๊ฐ์ feature names
++ seaborn - jointplot์ผ๋ก ๋ ๋ณ์๊ฐ์ correlation ์๊ฐํ ++
โฝ jointplot docu โฝ
https://seaborn.pydata.org/generated/seaborn.jointplot.html
seaborn.jointplot(*, x=None, y=None, data=None, kind='scatter', color=None, height=6, ratio=5, space=0.2, dropna=False, xlim=None, ylim=None, marginal_ticks=False, joint_kws=None, marginal_kws=None, hue=None, palette=None, hue_order=None, hue_norm=None, **kwargs)
๐ค "Draw a plot of two variables with bivariate and univariate graphs"
โซ ์ฃผ๋ก ์์นํ ์ฐ์ํ ๋ ๋ณ์๊ฐ์ ๊ด๊ณ๋ฅผ ์ก์์ผ๋ก ๋ฐ๋ก ํ์ ํ๊ณ ์ถ์ ๋ ์ฌ์ฉํ๋ค!
"kind{ “scatter” | “kde” | “hist” | “hex” | “reg” | “resid” }"
โซ ์ฌ๋ฌ ์ข ๋ฅ์ graph๋ก ๋ ๋ณ์๊ฐ์ ๊ด๊ณ๋ฅผ jointplot์ ๋ํ๋ผ ์ ์์ผ๋ฉฐ ์ฃผ๋ก numerical bivariates' correlation์ ๋ํ๋ด๊ธฐ ์ํด ํ๊ท์ ์ด scatterplot์ ํฌํจ๋ ํํ๋ก ๋ง์ด ์ฌ์ฉํ๋ค (kind = 'reg')
์์ ) <k selection์ ๋ฐ๋ฅธ ์ฑ๋ฅ ์คํ>
Q. ์ฃผ์ด์ง car price data์ ๋ง๋ค์ด์ง MLR ๋ชจ๋ธ์์ car price๋ฅผ ๊ฒฐ์ ์ง์ ์ ์ฉํ ๋ณ์๋ค๋ง f_regression์ ์ํด ๋ช ๊ฐ๋ฅผ ๋ฝ๋๊ฒ ์ข์ ์ง selectKBest์ ์ํด์ ๊ตฌํ๋ feature selection์ ์งํํ๋ค. ์ดํ ๊ฒฐ์ ํ evaluation metric์ ์ํด feature selection ์ด์ ๊ณผ ์ดํ ์ผ๋ง๋ MLR ๋ชจ๋ธ ์ฑ๋ฅ์ด ์ข์์ก๋์ง ์์น๋ฅผ ํตํด ํ์ธํ์. the number of features์ ๋ฐ๋ฅธ error ์์น์ ๋ณํ๋ฅผ ๊ทธ๋ํ๋ก ์๊ฐํํ๊ณ ๊ณผ์ ํฉ์ด ์ผ์ด๋์ง ์๋ ์ต์ ์ ๋ชจ๋ธ ์ฑ๋ฅ์ ๋ณด์ด๋ feature์ ๊ฐ์ ๋ฐ ํด๋น ์ ํ๋ feature์ ์ข ๋ฅ๋ฅผ ๊ตฌํด๋ณด์.
(+์ถ๊ฐ ์์ - jointplot ์๊ฐํ๋ฅผ ๊ทผ๊ฑฐ๋ก selectKBest์ ์ํด selected๋ feature์ ์ ๋น์ฑ์ ๋ณด์ด์)
A.
1> import & dataset ์ค๋น
import pandas as pd
import matplotlib
import seaborn as sns
import numpy as np
import matplotlib.pyplot as plt
path = 'https://cf-courses-data.s3.us.cloud-object-storage.appdomain.cloud/IBMDeveloperSkillsNetwork-DA0101EN-SkillsNetwork/labs/Data%20files/module_5_auto.csv'
df = pd.read_csv(path)
df.to_csv('module_5_auto.csv')
df=df._get_numeric_data()
2> train / test set ๋๋๊ธฐ & target๊ณผ ๊ทธ ์ด์ธ์ data๋ก ๋๋๊ธฐ
train = df.sample(frac=0.75,random_state=1)
test = df.drop(train.index)
train.dropna(inplace=True)
test.dropna(inplace=True)
target = 'price' #y๋ car price data
## X_train, y_train, X_test, y_test ๋ฐ์ดํฐ๋ก ๋ถ๋ฆฌ
X_train = train.drop(columns=target)
y_train = train[target]
X_test = test.drop(columns=target)
y_test = test[target]
3> evaluation metrics๋ r2 score & MAE / ๊ทธ๋ฆฌ๊ณ 1๊ฐ๋ถํฐ ์ ์ฒด column๊น์ง ์ฐจ๋ก๋ก selectKBest ๋๋ ค ๊ฐ๊ฐ์ training set & test set์ ์งํ ๊ฒฐ๊ณผ ์๊ฐํํ๊ธฐ
from sklearn.feature_selection import f_regression, SelectKBest
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_absolute_error, r2_score
training=[]
testing=[]
feature_names = []
x = range(1, len(X_train.columns)+1)
for num in range(1, len(X_train.columns)+ 1):
selector = SelectKBest(score_func=f_regression, k=num)
X_train_selected = selector.fit_transform(X_train, y_train)
X_test_selected = selector.transform(X_test)
selected_mask = selector.get_support()
selected_names = all_names[selected_mask]
feature_names.append(selected_names)
model = LinearRegression()
model.fit(X_train_selected, y_train)
y_train_pred = model.predict(X_train_selected)
train_mae = mean_absolute_error(y_train, y_train_pred)
training.append(train_mae)
y_test_pred = model.predict(X_test_selected)
test_mae = mean_absolute_error(y_test,y_test_pred)
testing.append(test_mae)
plt.plot(x, training, label='Training Score', color='b')
plt.plot(x, testing, label='Testing Score', color='g')
plt.axvline(6.0, 0, 1, color='red', linestyle='--', linewidth=2)
plt.ylabel("MAE ($)")
plt.xlabel("Number of Features")
plt.title('Validation Curve')
plt.legend()
plt.show()
print('------selected feature names------')
for a in feature_names[5].values[0:6]:
print(a)
4> ๊ฒฐ๊ณผ ํด์
๐งธ validation curve ์๊ฐํ ๊ฒฐ๊ณผ(MAE)๋ฅผ ๋ณด์์ ๋ feature ๊ฐ์๊ฐ ๋์ด๋ ์๋ก ์ด์ ๊ณผ์ ํฉ๋์ด error๊ฐ ๊ฒฐ๊ตญ์ ์ญ ๊ฐ์ํ๋ ๊ฒ์ ๋ณผ ์ ์๋ค. ํ์ง๋ง overfitting์ ๋ฌธ์ & ๋ชจ๋ธ training time์ ๊ฐ์ ํจ์จ์ฑ์ ์ํด features ์๊ฐ ์ ๊ฒ ์ ํ๋๋ ๊ฒ ์ข๊ธฐ ๋๋ฌธ์ error๊ฐ ํฐ ํญ์ผ๋ก ๊ฐ์ํ๋ ์์ ์ธ, features ์๊ฐ 6๊ฐ์ผ ๋๊ฐ ์ต์ ์ feature selection (selectKBest()๋ก๋ง ๋ณด์์ ๋)๋ผ๊ณ ํ๋จํ ์ ์๋ค. ์ฌ๊ธฐ์ test set error๊ฐ ์ ์ผ ์ ์ 20์ด ์ ์ผ ์ข์ ๊ฒ์ด ์๋๊ฐ ๋ผ๊ณ ์๊ฐํ ์ ์์ง๋ง ์ฌ๊ธฐ์์ test set์ validation ๊ฐ๋ ์ด๋ฉฐ, ์ถํ ๊ทธ ์ด๋ค ์๋ก์ด ๊ฐ๋ ์ test set์ด ์๋ ์์ ๊ฐ์ด ๋ฌด์กฐ๊ฑด error๊ฐ ์ ๊ฒ ๋์จ๋ค๊ณ ๋ณด์ฅ์ด ์ด๋ ต๊ณ ๋ ์ค์ ์ธ๊ณ์์๋ ์ด๋ ๊ฒ ์์ธก ๊ฐ๋ฅ์ฑ ์ค๋ช ๋ ฅ์ด ๋์ ๊ฒฝ์ฐ๊ฐ ๋๋ฌผ๊ธฐ ๋๋ฌธ์ ์ต์ feature ์์ ์ ์ ๊ฐ ๋ด์์ selectํ๋ ๊ฒ์ด ์ต์ ์ด๋ผ๊ณ ์๊ฐ๋๋ค. r-squared ์๊ฐํ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์์ ๋๋ test set line์์ ๊ฒฐ์ ๊ณ์๊ฐ์ด ๊ฐ์์ค๋ฝ๊ฒ ์ฆ๊ฐํ feature๊ฐ 6๊ฐ์ผ ๋์ ์ง์ ์ด ์ ์ผ ์ต์ ์ด๋ผ ์๊ฐํ๋ฉฐ ์ดํ r-sqaured ๊ฒฐ์ ๊ณ์๊ฐ ์ํญ ์ฆ๊ฐํ๊ธด ํ๋ ๊ทธ ์ ๋๊ฐ ์ฝํ๋ฏ๋ก ๊ทธ ์ํฅ์ ๋ฐฐ์ ํด๋ ์ถฉ๋ถํ๋ค๊ณ ํ๋จ๋๋ค. ๐งธ
(++ r-squared & MAE ๊ด๋ จ ์ค๋ฅ ์งํ ์์ธํ ๋ด์ฉ์ ์๋ ํฌ์คํ ์ฐธ์กฐ ++ - ์ถํ adjusted-R metric๋ ๋ค๋ฃฐ ์์ - โ๏ธ )
All About Evaluation Metrics(1/2) → MSE, MAE, RMSE, R^2
** ML ๋ชจ๋ธ์ ์ฑ๋ฅ์ ์ต์ข ์ ์ผ๋ก ํ๊ฐํ ๋ ๋ค์ํ evaluation metrics๋ฅผ ์ฌ์ฉํ ์ ์๋ค๊ณ ํ์! ** (supervised learning - regression problem์์ ๋ง์ด ์ฐ์ด๋ ํ๊ฐ์งํ๋ค) - ๊ณผ์ (5) - ๐ ๊ทธ๋ฌ๋ฉด ์ฐจ๊ทผ์ฐจ..
sh-avid-learner.tistory.com
→ code ๊ฒฐ๊ณผ ์ต์ ์ 6๊ฐ feature๋ 'width & curb-weight & engine-size & horsepower & highway-mpg' & 'city-L/100km'
5> jointplot์ผ๋ก ์ ํ๋ ํน์ฑ๊ณผ target๊ณผ์ ํ๊ท์ ์๊ฐํ (scatterplot ํฌํจ)
<์ ์ ํ๋ ํน์ฑ ์ค horsepower, ๊ทธ๋ฆฌ๊ณ ์ ํ ์๋ ํน์ฑ ์ค compression-ratio๋ฅผ ๊ฐ๊ฐ jointplot์ผ๋ก ์๊ฐํํ ๊ฒฐ๊ณผ>
#code source by Bhavesh Bhatt
from scipy import stats
from scipy.stats.stats import pearsonr
def plot_join_plot(df, feature, target):
j = sns.jointplot(feature, target, data=df, kind='reg')
#j.annotate(stats.pearsonr) ์ฌ๋ผ์ง..
return plt.show()
train_df = pd.concat([X_train, y_train], axis=1)
plot_join_plot(train_df, 'compression-ratio','price')
plot_join_plot(train_df, 'horsepower','price')
๐ horsepower๋ ์ ํ๋ ํน์ฑ์ ๋ง๊ฒ price์ ๋ฐ๋ฅธ ์์ ์๊ด๊ด๊ณ๋ฅผ ๋์ฒด์ ์ผ๋ก ๋ณด์ฌ์ฃผ๋๋ฐ ๋ฐํด, compression-ratio๋ ํ๊ท์ ์ ๊ธฐ์ธ๊ธฐ๊ฐ ๊ฑฐ์ 0์ผ๋ก price์ ๋ณํ์ ๋ฐ๋ฅธ compression-ratio ๋ณํ๊ฐ ๊ฑฐ์ ์๋ค๊ณ ๋ด๋ ๋ฌด๋ฐฉํ๊ธฐ ๋๋ฌธ์ selectKBest๊ฐ ์ ํ๋ ํน์ฑ์์ ์ ์ธํ๋ค๊ณ ๋ณผ ์ ์๋ค.
- ๋ ๋ค์ํ feature selection ๊ธฐ๋ฒ ์ถํ ํฌ์คํ ์์ ๐ฆพ -
* ์ถ์ฒ) https://www.kaggle.com/jepsds/feature-selection-using-selectkbest
* kBest ์ถ์ฒ) https://www.youtube.com/watch?v=UW9U0bYJ-Ys
* jointplot - ์ถ์ฒ) https://www.geeksforgeeks.org/python-seaborn-jointplot-method/
'Machine Learning > Fundamentals' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
PCA(concepts) (0) | 2022.05.30 |
---|---|
Feature Selection vs. Feature Extraction (0) | 2022.05.18 |
Ordinal Encoding (0) | 2022.04.20 |
train vs. validation vs. test set (0) | 2022.04.18 |
Gradient Descent (concepts) (+momentum) (0) | 2022.04.18 |
๋๊ธ