본문으로 바로가기

sklearn : MinMaxScaler

category 알고리즘/Deep Learning 2021. 1. 24. 00:28
728x90
반응형

딥러닝에 사용되는 데이터의 범위가 각 Feature 마다 다릅니다. 각 Feature의 값을 일정한 범위로 조정하기 위해서는 데이터의 전처리 과정 중의 하나인 스케일링이 필요합니다. 스케일링의 목적은 크게 2가지로 구분할 수 있습니다.

 

1. 서로 다른 Feature 데이터의 범위를 통일하기 위함입니다. 예를들어 수량은 1개~10개의 범위의 데이터 값을 가지고, 가격은 1,000원~100,000원의 데이터를 범위를 가질 경우, 이 각 Feature는 1,000배에서 10,000배의 차이가 생깁니다.

이러한 차이의 발생을 조정하기 위해서 스케일이 필요합니다. 

MinMaxScaler를 사용하는 방법을 알아 보겠습니다. 아래의 소스를 실행해 보세요.

 

from sklearn.preprocessing import MinMaxScaler

data1 = [[1, 200], [3, 3000], [5, 6000], [7, 12000], [9, 24000]]

scaler = MinMaxScaler()
print(scaler)

scaler.fit(data1)
print(scaler.n_samples_seen_)
print(scaler.feature_range)
print(scaler.data_min_)
print(scaler.data_max_)
MinMaxScaler()
5
(0, 1)
[  1. 200.]
[9.0e+00 2.4e+04]

 

위의 예는 data1의 MinMaxScaler의 fitting 결과를 출력한 것입니다. 샘플의 개수는 5개이고, Feature 값의 범위는 0에서 1 사이로 나타납니다. 최솟값은 1과 200이며, 최댓값은 9와 24,000입니다.

아래의 예는 이 데이터 범위에 새로운 데이터를 추가하여 범위를 재조정합니다.

 

from sklearn.preprocessing import MinMaxScaler

data1 = [[1, 200], [3, 3000], [5, 6000], [7, 12000], [9, 24000]]
data2 = [[-3, 50], [2, 25000], [4, 54000], [6, 150000], [8, 370000]]

scaler = MinMaxScaler()
print(scaler)
scaler.fit(data1)
print(scaler.n_samples_seen_)
print(scaler.feature_range)
print(scaler.data_min_)
print(scaler.data_max_)
scaler.partial_fit(data2)
print(scaler.n_samples_seen_)
print(scaler.feature_range)
print(scaler.data_min_)
print(scaler.data_max_)

 

MinMaxScaler()
5
(0, 1)
[  1. 200.]
[9.0e+00 2.4e+04]
10
(0, 1)
[ -3. 50.]
[9.0e+00 3.7e+05]

partial_fit() 함수를 이용하여  기존의 fiting 범위에 새로운 데이터의 범위로 수정되었음을 확인할 수 있습니다. 기존의 min 값 [1, 200]이 새로운 값[-3 50]으로 변경되었고, max 값[9 240000]이 새로운 값[9 370000]으로 수정되었습니다.

만약 fit() 함수를 사용할 경우 기존의 범위는 초기화되고, 새로운 입력 데이터를 기준으로 범위를 설정하게 됩니다.

 

다음은 만들어진 스케일러를 이용하여 데이터를 변환하겠습니다. 아래의 예를 실행한 후 결과를 확인하세요.

 

from sklearn.preprocessing import MinMaxScaler

data1 = [[1, 200], [3, 3000], [5, 6000], [7, 12000], [9, 24000]]
data2 = [[-3, 500], [2, 25000], [4, 54000], [6, 150000], [8, 370000]]

scaler = MinMaxScaler(feature_range=(1, 100))
scaler.fit(data1)
scaler.partial_fit(data2)

new_data1 = scaler.transform(data1)
print("new_data1:")
print(new_data1)
new_data2 = scaler.transform(data2)
print("new_data2:")
print(new_data2)

 

new_data1:
[[ 34.           1.        ]
 [ 50.5          1.74959438]
 [ 67.           2.55273121]
 [ 83.5          4.15900487]
 [100.           7.37155219]]
new_data2:
[[  1.           1.08031368]
 [ 42.25         7.63926447]
 [ 58.75        15.4029205 ]
 [ 75.25        41.10329908]
 [ 91.75       100.        ]]

 

위의 예제에서 feature범위를 1에서 100으로 정의하고 data1과 data2를 스케일 변환을 수행했습니다. 수정된 범위를 기준으로 각각의 데이터 값들이 변경되었습니다.

 

 

2. 데이터들의 정규화를 위해 사용될 수 있습니다. 데이터를 정규화할 경우 다차원 값들에 대한 계산 값들이 작아지고, 오버플로우(overdlow)나 언더플로우(underflow)를 방지하고, 최적화 과정에서 안정성을 확보하고 수렴 속도를 향상하는 장점이 있습니다.

아래의 예제는 feature_range를 0에서 1로 설정하고 변환을 수행한 것입니다. 모든 데이터가 설정한 범위의 값으로 변경되었습니다.

from sklearn.preprocessing import MinMaxScaler

data = [[1000,2000],[3000,4000],[1,2],[3,50]]

scaler = MinMaxScaler(feature_range=(0.0, 1.0))
scaler.fit(data)
print(scaler.n_samples_seen_, scaler.data_min_, scaler.data_max_)
new_data = scaler.transform(data)
print(new_data)
4 [1. 2.] [3000. 4000.]
[[3.33111037e-01 4.99749875e-01]
 [1.00000000e+00 1.00000000e+00]
 [0.00000000e+00 0.00000000e+00]
 [6.66888963e-04 1.20060030e-02]]

 

fit_transform()은 fit()와 transform()을 함께 실행해 줍니다. 만약 fit()와 transform()을 별도로 수행해야 할 경우  이 함수를 사용하면 안됩니다.

 

from sklearn.preprocessing import MinMaxScaler

data = [[1000,2000],[3000,4000],[1,2],[3,50]]

scaler = MinMaxScaler(feature_range=(0.0, 1.0))
new_data = scaler.fit_transform(data)
print(new_data)

 

[[3.33111037e-01 4.99749875e-01]
 [1.00000000e+00 1.00000000e+00]
 [0.00000000e+00 0.00000000e+00]
 [6.66888963e-04 1.20060030e-02]]

 

추가로 스케일 된 값을 이요하여 원래의 값으로 변환이 필요한 경우 inverse_transform() 함수를 사용할 수 있습니다.

 

from sklearn.preprocessing import MinMaxScaler

data = [[1000,2000],[3000,4000],[1,2],[3,50]]

scaler = MinMaxScaler(feature_range=(0.0, 1.0))
new_data = scaler.fit_transform(data)
print(new_data)
pre_data = scaler.inverse_transform(new_data)
print(pre_data)
[[3.33111037e-01 4.99749875e-01]
 [1.00000000e+00 1.00000000e+00]
 [0.00000000e+00 0.00000000e+00]
 [6.66888963e-04 1.20060030e-02]]
[[1.e+03 2.e+03]
 [3.e+03 4.e+03]
 [1.e+00 2.e+00]
 [3.e+00 5.e+01]]

 

728x90
반응형