์๋ฅผ ๋ค์ด, 'ํค(170cm)'์ '๋ชธ๋ฌด๊ฒ(65kg)'๋ฅผ ๊ฐ์ง๊ณ ํน์ฑ์ ๋ถ์ํ๋ค๊ณ ํ์.
- ํค: 150 ~ 190 (๋ฒ์๊ฐ ํผ)
- ๋ชธ๋ฌด๊ฒ: 40 ~ 100 (์๋์ ์ผ๋ก ๋ฒ์๊ฐ ์์)
๋ฐ์ดํฐ์ ๋จ์(Scale) ์ฐจ์ด๊ฐ ํฌ๋ฉด, ์ซ์๊ฐ ํฐ ํน์ฑ(ํค)์ด ๊ฒฐ๊ณผ์ ๊ณผ๋ํ ์ํฅ์ ๋ฏธ์น๊ฒ ๋๋ค.
preprocessing ๋ชจ๋์์ ์ ๊ณต| ์ข ๋ฅ | ์ค๋ช | ์์ | ํน์ง |
|---|---|---|---|
| Min-Max Scaling | ๊ฐ์ 0 ~ 1 ์ฌ์ด๋ก ๋ณํ | x' = (x - min) / (max - min) | ๋ฐ์ดํฐ ๋ถํฌ๋ ์ ์ง๋๋ ์ด์์น์ ๋งค์ฐ ๋ฏผ๊ฐํจ |
| Standard Scaling | ํ๊ท 0, ํ์คํธ์ฐจ 1๋ก ๋ณํ | x' = (x - ฮผ) / ฯ | ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉ๋๋ ํ์คํ, ์ ๊ท๋ถํฌ ๊ฐ์ ๋ชจ๋ธ์ ์ ๋ฆฌ |
| Robust Scaling | ์ค์๊ฐ(Median)๊ณผ IQR ์ฌ์ฉ | x' = (x - Q2) / (Q3 - Q1) | ์ด์์น ์ํฅ ์ต์ํ, ๋ถํฌ๊ฐ ๋น๋์นญ์ผ ๋ ์ ๋ฆฌ |
์ ํ ํ๊ท ์ค ๊ฒฝ์ฌํ๊ฐ๋ฒ์ ์ฐ๋ SGDRegressor๋ ๋ฐ์ดํฐ ์ค์ผ์ผ์ ๋งค์ฐ ๋ฏผ๊ฐํ๋ฏ๋ก ์ ๊ทํ๊ฐ ํ์์ด๋ค
import pandas as pd
import numpy as np
from sklearn.preprocessing import MinMaxScaler, StandardScaler
from sklearn.linear_model import SGDRegressor
# ๋ฐ์ดํฐ ์์ฑ (3๋ฒ์งธ ์ปฌ๋ผ์ ๋จ์๊ฐ ๋งค์ฐ ํผ)
data = [[828, 920, 1234567, 1020, 1111],
[824, 910, 2345612, 1090, 1234],
[880, 900, 3456123, 1010, 1000],
[870, 990, 2312123, 1001, 1122],
[860, 980, 3223123, 1008, 1133],
[850, 970, 2432123, 1100, 1221]]
# ์ฐ์ฐ์ ์ํด float32๋ก ๋ณํ
df = pd.DataFrame(np.float32(data))
x_data = df.iloc[:, :-1].values # ํน์ฑ (๋
๋ฆฝ๋ณ์)
y_data = df.iloc[:, [-1]].values # ๋ผ๋ฒจ (์ข
์๋ณ์)
fit(๊ธฐ์ค ์ฐพ๊ธฐ)๊ณผ transform(๋ณํํ๊ธฐ)์ ๋์์ ์ํํ๋ค.# 1. ํน์ฑ ๋ฐ์ดํฐ(X) ์ ๊ทํ
scaleF = MinMaxScaler()
x_dataN = scaleF.fit_transform(x_data)
print(x_dataN[:2])
# 0๊ณผ 1 ์ฌ์ด์ ๊ฐ์ผ๋ก ์์๊ฒ ๋ณํ๋จ
# 2. ๋ผ๋ฒจ ๋ฐ์ดํฐ(Y) ์ ๊ทํ (ํ๊ท ๋ฌธ์ ์์ SGD ์ฌ์ฉ ์ ๊ถ์ฅ)
# ๋ณดํต ๋ถ๋ฅ๋ฌธ์ ์์๋ Y๋ฅผ ์ค์ผ์ผ๋ง ํ์ง ์์ง๋ง,
# ๊ฐ์ ๋ฒ์๊ฐ ํฐ ํ๊ท ๋ฌธ์ ์์๋ ์๋ ด์ ๋๊ธฐ ์ํด Y๋ ์ค์ผ์ผ๋ง ํ๊ธฐ๋ ํ๋ค.
scaleL = MinMaxScaler()
y_dataN = scaleL.fit_transform(y_data)
# ํ์ต
model = SGDRegressor(verbose=True, max_iter=200)
model.fit(x_dataN, y_dataN.ravel()) # .ravel()๋ก 1์ฐจ์ ๋ณํ ๊ถ์ฅ
# ์์ธก ์๋๋ฆฌ์ค:
# [828, 920, 1234567, 1020] ๋ฐ์ดํฐ๋ฅผ ์์ธกํ๊ณ ์ถ๋ค๋ฉด?
# 1. ์
๋ ฅ ๋ฐ์ดํฐ ์ ๊ทํ (transform๋ง ์ฌ์ฉ!)
# ์ด๋ฏธ fit์ผ๋ก ๊ธฐ์ค(min, max)์ ์ก์์ผ๋ฏ๋ก transform๋ง ํฉ๋๋ค.
new_data = [[828.0, 920.0, 1234567.0, 1020.0]]
xN = scaleF.transform(new_data)
# 2. ๋ชจ๋ธ ์์ธก
pred = model.predict(xN)
print(f"์์ธก๋ ์ค์ผ์ผ ๊ฐ: {pred}")
# array([0.30035559]) -> 0~1 ์ฌ์ด์ ๊ฐ์ด๋ผ ์ฐ๋ฆฌ๊ฐ ์์๋ณผ ์ ์์
# 3. ์ญ์ ๊ทํ (์๋ ๋จ์๋ก ๋ณต์)
# ์์ธก๊ฐ์ 1์ฐจ์์ด๋ฏ๋ก 2์ฐจ์ ํํ๋ก ๋ฃ์ด์ค์ผ ํจ [pred]
original_val = scaleL.inverse_transform([pred])
print(f"์ค์ ์์ธก๊ฐ: {original_val}")
# array([[1070.28315213]]) -> ์ด์ ์ผ ์ค์ ๊ฐ๊ฒฉ/์์น๋ก ๋ณด์!
๐ก Pipeline (ํ์ดํ๋ผ์ธ)
์์ฒ๋ผ scale -> fit -> predict -> inverse ๊ณผ์ ์ด ๋ฒ๊ฑฐ๋กญ๋ค๋ฉด, Scikit-learn์ Pipeline์ ์ฌ์ฉํ์ฌ ์ด ๊ณผ์ ์ ํ๋๋ก ๋ฌถ์ด ์๋ํํ ์ ์๋ค.
Pima Indians Diabetes ๋ฐ์ดํฐ์ ์ ํ์ฉํ ๋ถ๋ฅ ๋ฌธ์ ์ค์ต
๋ถ๋ฅ ๋ฌธ์ ์์๋ ๋ผ๋ฒจ()์ 0, 1์ด๋ฏ๋ก ์ค์ผ์ผ๋งํ์ง ์๋๋ค.
df = pd.read_csv('data/pima-indians-diabetes.data.csv')
x_data = df.iloc[:, :-1].values
y_data = df.iloc[:, -1].values
# ์ค์ผ์ผ๋ฌ ์์ฑ
scaler = MinMaxScaler()
# ์ ์ฒด ๋ฐ์ดํฐ๋ฅผ ์ค์ผ์ผ๋ง
x_dataN = scaler.fit_transform(x_data)
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
# ์ ๊ทํ๋ ๋ฐ์ดํฐ(x_dataN)๋ฅผ ๋๋๋๋ค.
x_train, x_test, y_train, y_test = train_test_split(
x_dataN, y_data,
test_size=0.3,
stratify=y_data
)
# ํ์ต
model = LogisticRegression(max_iter=500, verbose=True)
model.fit(x_train, y_train)
# ์์ธกํ ์ค์ ๋ฐ์ดํฐ
new_sample = [[6, 148, 72, 35, 0, 33.6, 0.627, 50]]
# ๋ฐ๋์ ํ์ต ๋ ์ฌ์ฉํ ์ค์ผ์ผ๋ฌ๋ก ๋ณํ(transform) ํ ์
๋ ฅ!
xN = scaler.transform(new_sample)
result = model.predict(xN)
print(f"๋น๋จ ์ฌ๋ถ ์์ธก: {result}") # array([1]) -> ๋น๋จ(1)๋ก ์์ธก
Data Leakage (์ ๋ณด ๋์)
Note: ์ ์์ ์์๋ ํธ์์ ์ ์ฒด ๋ฐ์ดํฐ๋ฅผ fit_transform ํ ํ split ํ๋ค. ํ์ง๋ง ์ค๋ฌด์์ ๊ถ์ฅํ๋ ๋ฐฉ๋ฒ X
1. train_test_split์ ๋จผ์ ํ๋ค.
2. x_train ๋ฐ์ดํฐ๋ก๋ง scaler๋ฅผ fit ํ๋ค. (scaler.fit(x_train))
3. ๊ทธ ๊ธฐ์ค์ผ๋ก x_train๊ณผ x_test๋ฅผ ๊ฐ๊ฐ transform ํ๋ค.
- ์ด์ : ํ ์คํธ ๋ฐ์ดํฐ(๋ฏธ๋ ๋ฐ์ดํฐ)์ ์ ๋ณด(min, max, mean ๋ฑ)๊ฐ ํ์ต ๊ณผ์ ์ ๋ฏธ๋ฆฌ ๋ฐ์๋๋ ๊ฒ์ ๋ง๊ธฐ ์ํจ.
transform)