Codelog
[AIB] One Hot Encoding, Feature Selection, Ridge Regression ๋ณธ๋ฌธ
[AIB] One Hot Encoding, Feature Selection, Ridge Regression
minzeros 2022. 3. 30. 17:10๐ก One-hot Encoding
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
df = pd.DataFrame({
'City' : ['Seoul', 'Seoul', 'Seoul', 'Busan', 'Busan', 'Busan', 'Incheon', 'Incheon', 'Seoul', 'Busan', 'Incheon'],
'Room' : [3, 4, 3, 2, 3, 3, 3, 3, 3, 3, 2],
'Price' : [55000, 61000, 44000, 35000, 53000, 45000, 32000, 51000, 50000, 40000, 30000]
})
# ๋ฐ์ดํฐ ํ์ธ
df
output :
City ์ปฌ๋ผ์ ์๋ ๋ฐ์ดํฐ๋ ๋์ ์ง์ญ์ ๊ตฌ๋ถํ๋ ๋ฒ์ฃผํ ๋ณ์ (Categorical variable)์ด๋ค.
๋ฒ์ฃผํ ์๋ฃ๋ ์์๊ฐ ์๋ ๋ช ๋ชฉํ(Nominal)๊ณผ ์์๊ฐ ์๋ ์์ํ(Ordinal)๋ก ๋๋๋ค.
City ์ปฌ๋ผ์ ๋ช ๋ชฉํ ๋ฒ์ฃผํ ๋ณ์๋ก ๋ณผ ์ ์๋ค.
City ์ปฌ๋ผ์ฒ๋ผ ๋ฌธ์์ด(String) ๋ณ์๋ฅผ ์ฒ๋ฆฌํด์ผ ํ ๋, ์ธ์ฝ๋ฉ ๋ฐฉ์์ ํ์ฉํ๋ค.
์ํซ์ธ์ฝ๋ฉ์ผ๋ก ๋ฒ์ฃผํ ๋ฐ์ดํฐ๋ฅผ ๋ณํํ๋ ๋ชจ์๋๋ ์๋์ ๊ฐ๋ค.
City | -> | Seoul | Busan | Incheon |
Seoul | 1 | 0 | 0 | |
Busan | 0 | 1 | 0 | |
Incheon | 0 | 0 | 1 |
์ํซ์ธ์ฝ๋ฉ์ ์ํํ๋ฉด ๊ฐ ์นดํ ๊ณ ๋ฆฌ์ ํด๋นํ๋ ๋ณ์๋ค์ด ๋ชจ๋ ์ฐจ์(์ปฌ๋ผ)์ ๋ํด์ง๊ฒ ๋๋ค.
๋ฐ๋ผ์ ์นดํ ๊ณ ๋ฆฌ๊ฐ ๋๋ฌด ๋ง์ ๊ฒฝ์ฐ(high cardinality)์๋ ์ฌ์ฉํ๊ธฐ ์ ํฉํ์ง ์๋ค.
โจ ์ํซ์ธ์ฝ๋ฉ ์์
# category_encoders ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฌ์ฉ
!pip install category_encoders
from category_encoders import OneHotEncoder
features = ['City', 'Room']
target = 'Price'
# ํ๋ จ/ํ
์คํธ ๋ฐ์ดํฐ ๋ถ๋ฆฌ
X_train = df[features][:8]
y_train = df[target][:8]
X_test = df[features][8:]
y_test = df[target][8:]
# ์ํซ์ธ์ฝ๋ฉ
encoder = OneHotEncoder(use_cat_names=True)
X_train = encoder.fit_transform(X_train)
X_test = encoder.fit_transform(X_test)
X_train.head()
output :
X_test
output :
๐ก ํน์ฑ ์ ํ (Feature Selection)
ํน์ฑ๊ณตํ์ ๊ณผ์ ์ ์ ํฉํ ํน์ฑ์ ๋ง๋ค์ด ๋ด๋ ๊ณผ์ ์ด๋ค.
๊ทธ ์ค์์ ํน์ฑ ์ ํ์ด ์กด์ฌํ๋๋ฐ ์ข์ ํน์ฑ์ ์ ํํ๋ ๋ฐฉ๋ฒ์
ํน์ฑ๋ผ๋ฆฌ์ ์๊ด๋๋ ๋ฎ์ผ๋ฉด์, ํ๊ฒ๊ณผ์ ์๊ด๋๊ฐ ํฐ ํน์ฑ ์กฐํฉ์ ์ ํํ๋ ๊ฒ์ด๋ค.
โจ ํน์ฑ ์ ํ ์์
ํน์นด์ดํฐ ์ฃผํ ๊ฐ๊ฒฉ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ๋ค.
# ํน์นด์ดํฐ ์ฃผํ ๊ฐ๊ฒฉ ๋ฐ์ดํฐ
df = pd.read_csv('kc_house_data.csv')
# price ๊ฐ ์์ 5%, ํ์ 5%์ธ ๋ฐ์ดํฐ ์ญ์
# np.percentile ์ฌ์ฉ
df = df[(df['price'] >= np.percentile(df['price'], 0.05)) &
(df['price'] <= np.percentile(df['price'], 0.95))]
# date ์ปฌ๋ผ์ datetime64 ํ์
์ผ๋ก ๋ณํ
df['date'] = pd.to_datetime(df['date'])
# 2015-03-01 ๋ ์ง๋ฅผ ๊ธฐ์ค์ผ๋ก ํ๋ จ/ํ
์คํธ ๋ฐ์ดํฐ๋ก ๋ถ๋ฆฌ
cutoff = pd.to_datetime('2015-03-01')
train = df[df['date'] < cutoff]
test = df[df['date'] >= cutoff]
# ํน์ฑ ์ ํ์ ํ๊ธฐ ์ , ์๋ก์ด ํน์ฑ ์์ฑ ๋ฐ ์ญ์ ์งํ = "ํน์ฑ ๊ณตํ"
def engineer_features(X):
# pandas.DataFrame.copy()
X = X.copy()
# ์์ค ๊ฐ์๋ฅผ ์ ์ํ์ผ๋ก ๋ณํ
X['bathrooms'] = X['bathrooms'].round(0).astype(int)
# ๋ฐฉ ์๋ฅผ ํฉ์ณ์ rooms ์ปฌ๋ผ์ผ๋ก ํฉ์ฐ
X['rooms'] = X['bedrooms'] + X['bathrooms']
# ์ฌ์ฉํ์ง ์์ ํน์ฑ ์ญ์
X = X.drop(['id', 'date', 'waterfront'], axis=1)
return X
train = engineer_features(train)
test = engineer_features(test)
# ๋ณ๊ฒฝ๋ ํ
์ด๋ธ ํ์ธ
train.head()
output :
from math import factorial
# n๊ฐ์ ํน์ฑ ์ค์์ k๊ฐ์ ํน์ฑ์ ๋ฝ๋ ๊ฒฝ์ฐ์ ์
def n_choose_k(n, k):
return factorial(n) / (factorial(k)*factorial(n-k))
n = len(train.columns)
combinations = sum(n_choose_k(n, k) for k in range(1, n+1))
print(combinations)
>>> 524287
k๊ฐ์ ํน์ฑ์ ์ ํํ ์ ์๋ ๊ฒฝ์ฐ์ ์๊ฐ ๋๋ฌด ๋ง์ ๋,
์ข์ ํน์ฑ๋ง ๋ฝ์์ฃผ๋ SelectKBest ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ํน์ฑ์ ์ ํํ ์ ์๋ค.
target = 'price'
X_train = train.drop(columns=target)
y_train = train[target]
X_test = test.drop(columns=target)
y_test = test[target]
# target ํน์ฑ์ธ price ์ปฌ๋ผ๊ณผ ๊ฐ์ฅ ์๊ด๋๊ฐ ๋์ feature k๊ฐ๋ฅผ ์ ํ
from sklearn.feature_selection import f_regression, SelectKBest
# SelectKBest๋ฅผ ์ฌ์ฉํ ๋ score ํจ์๋ฅผ ์ฌ์ฉํ ์ ์๋๋ฐ
# ํ๊ท ๋ฌธ์ ์์๋ f_reression ์ ์์ฃผ ์ฌ์ฉํ๋ค.
selector = SelectKBest(score_func=f_regression, k=10)
# ํ๋ จ ๋ฐ์ดํฐ์ fit_transform
X_train_selected = selector.fit_transform(X_train, y_train)
# ํ
์คํธ ๋ฐ์ดํฐ์๋ transform
X_test_selected = selector.transform(X_test)
# ์ ํ๋ ํน์ฑ ํ์ธ
all_names = X_train.columns
selected_mask = selector.get_support()
# ์ ํ๋ ์ปฌ๋ผ๋ค
selected_names = all_names[selected_mask]
# ์ ํ๋์ง ์์ ์ปฌ๋ผ๋ค
unselected_names = all_names[~selected_mask]
์ ํํ ํน์ฑ ๊ฐ์ k๋ฅผ ๊ฒฐ์ ํ๋ ๋ฐฉ๋ฒ
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_absolute_error, r2_score
training = []
testing = []
# 1 ๋ถํฐ ํน์ฑ ์ ๋งํผ ์ฌ์ฉํ ๋ชจ๋ธ์ ๋ง๋ค์ด์ MAE ๊ฐ์ ๋น๊ต ํฉ๋๋ค.
for k in range(1, len(X_train.columns)+ 1):
print(f'{k} features')
selector = SelectKBest(score_func=f_regression, k=k)
X_train_selected = selector.fit_transform(X_train, y_train)
X_test_selected = selector.transform(X_test)
all_names = X_train.columns
selected_mask = selector.get_support()
selected_names = all_names[selected_mask]
print('Selected names: ', selected_names)
model = LinearRegression()
model.fit(X_train_selected, y_train)
y_pred = model.predict(X_train_selected)
mae = mean_absolute_error(y_train, y_pred)
training.append(mae)
y_pred = model.predict(X_test_selected)
mae = mean_absolute_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
testing.append(mae)
print(f'Test MAE: ${mae:,.0f}')
print(f'Test R2: {r2} \n')
output :
หหหห
ks = range(1, len(X_train.columns)+1)
plt.plot(ks, training, label='Training Score', color='b')
plt.plot(ks, testing, label='Testing Score', color='g')
plt.ylabel("MAE ($)")
plt.xlabel("Number of Features")
plt.title('Validation Curve')
plt.legend()
plt.show()
output :
ํน์ฑ ๊ฐ์ k ๊ฐ์ด 5๊ฐ์์ 6๊ฐ๋ก ๋์ด๊ฐ ๋ ๊ทธ๋ํ ์์์ ๊ฐ์ฅ ํฌ๊ฒ MAE๊ฐ ๊ฐ์ํ๋ค.
๋ชจ๋ ํน์ฑ์ ์ฌ์ฉํ๋ฉด ๋น์ฐํ MAE ๊ฐ์ ์ต์๊ฐ ๋์ง๋ง ์ฐจ์์ด ๋๋ฌด ์ปค์ ธ ๋ชจ๋ธ์ ์ํฅ์ ๋ฏธ์น๋ค.
๋ฐ๋ผ์ k๊ฐ์ 6๊ฐ์ผ ๋, ๊ฐ์ฅ ํจ๊ณผ์ ์ด๋ผ๊ณ ๋ณผ ์ ์๋ค.
๐ก Ridge Regression
Ridge ํ๊ท๋ ๊ธฐ์กด์ ๋ค์คํ๊ท์ ์ ํ๋ จ ๋ฐ์ดํฐ์ ๋ ์ ํฉ๋๋๋ก ๋ง๋๋ ๊ฒ์ด๋ค.
Ridge ํ๊ท๋ชจ๋ธ์ ๋น์ฉํจ์์์ ๋ค์๊ณผ ๊ฐ๋ค.
n : ์ํ์, p : ํน์ฑ์, λ(๋๋ค) : ํ๋ ํ๋ผ๋ฏธํฐ, β : ํ๊ท๊ณ์
๋ฆฟ์ง ํ๊ท๋ชจ๋ธ์ ๋น์ฉํจ์๋ฅผ ๋ณด๋ฉด ๊ธฐ์กด ๋น์ฉํจ์์ธ SSE์ ํ๊ท๊ณ์์ ๊ณฑํฉ ํํธ๊ฐ ์ถ๊ฐ๋์๋ค.
ํ๊ท๊ณ์์ ๊ณฑํฉ์์ ๋๋ค๋ ํ๋ ํ๋ผ๋ฏธํฐ๋ก, ๋๋ค ๊ฐ์ด ์ปค์ง์๋ก ํ๊ท๊ณ์๋ค์ 0์ผ๋ก ์๋ ด์ํจ๋ค.
ํ๊ท๊ณ์๊ฐ์ 0์ผ๋ก ์๋ ด์ํด์ผ๋ก์จ ๋ ์ค์ํ ํน์ฑ์ ๊ฐฏ์๋ฅผ ์ค์ด๋ ํจ๊ณผ๋ฅผ ๋ธ๋ค. ์ฆ ๊ณผ์ ํฉ์ ์ค์ธ๋ค.
๋ฐ๋๋ก ๋๋ค๊ฐ 0์ ๊ฐ๊น์์ง๋ฉด ๋ฆฟ์ง ํ๊ท๋ ๋ค์คํ๊ท๋ชจ๋ธ ๋ฌธ์ ๊ฐ ๋๋ค.
Ridge ํ๊ท๋ ๊ณผ์ ํฉ์ ์ค์ด๊ธฐ ์ํด์ ์ฌ์ฉํ๋ค.
๊ณผ์ ํฉ์ ์ค์ด๋ ๊ฐ๋จํ ๋ฐฉ๋ฒ์ ๋ชจ๋ธ์ ๋ณต์ก๋๋ฅผ ์ค์ด๋ ๋ฐฉ๋ฒ์ด๋ค.
ํน์ฑ์ ๊ฐ์๋ฅผ ์ค์ด๊ฑฐ๋ ๋ชจ๋ธ์ ๋จ์ํ ๋ชจ์์ผ๋ก ์ ํฉ์ํค๋ ๊ฒ์ด๋ค.
Ridge ํ๊ท๋ ํธํฅ(Bias)์ ์กฐ๊ธ ๋ํ๊ณ , ๋ถ์ฐ(Variance)์ ์ค์ด๋ ๋ฐฉ์์ผ๋ก ์ ๊ทํ(Regularization)๋ฅผ ์ํํ๋ค.
์ฌ๊ธฐ์ ๋งํ๋ ์ ๊ทํ๋ ๋ชจ๋ธ์ ๋ณํํ์ฌ ๊ณผ์ ํฉ์ ์ํํด ์ผ๋ฐํ ์ฑ๋ฅ์ ๋์ฌ์ฃผ๊ธฐ ์ํ ๊ธฐ๋ฒ์ ๋งํ๋ค.
โจ๋ค์คํ๊ท๋ชจ๋ธ๊ณผ ๋ฆฟ์งํ๊ท๋ชจ๋ธ ๋น๊ต
OLS vs Ridge
OLS(Ordinary Least Squares)๋ ์ต์์์น๋ฒ์ผ๋ก,
์์ฐจ์ ๊ณฑํฉ(RSS: Residual Sum of Squares)์ ์ต์ํํ๋ ๊ฐ์ค์น ๋ฒกํฐ๋ฅผ ๊ตฌํ๋ ๋ฐฉ๋ฒ์ด๋ค.
Anscome's quartet ๋ฐ์ดํฐ ์ฌ์ฉ
import seaborn as sns
ans = sns.load_dataset('anscombe').query('dataset=="|||"')
ans.plot.scatter('x', 'y')
OLS
%matplotlib inline
ax = ans.plot.scatter('x', 'y')
# OLS
ols = LinearRegression()
ols.fit(ans[['x']], ans['y'])
# ํ๊ท๊ณ์์ ์ ํธ(intercept)์ ํ์ธํ๋ค
m = ols.coef_[0].round(2)
b = ols.intercept_.round(2)
title = f'Linear Regression \n y = {m}x + b'
# ํ๋ จ ๋ฐ์ดํฐ๋ก ์์ธก
ans['y_pred'] = ols.predict(ans[['x']])
ans.plot('x', 'y_pred', ax=ax, title=title)
output :
Ridge Regression
λ ๊ฐ์ ์ฆ๊ฐ์ํค๋ฉฐ ๊ทธ๋ํ๋ฅผ ํตํด ํ๊ท๊ณ์์ ๋ณํ๋ฅผ ํ์ธํ๋ค.
import matplotlib.pyplot as plt
from sklearn.linear_model import Ridge
def ridge_anscombe(alpha):
# alpha = lambda
ans = sns.load_dataset('anscombe').query('dataset=="|||"')
ax = ans.plot.scatter('x', 'y')
ridge = Ridge(alpha=alpha, normalize=True)
ridge.fit(ans[['x']], ans['y'])
# ํ๊ท๊ณ์์ ์ ํธ(intercept)
m = ridge.coef_[0].round(2)
b = ridge.intercept_.round(2)
title = f'Ridge Regression, alpha={alpha} \n y = {m}x + {b}'
# ํ๋ จ ๋ฐ์ดํฐ๋ก ์์ธก
ans['y_pred'] = ridge.predict(ans[['x']])
ans.plot('x', 'y_pred', ax=ax, title=title)
plt.show()
# ์ฌ๋ฌ alpha ๊ฐ์ผ๋ก ๊ทธ๋ํ๋ฅผ ๊ทธ๋ฆฐ๋ค
alphas = np.arange(0, 2, 0.4)
for alpha in alphas:
ridge_anscombe(alpha)
output :
๊ทธ๋ํ๋ฅผ ๋ณด๋ฉด, alpha = 0 ์ธ ๊ฒฝ์ฐ์๋ OLS์ ๊ฐ์ ๊ทธ๋ํ ํํ๋ฅผ ๋ณด์ด๋ฏ๋ก ๊ฐ์ ๋ชจ๋ธ์์ ํ์ธํ ์ ์๊ณ ,
alpha ๊ฐ์ด ์ปค์ง์๋ก ์ง์ ์ ๊ธฐ์ธ๊ธฐ๊ฐ 0์ ๊ฐ๊น์์ง๋ฉด์ ํ๊ท ๊ธฐ์ค๋ชจ๋ธ(baseline)๊ณผ ๋น์ทํด์ง๋ ๋ชจ์ต์ ๋ณผ ์ ์๋ค.
์ต์ ์ ํจ๋ํฐ ๊ฐ์ผ๋ก ์์ธก๋ Ridge ํ๊ท ์ง์ ์ ์ด์์น ์ํฅ์ ๋ ๋ฐ์ ์ ์๋ค.
์ต์ ํจ๋ํฐ ๊ฐ์ธ alpha ๊ฐ์ ํจ์จ์ ์ผ๋ก ๊ตฌํ๊ธฐ ์ํด์๋, ์ฌ๋ฌ ํจ๋ํฐ ๊ฐ์ ๊ฐ์ง๊ณ ๊ต์ฐจ๊ฒ์ฆ (cross-validation)์
์ฌ์ฉํ์ฌ ์ฐพ์๋๊ฐ์ผ ํ๋ค.
sklearn์ RidgeCV ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ฉด ๊ต์ฐจ๊ฒ์ฆ ์๊ณ ๋ฆฌ์ฆ์ ์์ฒด์ ์ผ๋ก ์งํํด ์ต์ ์ ํจ๋ํฐ ๊ฐ์ ์ฐพ๋๋ค.
โจ RidgeCV๋ฅผ ํตํ ์ต์ ํจ๋ํฐ ๊ฒ์ฆ
from sklearn.linear_model import RidgeCV
alphas = [0.01, 0.05, 0.1, 0.2, 1.0, 10.0, 100.0]
ridge = RidgeCV(alphas=alphas, normalize=True, cv=3)
ridge.fit(ans[['x']], ans['y'])
print("alpha: ", ridge.alpha_)
print("best score: ", ridge.best_score_)
output :
cf.
sklearn.linear_model.RidgeCV
: cv ํ๋ผ๋ฏธํฐ๋ฅผ ํตํด์ K-fold ๊ต์ฐจ๊ฒ์ฆ์ ์ง์ ํ ์ ์๋ค.
reference
https://modern-manual.tistory.com/21
Ridge regression(๋ฅํ ํ๊ท) ๊ฐ๋จํ ์ค๋ช ๊ณผ ์ฅ์
์ ํ ๋ชจ๋ธ(Linear model)์ ์์ธก๋ ฅ(accuracy) ํน์ ์ค๋ช ๋ ฅ(interpretability)์ ๋์ด๊ธฐ ์ํด ์ฌ๋ฌ ์ ๊ทํ(regularization) ๋ฐฉ๋ฒ๋ค์ ์ฌ์ฉํ๋ค. ๋ํ์ ์ธ shrinkage ๋ฐฉ๋ฒ์๋ ridge regression๊ณผ lasso๊ฐ ์์ผ๋ฉฐ..
modern-manual.tistory.com
https://velog.io/@dlskawns/Linear-Regression-Ridge-Regression-RidgeCV-%EC%A0%95%EB%A6%AC
Linear Regression - Ridge Regression, RidgeCV ์ ๋ฆฌ
์ค๋ ๋ฐฐ์ด Ridge Regression ๋ฐ ๋คํญํ๊ท์ ๋ํ ์ ๋ฆฌ๋ฅผ ํด๋ณธ๋ค.Rigdge ํ๊ท๋ ๊ธฐ์กด Linear Rigression์ ๊ณผ์ ํฉ์ ํด๊ฒฐํด์ฃผ๋ ๊ต์ฅํ ํ์ค์ ์ธ ์ ํํ๊ท๋ฐฉ๋ฒ์ด๋ค. ๋๋ฌด๋ ๋ง์ ํ์ต์ผ๋ก ์ธํด ๊ณผ์ ํฉ๋๋
velog.io
'Boot Camp > section2' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[AIB] Logistic Regression (0) | 2022.03.30 |
---|---|
[AIB] Bias, Variance, R-Square, Multiple Regression, Evaluation Metrics (0) | 2022.03.25 |
[AIB] OLS, MAE, RSS, Simple Regression (0) | 2022.01.07 |