스케일링¶
- 수치형 데이터들의 값의 범위가 클 경우 사용한다.(연산 속도 증가)
- 예를 들어 주식의 가격을 생각했을 경우 100원의 1%와 100000원의 1%를 계산하고자 한다면 같은 1%연산이지만 숫자가 클 경우 연산속도에 영향을 미치게 된다.
- 서로 다른 변수의 값 범위를 일정한 수준으로 맞추고자 하는 경우
- 대표적 스케일링 클래스는 StandardScaler, MinMaxScaler이 있다
- 사용 이유
- 연산속도를 올릴 수 있다
- 확률을 높일 수 있다
- 과대, 과소적합을 조금은 해결할 수 있다
- 참고
- 이상치가 있을 경우 범위의 차이가 커지게 되므로 이상치는 제거해야 한다
- RandomForest는 따로 스케일링 할 필요가 없다.(tree계열은 따로 스케일 할 필요가 없다)
In [3]:
import pandas as pd
from sklearn.preprocessing import StandardScaler
# 가상의 영화 평점 데이터
movie = {'daum':[2,4,6,8,10], 'naver':[1,2,3,4,5]}
mv = pd.DataFrame(movie)
mv
Out[3]:
daum | naver | |
---|---|---|
0 | 2 | 1 |
1 | 4 | 2 |
2 | 6 | 3 |
3 | 8 | 4 |
4 | 10 | 5 |
In [13]:
# standardscaler 를 사용해서
# 두 데이터 간의 범위를 줄인다
st = StandardScaler()
scaled = st.fit_transform(mv)
mv = pd.DataFrame(data = scaled, columns=['daum', 'naver'])
mv
Out[13]:
daum | naver | |
---|---|---|
0 | -1.414214e+00 | -1.414214e+00 |
1 | -7.071068e-01 | -7.071068e-01 |
2 | 4.440892e-17 | 4.440892e-17 |
3 | 7.071068e-01 | 7.071068e-01 |
4 | 1.414214e+00 | 1.414214e+00 |
In [12]:
# round() : 소숫점 범위를 잘라준다
round(scaled.std(), 2)
Out[12]:
1.0
In [ ]:
In [ ]:
In [16]:
from sklearn.preprocessing import MinMaxScaler
mv = pd.DataFrame(movie)
mv
Out[16]:
daum | naver | |
---|---|---|
0 | 2 | 1 |
1 | 4 | 2 |
2 | 6 | 3 |
3 | 8 | 4 |
4 | 10 | 5 |
In [18]:
# MinMaxScaler 를 사용해
# 다른 두 값을 0 ~ 1 사이의 값으로
# 바꿔준다
m = MinMaxScaler()
min_max_mv = m.fit_transform(mv)
pd.DataFrame(min_max_mv, columns=['d', 'b'])
Out[18]:
d | b | |
---|---|---|
0 | 0.00 | 0.00 |
1 | 0.25 | 0.25 |
2 | 0.50 | 0.50 |
3 | 0.75 | 0.75 |
4 | 1.00 | 1.00 |
In [ ]:
In [ ]:
In [19]:
df = pd.read_csv("../data_set/5.스케일링/bank_train_clean.csv")
df.head()
Out[19]:
age | duration | campaign | pdays | previous | y | |
---|---|---|---|---|---|---|
0 | 58 | 261 | 1 | -1 | 0 | 0 |
1 | 44 | 151 | 1 | -1 | 0 | 0 |
2 | 33 | 76 | 1 | -1 | 0 | 0 |
3 | 47 | 92 | 1 | -1 | 0 | 0 |
4 | 33 | 198 | 1 | -1 | 0 | 0 |
In [20]:
df.columns
Out[20]:
Index(['age', 'duration', 'campaign', 'pdays', 'previous', 'y'], dtype='object')
In [21]:
features = ['age', 'duration', 'campaign', 'pdays', 'previous']
label = 'y'
X, y = df[features], df[label]
In [22]:
from sklearn.model_selection import train_test_split
# 학습용 70%, 테스트용 30%
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)
In [26]:
from sklearn.ensemble import RandomForestClassifier
# 머신 생성
rfc = RandomForestClassifier()
# 머신 학습
rfc.fit(X_train, y_train);
print( "학습 데이터 : ", rfc.score(X_train, y_train) )
# 학습된 머신 테스트 결과
print( "test 데이터 : ", rfc.score(X_test, y_test) )
# 학습 데이터의 결과와 테스트 결과의 차이가 커지면
# 과적합 되었다라고 말한다
학습 데이터 : 0.9923847442095617 test 데이터 : 0.8815246240047184
In [ ]:
In [ ]:
In [28]:
from sklearn.neighbors import KNeighborsClassifier
# 머신 생성
kn = KNeighborsClassifier()
# 머신 학습
kn.fit(X_train, y_train)
print( "학습 데이터 : ", kn.score(X_train, y_train) )
# 학습된 머신 테스트 결과
print( "test 데이터 : ", kn.score(X_test, y_test) )
# 학습 데이터와 test 데이터 테스트 결과의
# 차이 폭이 적으므로 좋은 알고리즘이다....
학습 데이터 : 0.9139570891395709 test 데이터 : 0.8846210557357712
In [ ]:
In [ ]:
In [30]:
# 데이터 스케일링
sc = StandardScaler()
sc.fit( X )
X2 = sc.transform( X )
X2
Out[30]:
array([[ 1.60696496, 0.0110161 , -0.56935064, -0.41145311, -0.25194037], [ 0.28852927, -0.41612696, -0.56935064, -0.41145311, -0.25194037], [-0.74738448, -0.70736086, -0.56935064, -0.41145311, -0.25194037], ..., [ 2.92540065, 3.37379688, 0.72181052, 1.43618859, 1.05047333], [ 1.51279098, 0.97014641, 0.39902023, -0.41145311, -0.25194037], [-0.37068857, 0.39932797, -0.24656035, 1.4761376 , 4.52357654]])
In [31]:
X_train, X_test, y_train, y_test = train_test_split(X2, y, test_size=0.3)
In [35]:
# 머신 생성
rfc = RandomForestClassifier()
# 머신 학습
rfc.fit(X_train, y_train);
print( "학습 데이터 : ", rfc.score(X_train, y_train) )
# 학습된 머신 테스트 결과
print( "test 데이터 : ", rfc.score(X_test, y_test) )
# 스케일링된 데이터로 다시 테스트
학습 데이터 : 0.9919423642051379 test 데이터 : 0.8757003833677381
In [36]:
# 머신 생성
kn = KNeighborsClassifier()
# 머신 학습
kn.fit(X_train, y_train)
print( "학습 데이터 : ", kn.score(X_train, y_train) )
# 학습된 머신 테스트 결과
print( "test 데이터 : ", kn.score(X_test, y_test) )
# 스케일링된 데이터로 다시 테스트
학습 데이터 : 0.9128195405567668 test 데이터 : 0.8824830433500442
스케일링을 사용하면 과적합을 줄여줄 수도 있다¶
In [ ]:
In [ ]:
In [41]:
# fit_transform() 을 사용하여 스케일링
X2 = m.fit_transform( X )
X2
Out[41]:
array([[0.51948052, 0.05307035, 0. , 0. , 0. ], [0.33766234, 0.03070354, 0. , 0. , 0. ], [0.19480519, 0.01545344, 0. , 0. , 0. ], ..., [0.7012987 , 0.22915819, 0.06451613, 0.21215596, 0.01090909], [0.50649351, 0.10329402, 0.0483871 , 0. , 0. ], [0.24675325, 0.07340382, 0.01612903, 0.21674312, 0.04 ]])
In [38]:
X_train, X_test, y_train, y_test = train_test_split(X2, y, test_size=0.3)
In [39]:
# 머신 생성
rfc = RandomForestClassifier()
# 머신 학습
rfc.fit(X_train, y_train);
print( "학습 데이터 : ", rfc.score(X_train, y_train) )
# 학습된 머신 테스트 결과
print( "test 데이터 : ", rfc.score(X_test, y_test) )
# 스케일링된 데이터로 다시 테스트
학습 데이터 : 0.9916895756311814 test 데이터 : 0.8786493659687408
In [40]:
# 머신 생성
kn = KNeighborsClassifier()
# 머신 학습
kn.fit(X_train, y_train)
print( "학습 데이터 : ", kn.score(X_train, y_train) )
# 학습된 머신 테스트 결과
print( "test 데이터 : ", kn.score(X_test, y_test) )
# 스케일링된 데이터로 다시 테스트
학습 데이터 : 0.9158846020159889 test 데이터 : 0.8817457976997936
In [ ]:
In [ ]:
In [43]:
# corr() : 데이터 간의 상관관계를 확인
df.corr()
Out[43]:
age | duration | campaign | pdays | previous | y | |
---|---|---|---|---|---|---|
age | 1.000000 | -0.004648 | 0.004760 | -0.023758 | 0.001288 | 0.025155 |
duration | -0.004648 | 1.000000 | -0.084570 | -0.001565 | 0.001203 | 0.394521 |
campaign | 0.004760 | -0.084570 | 1.000000 | -0.088628 | -0.032855 | -0.073172 |
pdays | -0.023758 | -0.001565 | -0.088628 | 1.000000 | 0.454820 | 0.103621 |
previous | 0.001288 | 0.001203 | -0.032855 | 0.454820 | 1.000000 | 0.093236 |
y | 0.025155 | 0.394521 | -0.073172 | 0.103621 | 0.093236 | 1.000000 |
In [45]:
import seaborn as sns
# annot = True : 상관관계 숫자를 출력
sns.heatmap( df.corr(), annot=True )
Out[45]:
<Axes: >
In [55]:
# features = ['age', 'duration', 'campaign', 'pdays', 'previous']
# features = ['age', 'duration', 'campaign', 'previous']
# features = ['age', 'campaign', 'previous']
features = ['age', 'campaign', 'previous']
label = 'y'
X, y = df[features], df[label]
sc = StandardScaler()
sc.fit( X )
X_scaler = sc.transform( X )
X_train, X_test, y_train, y_test = train_test_split(X_scaler, y, test_size=0.3)
In [56]:
rfc = RandomForestClassifier()
rfc.fit(X_train, y_train);
print( "학습 데이터 : ", rfc.score(X_train, y_train) )
print( "test 데이터 : ", rfc.score(X_test, y_test) )
kn = KNeighborsClassifier()
kn.fit(X_train, y_train)
print( "학습 데이터 : ", kn.score(X_train, y_train) )
print( "test 데이터 : ", kn.score(X_test, y_test) )
학습 데이터 : 0.8956615160994723 test 데이터 : 0.8768799764081392 학습 데이터 : 0.8799886245141719 test 데이터 : 0.8695812444706577