Scaling
데이터 셋에 키와 몸무게 Feature가 있다고 가정해보자.
키와 몸무게의 평균적인 값들과 단위는 다르기에, 이를 정제 없이 훈련시킨다면 모델의 정확성이 떨어진다.
따라서 데이터 Feature 들의 크기 규모를 동일하게 하는 작업이 필요한데, 이를 Scaling 이라 한다.
- Tip💡
이 글에서는 iris 데이터를 이용하여 실습을 진행하고 있다. iris 데이터는 붗꽃 데이터로, 해당 데이터에는 꽃받침의 길이, 꽃받침의 너비, 꽃잎의 길이, 꽃잎의 너비와 꽃의 종류가 기술되어있다. 다운 받고 싶은 분이 계시다면 Kaggle 참조
Import data
pandas 라이브러리를 이용하여 csv 데이터를 불러오자.
import pandas as pd
df = pd.read_csv("iris.csv")
df.head()
Split data into train and test
X 데이터(features)와 y 데이터(target) 을 정의하고, 이를 train set과 test set으로 나눈다.
features와 target 을 정의하기에 앞서, "Species" 컬럼은 문자열 형태의 데이터를 가지고 있으므로 이를 정수 형태로 변환하여 준다. 변환을 위해 apply(), map() 등의 함수를 사용할 수도 있지만 간단하게 sklearn 라이브러리의 LabelEncoder() 함수를 통해 변환해보자.
from sklearn.preprocessing import LabelEncoder
encoder = LabelEncoder()
encoder.fit(df["Species"])
df["Species"] = encoder.transform(df["Species"])
df["Species"].unique()
output:
array([0, 1, 2])
변환 결과, 'Iris-setosa', 'Iris-versicolor', 'Iris-virginica' 값 중 하나를 가지고 있던 "Species" 컬럼은 0, 1, 2 의 값으로 변경되었다. X(features)와 y(target)를 초기화 하면, 4개의 속성 값을 가지는 X와 1개의 target 값을 가지는 y 데이터가 구성된다.
X = df.iloc[:, 1:5].values
y = df["Species"].values
print(X.shape)
print(y.shape)
output:
(150, 4)
(150,)
sklearn의 tran_test_split() 함수를 이용하여 X 데이터를 X_train과 X_test로, y 데이터를 y_train과 y_test로 나누어준다. test_size = 0.2 로 train 데이터는 전체의 80%, test 데이터는 전체의 20%가 되도록 한다.
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = \
train_test_split(X, y, test_size=0.2, shuffle=True, stratify=y)
print(X_train.shape)
print(y_train.shape)
print(X_test.shape)
print(y_test.shape)
output:
(120, 4)
(120,)
(30, 4)
(30,)
MinMax Scaling
vinilla python과 MinMaxScaler를 이용하여 MinMax Scaling을 수행해보자.
- vinilla python
MinMax Scaling이란 벡터의 최솟값을 0, 벡터의 최댓값을 1로 scaling 하는 것을 의미한다. 따라서 minmax scaling 후 벡터 내의 모든 값은 [0, 1] 사이에 분포하게 된다. 이를 계산하는 방법은 다음과 같다.
$$ (v[i] - min) / (max - min)$$
각 Feature 별로 최솟값과 최댓값을 구해놓은 후, Feature 별 scaling을 진행한다.
minv = X_train.min(axis = 0)
maxv = X_train.max(axis = 0)
print(minv) # 각 Feature 별 최솟값
print(maxv) # 각 Feature 별 최댓값
output:
[4.3 2. 1. 0.1]
[7.9 4.4 6.9 2.5]
x_train의 scaling 결과, 모든 값이 0과 1 사이에 분포하는 것을 확인할 수 있다.
X_train_minmaxscaled = (X_train - minv) / (maxv - minv)
X_train_minmaxscaled[:5, ]
output:
array([[0.22222222, 0.625 , 0.06779661, 0.04166667],
[0.19444444, 0.58333333, 0.10169492, 0.125 ],
[0.55555556, 0.33333333, 0.69491525, 0.58333333],
[0.47222222, 0.29166667, 0.69491525, 0.625 ],
[0.33333333, 0.125 , 0.50847458, 0.5 ]])
X_test도 X_train과 동일하게 scaling을 진행한다. 이 때 주의해야 할 점은, X_train 데이터에서 구한 minv와 maxv를 사용하여 X_test를 스케일링 해야 한다는 것이다. X_test의 feature 별 최솟값과 최댓값을 구해 별도로 scaling을 하는 실수를 하지말자.
X_test_minmaxscaled = (X_test - minv) / (maxv-minv)
X_test_minmaxscaled[:5, ]
output:
array([[0.11111111, 0.5 , 0.05084746, 0.04166667],
[0.38888889, 0.41666667, 0.54237288, 0.45833333],
[0.38888889, 0.33333333, 0.52542373, 0.5 ],
[0.5 , 0.41666667, 0.66101695, 0.70833333],
[0.44444444, 0.5 , 0.6440678 , 0.70833333]])
- sklearn.preprocessing.MinMaxScaler
sklearn 라이브러리의 MinMaxScaler를 이용하면 조금 더 편하게 scaling을 진행할 수 있다.
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
X_train_minmaxscaled = scaler.fit_transform(X_train)
X_test_minmaxscaled = scaler.transform(X_test)
X_train_minmaxscaled[:5, ]
output:
array([[0.22222222, 0.625 , 0.06779661, 0.04166667],
[0.19444444, 0.58333333, 0.10169492, 0.125 ],
[0.55555556, 0.33333333, 0.69491525, 0.58333333],
[0.47222222, 0.29166667, 0.69491525, 0.625 ],
[0.33333333, 0.125 , 0.50847458, 0.5 ]])
fit_transform() 함수를 통해 X_train의 속성을 학습 및 변형한다. 이 때, 학습한 X_train의 속성이 모델에 저장되어있으므로, transform() 함수를 통해 X_test를 변형한다.
Standard(Z-score) Scaling
vinilla python과 SandardScaler를 이용하여 Standard Scaling을 수행해보자.
Standard scaling 이란, 벡터의 평균이 0, 표준편차가 1이 되도록 scaling 하는 것을 의미한다. 이를 계산하는 수식은 다음과 같다.
$$ (v[i] - Mu) / std$$
각 Feature 별 평균과 표준편차를 구해놓은 후, Feature 별 scaling을 진행한다.
Mu = X_train.mean(axis = 0)
std = X_train.std(axis = 0)
print(Mu)
print(std)
output:
[5.85583333 3.04916667 3.765 1.2025 ]
[0.84397826 0.43817725 1.77949665 0.77593626]
X_train_standardScaled = (X_train - Mu) / std
X_train_standardScaled[:5, ]
output:
array([[-0.89556019, 1.02888347, -1.32902751, -1.29198756],
[-1.01404666, 0.80066533, -1.21663618, -1.03423443],
[ 0.52627738, -0.56864354, 0.75021214, 0.38340778],
[ 0.17081799, -0.79686169, 0.75021214, 0.51228435],
[-0.42161433, -1.70973427, 0.13205982, 0.12565465]])
X_train의 Mu 벡터와 std 벡터를 이용하여 X_test의 scaling을 진행한다. X_train과 동일한 평균값과 표준편차를 이용하여 X_test를 스케일링 해야 한다는 사실을 잊지 말자.
X_test_standardScaled = (X_test - Mu) / std
X_test_standardScaled[:5, ]
output:
array([[-1.36950605, 0.34422904, -1.38522317, -1.29198756],
[-0.18464141, -0.11220725, 0.24445115, -0.00322191],
[-0.18464141, -0.56864354, 0.18825548, 0.12565465],
[ 0.28930445, -0.11220725, 0.63782081, 0.77003747],
[ 0.05233152, 0.34422904, 0.58162515, 0.77003747]])
sklearn 라이브러리의 StandardScaler를 사용하면 비교적 쉽게 scaling을 수행할 수 있다.
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_train_standardscaled = scaler.fit_transform(X_train)
X_test_standardscaled = scaler.transform(X_test)
X_train_standardscaled[:5, :]
output:
array([[-0.89556019, 1.02888347, -1.32902751, -1.29198756],
[-1.01404666, 0.80066533, -1.21663618, -1.03423443],
[ 0.52627738, -0.56864354, 0.75021214, 0.38340778],
[ 0.17081799, -0.79686169, 0.75021214, 0.51228435],
[-0.42161433, -1.70973427, 0.13205982, 0.12565465]])
fit_transform() 함수를 통해 X_train의 속성을 학습 및 변형한다. 이 때, 학습한 X_train의 속성이 모델에 저장되어있으므로, transform() 함수를 통해 X_test를 변형한다.
관련 링크
sklearn 라이브러리의 더 많은 scaler를 참고하고 싶다면, 링크 참조
'ㄴ DS' 카테고리의 다른 글
Numpy Indexing, Boolean Indexing, Fancy Indexing (0) | 2021.10.31 |
---|---|
Numpy 배열 생성하기와 형태 변형하기 (0) | 2021.10.30 |
[Matplotlb:3.4.3] Matplotlib와 Python으로 시각화 하는법 (0) | 2021.10.30 |
댓글