(데이콘 커뮤니티에서 참고함 https://dacon.io/codeshare/4526)
데이터 스케일링 Data Scaling
- 피처들마다 데이터값 범위가 제각각이기 때문에 범위 차이가 클 경우, 모델링에 방해가 됨
- 스케일링을 통해 모든 피처들의 데이터 분포나 범위를 동일하게 조정해줄 수 있음
- 훈련용 데이터셋은 fit 메서드를 적용시킨 후 transform, 테스트용 데이터셋에는 transform만 적용
In [45]:
#라이브러리 정의
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
In [46]:
#데이터 df형태로 불러오기
cancer = load_breast_cancer()
cancer_df = pd.DataFrame(cancer.data, columns=cancer.feature_names)
In [47]:
#target 확인하기, 0과 1밖에 없는 것으로 보아 분류 알고리즘 사용해야 함
print(cancer.target)
cancer_df['target'] = cancer.target
cancer_df.head()
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 1 0 1 1 1 1 1 0 0 1 0 0 1 1 1 1 0 1 0 0 1 1 1 1 0 1 0 0
1 0 1 0 0 1 1 1 0 0 1 0 0 0 1 1 1 0 1 1 0 0 1 1 1 0 0 1 1 1 1 0 1 1 0 1 1
1 1 1 1 1 1 0 0 0 1 0 0 1 1 1 0 0 1 0 1 0 0 1 0 0 1 1 0 1 1 0 1 1 1 1 0 1
1 1 1 1 1 1 1 1 0 1 1 1 1 0 0 1 0 1 1 0 0 1 1 0 0 1 1 1 1 0 1 1 0 0 0 1 0
1 0 1 1 1 0 1 1 0 0 1 0 0 0 0 1 0 0 0 1 0 1 0 1 1 0 1 0 0 0 0 1 1 0 0 1 1
1 0 1 1 1 1 1 0 0 1 1 0 1 1 0 0 1 0 1 1 1 1 0 1 1 1 1 1 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 1 1 1 1 1 0 1 0 1 1 0 1 1 0 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1
1 0 1 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 0 1 1 1 1 0 0 0 1 1
1 1 0 1 0 1 0 1 1 1 0 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1 0 0
0 1 0 0 1 1 1 1 1 0 1 1 1 1 1 0 1 1 1 0 1 1 0 0 1 1 1 1 1 1 0 1 1 1 1 1 1
1 0 1 1 1 1 1 0 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 0 1 0 1 1 1 1 1 0 1 1
0 1 0 1 1 0 1 0 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 0 1
1 1 1 1 1 1 0 1 0 1 1 0 1 1 1 1 1 0 0 1 0 1 0 1 1 1 1 1 0 1 1 0 1 0 1 0 0
1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 0 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 0 0 0 0 0 0 1]
Out[47]:
mean radius | mean texture | mean perimeter | mean area | mean smoothness | mean compactness | mean concavity | mean concave points | mean symmetry | mean fractal dimension | ... | worst texture | worst perimeter | worst area | worst smoothness | worst compactness | worst concavity | worst concave points | worst symmetry | worst fractal dimension | target | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 17.99 | 10.38 | 122.80 | 1001.0 | 0.11840 | 0.27760 | 0.3001 | 0.14710 | 0.2419 | 0.07871 | ... | 17.33 | 184.60 | 2019.0 | 0.1622 | 0.6656 | 0.7119 | 0.2654 | 0.4601 | 0.11890 | 0 |
1 | 20.57 | 17.77 | 132.90 | 1326.0 | 0.08474 | 0.07864 | 0.0869 | 0.07017 | 0.1812 | 0.05667 | ... | 23.41 | 158.80 | 1956.0 | 0.1238 | 0.1866 | 0.2416 | 0.1860 | 0.2750 | 0.08902 | 0 |
2 | 19.69 | 21.25 | 130.00 | 1203.0 | 0.10960 | 0.15990 | 0.1974 | 0.12790 | 0.2069 | 0.05999 | ... | 25.53 | 152.50 | 1709.0 | 0.1444 | 0.4245 | 0.4504 | 0.2430 | 0.3613 | 0.08758 | 0 |
3 | 11.42 | 20.38 | 77.58 | 386.1 | 0.14250 | 0.28390 | 0.2414 | 0.10520 | 0.2597 | 0.09744 | ... | 26.50 | 98.87 | 567.7 | 0.2098 | 0.8663 | 0.6869 | 0.2575 | 0.6638 | 0.17300 | 0 |
4 | 20.29 | 14.34 | 135.10 | 1297.0 | 0.10030 | 0.13280 | 0.1980 | 0.10430 | 0.1809 | 0.05883 | ... | 16.67 | 152.20 | 1575.0 | 0.1374 | 0.2050 | 0.4000 | 0.1625 | 0.2364 | 0.07678 | 0 |
5 rows × 31 columns
In [72]:
X_train, X_test, y_train, y_test = train_test_split(cancer.data, cancer.target, test_size=0.2, random_state=3)
dtc = DecisionTreeClassifier()
dtc.fit(X_train, y_train)
print('모델의 정확도 :', round(dtc.score(X_test, y_test), 4))
모델의 정확도 : 0.8947
(1) StandardScaler
- 모든 피처들이 평균 0, 분산 1인 정규분포 갖게 해줌(표준화)
- 이 방법은 데이터 내에 이상치가 있다면 데이터의 평균, 분산에 큰 영향 주므로 적절하지 않음
In [117]:
from sklearn.preprocessing import StandardScaler
std = StandardScaler()
std.fit(X_train)
X_train_scaled = std.transform(X_train)
X_test_scaled = std.transform(X_test)
dtc.fit(X_train_scaled, y_train)
print('모델의 정확도 :', round(dtc.score(X_test_scaled, y_test), 4))
모델의 정확도 : 0.9035
- 정확도가 올라감
In [51]:
X_train
Out[51]:
array([[1.916e+01, 2.660e+01, 1.262e+02, ..., 1.872e-01, 3.258e-01,
9.720e-02],
[1.831e+01, 1.858e+01, 1.186e+02, ..., 1.571e-01, 3.206e-01,
6.938e-02],
[1.404e+01, 1.598e+01, 8.978e+01, ..., 7.453e-02, 2.725e-01,
7.234e-02],
...,
[1.795e+01, 2.001e+01, 1.142e+02, ..., 1.185e-01, 4.882e-01,
6.111e-02],
[1.955e+01, 2.877e+01, 1.336e+02, ..., 1.941e-01, 2.818e-01,
1.005e-01],
[1.152e+01, 1.493e+01, 7.387e+01, ..., 9.608e-02, 2.664e-01,
7.809e-02]])
In [29]:
X_train_scaled
# 데이터값의 범위가 변화함
Out[29]:
array([[ 1.40381088, 1.79283426, 1.37960065, ..., 1.044121 ,
0.52295995, 0.64990763],
[ 1.16565505, -0.14461158, 1.07121375, ..., 0.5940779 ,
0.44153782, -0.85281516],
[-0.0307278 , -0.77271123, -0.09822185, ..., -0.64047556,
-0.31161687, -0.69292805],
...,
[ 1.06478904, 0.20084323, 0.89267396, ..., 0.01694621,
3.06583565, -1.29952679],
[ 1.51308238, 2.3170559 , 1.67987211, ..., 1.14728703,
-0.16599653, 0.82816016],
[-0.73678981, -1.02636686, -0.74380549, ..., -0.31826862,
-0.40713129, -0.38233653]])
In [30]:
X_train_scaled.shape
Out[30]:
(455, 30)
In [31]:
455*30
Out[31]:
13650
In [97]:
# 데이터 타입이 array이기 때문에 열을 1개로 바꿔주기
X_train_scaled_ss = X_train_scaled.reshape(13650, 1)
X_train_data = X_train.reshape(13650, 1)
스케일링 전의 훈련용 데이터셋 분포
In [98]:
plt.hist(X_train_data, bins=30, color='red', alpha=0.7)
plt.title('Before Data Scaling')
plt.show()
스케일링 후 훈련용 데이터셋 분포
In [99]:
plt.hist(X_train_scaled_ss, bins=30, alpha=0.7, density=True)
plt.title('After Data Scaling')
plt.show()
- 그래프가 0을 중심으로 정규 분포 모양을 가짐
(2) MInMaxScaler
- 모든 피처들이 0과 1사이의 데이터값을 갖도록 함(피처별로 최솟값 0 ~ 최댓값 1이 됨)
- 데이터가 2차원인 경우, 모든 데이터는 x, y축의 0과 1사이에 존재
- 이 방법도 이상치 존재할 경우, 이상치가 극값이 되어 데이터가 아주 좁은 범위에 분포하게돼서 적절한 스케일링이 아님
In [118]:
from sklearn.preprocessing import MinMaxScaler
mms = MinMaxScaler()
mms.fit(X_train)
X_train_scaled = mms.transform(X_train)
X_test_scaled = mms.transform(X_test)
dtc.fit(X_train_scaled, y_train)
print('모델의 정확도 :', round(dtc.score(X_test_scaled, y_test), 4))
모델의 정확도 : 0.9035
- 정확도가 올라감
In [84]:
X_train_scaled
# 데이터값이 0과 1사이에 있음을 확인할 수 있음
Out[84]:
array([[0.56168275, 0.7081761 , 0.55664674, ..., 0.64329897, 0.33372758,
0.27653155],
[0.52005485, 0.37190776, 0.50256191, ..., 0.53986254, 0.32347723,
0.09405746],
[0.31093589, 0.26289308, 0.29746655, ..., 0.25611684, 0.22866154,
0.11347239],
...,
[0.50242421, 0.43186583, 0.47124964, ..., 0.40721649, 0.65385374,
0.03981372],
[0.5807826 , 0.79916143, 0.60930828, ..., 0.66701031, 0.24699389,
0.29817657],
[0.18752143, 0.21886792, 0.18424424, ..., 0.33017182, 0.2166371 ,
0.1511872 ]])
In [85]:
X_train_scaled_mms = X_train_scaled.reshape(13650, 1)
In [86]:
plt.hist(X_train_scaled_mms, bins=30, color='green', alpha=0.7)
plt.title('MinMaxScaler')
plt.show()
(3) MaxAbsScaler
- MinMaxScaler와 비슷, 모든 피처들의 절댓값이 0과 1사이에 놓이도록 함(0을 기준으로 절댓값이 가장 큰 수가 1 또는 -1)
- 이상치의 영향을 크게 받음
In [91]:
from sklearn.preprocessing import MaxAbsScaler
mas = MaxAbsScaler()
mas.fit(X_train)
X_train_scaled = mas.transform(X_train)
X_test_scaled = mas.transform(X_test)
dtc.fit(X_train_scaled, y_train)
print('모델의 정확도 :', round(dtc.score(X_test_scaled, y_test), 4))
모델의 정확도 : 0.9123
- 마찬가지로 정확도 올라감
In [92]:
X_train_scaled
Out[92]:
array([[0.68160797, 0.79261025, 0.66949602, ..., 0.64329897, 0.49081049,
0.46843373],
[0.65136962, 0.55363528, 0.62917772, ..., 0.53986254, 0.4829768 ,
0.33436145],
[0.49946638, 0.4761621 , 0.47628647, ..., 0.25611684, 0.41051522,
0.34862651],
...,
[0.63856279, 0.59624553, 0.60583554, ..., 0.40721649, 0.73546249,
0.29450602],
[0.69548203, 0.85727056, 0.70875332, ..., 0.66701031, 0.42452546,
0.48433735],
[0.40981857, 0.44487485, 0.39188329, ..., 0.33017182, 0.4013257 ,
0.37633735]])
In [93]:
X_train_scaled_mas = X_train_scaled.reshape(13650, 1)
In [94]:
plt.hist(X_train_scaled_mas, bins=30, color='yellow', alpha=0.7)
plt.title('MaxAbsScaler')
plt.show()
- MinMaxScaler 그래프보다 퍼져있음을 알 수 있음, 데이터가 모두 양수라 0과 1사이에만 존재함
(4) RobustScaler
- StandardScaler와 비슷, 대신 얘는 중간값(median)과 사분위값(quartile)을 사용
- 이상치의 영향 최소화할 수 있음
- StandardScaler와 비교했을 때, RobustScaler는 표준화 후 데이터가 더 넓게 분포해있음
In [95]:
from sklearn.preprocessing import RobustScaler
rbs = RobustScaler()
rbs.fit(X_train)
X_train_scaled = rbs.transform(X_train)
X_test_scaled = rbs.transform(X_test)
dtc.fit(X_train_scaled, y_train)
print('모델의 정확도 :', round(dtc.score(X_test_scaled, y_test), 4))
모델의 정확도 : 0.9123
- 마찬가지로 정확도 올라감
In [96]:
X_train_scaled
Out[96]:
array([[ 1.36170213, 1.42597639, 1.34367099, ..., 0.83828187,
0.63836018, 0.78497281],
[ 1.1607565 , -0.03088102, 1.08747682, ..., 0.54038005,
0.56222548, -0.59021256],
[ 0.15130024, -0.50317893, 0.11596157, ..., -0.27682106,
-0.1420205 , -0.44389521],
...,
[ 1.07565012, 0.22888283, 0.93915389, ..., 0.15835313,
3.01610542, -0.99901137],
[ 1.45390071, 1.82016349, 1.59312321, ..., 0.90657165,
-0.00585652, 0.94809689],
[-0.44444444, -0.69391462, -0.42036069, ..., -0.06353919,
-0.23133236, -0.15966387]])
In [100]:
X_train_scaled_rbs = X_train_scaled.reshape(13650, 1)
In [102]:
plt.hist(X_train_scaled_rbs, bins=30, color='pink', alpha=0.7)
plt.title('RobustScaler')
plt.show()
- 표준화되었기 때문에 StandardScaler와 모양이 비슷
(5) Normalizer
- 앞의 4가지 방법은 각 피처의 통계치를 이용함. 즉, 칼럼을 대상으로 함
- Normalizer는 '행'마다 정규화가 진행, 한 행의 모든 피처들 사이의 유클리드 거리가 1이 되도록 만들어줌
- 유클리드 거리(L2 Distance): 모든 차원에서 두 점 사이의 최단 거리
- 좀 더 빠르게 학습할 수 있고 과대적합 확률을 낮출 수 있음
In [123]:
from sklearn.preprocessing import Normalizer
norm = Normalizer()
X_train_scaled = norm.fit_transform(X_train)
X_test_scaled = norm.fit_transform(X_test)
dtc.fit(X_train_scaled, y_train)
print('모델의 정확도 :', round(dtc.score(X_test_scaled, y_test), 4))
모델의 정확도 : 0.9211
- 모델 정확도가 가장 올라감
In [124]:
X_train_scaled
Out[124]:
array([[9.22211661e-03, 1.28031473e-02, 6.07427514e-02, ...,
9.01033522e-05, 1.56814488e-04, 4.67844329e-05],
[1.03861667e-02, 1.05393215e-02, 6.72746788e-02, ...,
8.91134236e-05, 1.81857184e-04, 3.93551199e-05],
[1.43548748e-02, 1.63383831e-02, 9.17934942e-02, ...,
7.62014828e-05, 2.78611352e-04, 7.39623677e-05],
...,
[1.11556685e-02, 1.24359291e-02, 7.09736683e-02, ...,
7.36460568e-05, 3.03409324e-04, 3.79789918e-05],
[8.54812786e-03, 1.25795211e-02, 5.84158507e-02, ...,
8.48691364e-05, 1.23215470e-04, 4.39430614e-05],
[1.77702285e-02, 2.30303396e-02, 1.13948505e-01, ...,
1.48208642e-04, 4.10936535e-04, 1.20458086e-04]])
In [125]:
X_train_scaled_norm = X_train_scaled.reshape(13650, 1)
In [126]:
plt.hist(X_train_scaled_norm, bins=30, color='orange', alpha=0.7)
plt.title('Normalizer')
plt.show()
- 0 근처에서 데이터값이 다 모여있음, x축의 범위도 가장 작음
'Data Science > 파이썬 머신러닝 완벽 가이드' 카테고리의 다른 글
[sklearn] (11) - 오차 행렬 confusion_matrix() (0) | 2023.05.09 |
---|---|
[sklearn] (10) - 정확도 accuracy_score (0) | 2023.05.09 |
[kaggle] 타이타닉 생존률 예측하기 (2) - 모델링 (0) | 2023.05.04 |
[sklearn] (8) - 데이터 전처리(LabelEncoder, OneHotEncoder, get_dummies, StandardScaler, MinMaxScaler) (0) | 2023.05.02 |
[sklearn] (7) - GridSearchCV (0) | 2023.05.02 |