본문 바로가기

AI/빅데이터

수치형 데이터 다루기

특성 스케일 바꾸기

- 최소 최대 스케일링은 특성의 최솟값과 최댓값을 사용하여 일정 범위 안으로 값2을 조정한다.

import numpy as np
from sklearn import preprocessing

# 특성 만들기
feature = np.array([[-500.5], [100.1], [0], [100.1], [900.9]])

# 스케일러 객체 생성
minmax_scale = preprocessing.MinMaxScaler(feature_range=(0, 1))

# 특성의 스케일을 변환
scaled_feature = minmax_scale.fit_transform(feature)

# 출력
print(scaled_feature)

# 결과
[[0.        ]
 [0.42857143]
 [0.35714286]
 [0.42857143]
 [1.        ]]

 

특성 표준화 화기

- 특성을 평균이 0이고 표준편차가 1이 되도록 반환

import numpy as np
from sklearn import preprocessing

# 특성 만들기
x = np.array([[-1000.1], [-200.2], [500.5], [600.6], [900.9]])

# 변환기 생성
scaler = preprocessing.StandardScaler()

# 특성 변환
standardized = scaler.fit_transform(x)

# 출력
print(standardized)

# 결과
[[-1.69825773]
 [-0.52763593]
 [ 0.49781062]
 [ 0.64430298]
 [ 1.08378007]]
 
 # 평균 출력
print("평균: ", round(standardized.mean()))

# 결과
평균:  0

# 표준편차 출력
print("표준 편차: ", standardized.std())

# 결과
표준 편차:  1.0

- 데이터에 이상치가 많을 경우에는 특성의 평균과 표준편차에 영향을 끼치기 때문에 표준화에 부정적인 효과를 끼침.

이런 경우에는 중간값과 사분위 범위를 사용하여 특성의 스케일을 조정

# 변환기 객체 생성
robust_scaler = preprocessing.RobustScaler()

# 특성을 변환
print(robust_scaler.fit_transform(x))

# 결과
[[-1.87387612]
 [-0.875     ]
 [ 0.        ]
 [ 0.125     ]
 [ 0.5       ]]

- 데이터를 오름차순으로 나열했을 때 75%에 위치한 값(3사분위수)과 25%에 위치한 값(1사분위수)의 차를 사분위 범위라고 부름.

interquatile_range = x[3] - x[1]

print((x- np.median(x)) / interquatile_range)

# 결과
[[-1.87387612]
 [-0.875     ]
 [ 0.        ]
 [ 0.125     ]
 [ 0.5       ]]
 

 

정규화 하기

import numpy as np
from sklearn.preprocessing import Normalizer

# 특성 만들기
features = np.array([[0.5, 0.5], [1.1, 3.4], [1.5, 20.2], [1.63, 34.4], [10.9, 3.3]])

# 변환기 객체를 생성
normalizer = Normalizer(norm = "l2")

# 특성 행렬을 변환
print(normalizer.transform(features))

# 결과
[[0.70710678 0.70710678]
 [0.30782029 0.95144452]
 [0.07405353 0.99725427]
 [0.04733062 0.99887928]
 [0.95709822 0.28976368]]

# L2 노름을 사용한 변환
print(features / np.sqrt(np.sum(np.square(features), axis = 1, keepdims=True)))

# 결과
[[0.70710678 0.70710678]
 [0.30782029 0.95144452]
 [0.07405353 0.99725427]
 [0.04733062 0.99887928]
 [0.95709822 0.28976368]]
 
 # 각 행에서 최댓값으로 나누기
print(Normalizer(norm="max").transform(features))

# 결과
[[1.         1.        ]
 [0.32352941 1.        ]
 [0.07425743 1.        ]
 [0.04738372 1.        ]
 [1.         0.30275229]]

 

다항 특성과 교차항 특성 생성하기

import numpy as np
from sklearn.preprocessing import PolynomialFeatures

# 특성 만들기
features = np.array([[2, 3], [2, 3], [2, 3]])

# 객체 생성(degree는 다항식의 최대 차수 결정 ex)degree=3 -> 3제곱까지 새로운 특성 생성
polynomial_interaction = PolynomialFeatures(degree=2, include_bias=False)

# 다항 특성 생성
print(polynomial_interaction.fit_transform(features))

# 결과
[[2. 3. 4. 6. 9.]
 [2. 3. 4. 6. 9.]
 [2. 3. 4. 6. 9.]]
 
 # interaction_only 를 True로 지정하면 교차항 특성만 생성가능
interaction = PolynomialFeatures(degree=2, interaction_only=True, include_bias=False)
print(interaction.fit_transform(features))

# 결과
[[2. 3. 6.]
 [2. 3. 6.]
 [2. 3. 6.]]

 

특성 변환하기

import numpy as np
from sklearn.preprocessing import FunctionTransformer

# 특성 만들기
features = np.array([[2, 3], [2, 3], [2, 3]])

# 덧셈 함수
def add(x):
    return x + 10

# 변환기 객체 생성
ten = FunctionTransformer(add)

# 특성 행렬 변환
print(ten.transform(features))

#결과
[[12 13]
 [12 13]
 [12 13]]

이상치 감지하기

import numpy as np
from sklearn.covariance import EllipticEnvelope
from sklearn.datasets import make_blobs

# 모의 데이터 생성
features, _ = make_blobs(n_samples= 10, n_features=2, centers=1, random_state=1)

# 첫 번쨰 샘플을 극단적인 값2으로 변경
features[0, 0] = 10000
features[0, 1] = 10000

# 이상치 감지 객체 생성
outlier_detector = EllipticEnvelope(contamination=.1)

# 감지 객체 훈련
outlier_detector.fit(features)

# 이상치 예측
print(outlier_detector.predict(features))

# 결과
[-1  1  1  1  1  1  1  1  1  1]

# 해당 방식의 단점은 이상치의 비율을 정하는 contamination 매개변수를 지정해야하는 것이다.

# 사분위 범위를 이용한 이상치 탐지
# 특성 생성
feature = features[:, 0]

# 이상치의 인덱스를 반환하는 함수
def indices_of_outliers(x):
    q1, q3 = np.percentile(x, [25, 75])
    iqr = q3 - q1
    lower_bound = q1 - (iqr * 1.5)
    upper_bound = q3 + (iqr * 1.5)
    return np.where((x > upper_bound) | (x < lower_bound))

# 함수 실행
print(indices_of_outliers(feature))

# 결과
(array([0], dtype=int64),)

 

이상치 다루기

- 일반적으로 이상치를 다루는 방법은 1. 이상치를 삭제하기 2. 이상치를 표시하고 이를 특성의 하나로 포함시키기

3. 이상치의 영향이 줄어들도록 특성을 변환하기

1. 이상치 삭제

import pandas as pd

# 데이터프레임 생성
house = pd.DataFrame()
house['Pirce'] = [534433, 392333, 293222, 4322032]
house['Bathroom'] = [2, 3.5, 2, 116]
house['Square_Feet'] = [1500, 2500, 1500, 48000]

# 샘플을 필터링하기
print(house[house['Bathroom'] < 20])

# 결과
    Pirce  Bathroom  Square_Feet
0  534433       2.0         1500
1  392333       3.5         2500
2  293222       2.0         1500

 

2. 이상치를 표시하고 이를 특성의 하나로 포함시키기

import numpy as np
# 조건을 기반으로 특성 생성
house['Outlier'] = np.where(house['Bathroom'] < 20, 0, 1)

# 출력
print(house)

# 결과
     Pirce  Bathroom  Square_Feet  Outlier
0   534433       2.0         1500        0
1   392333       3.5         2500        0
2   293222       2.0         1500        0
3  4322032     116.0        48000        1

 

3. 이상치의 영향이 줄어들도록 특성을 변환하기

# 로그 특성
house["log_of_square_feet"] = [np.log(x) for x in house["Square_Feet"]]

# 출력
print(house)


# 결과
     Pirce  Bathroom  Square_Feet  Outlier  log_of_square_feet
0   534433       2.0         1500        0            7.313220
1   392333       3.5         2500        0            7.824046
2   293222       2.0         1500        0            7.313220
3  4322032     116.0        48000        1           10.778956

 

특성 이산화하기

import numpy as np
from sklearn.preprocessing import Binarizer

# 특성 생성
age = np.array([[6], [12], [20], [36], [65]])

# Binarizer 객체 생성
binarizer = Binarizer(18)

# 특성 변환
print(binarizer.fit_transform(age))

# 결과
[[0]
 [0]
 [1]
 [1]
 [1]]
 
 # 임계값에 따라 나누기
 print(np.digitize(age, bins=[20, 30, 64]))
 
 # 결과
 [[0]
 [0]
 [1]
 [2]
 [3]]
 

 

군집으로 샘플을 그룹으로 묶기

import pandas as pd
from sklearn.datasets import make_blobs
from sklearn.cluster import KMeans

# 모의 특성 행렬 생성
features, _ = make_blobs(n_samples=50, n_features=2, centers = 3, random_state= 1)

# 데이터 프레임 생성
dataframe = pd.DataFrame(features, columns=["feature_1", "feature_2"])

# K-평균 군집 모델 생성
clusterer = KMeans(3, random_state=0)

# 모델 훈련
clusterer.fit(features)

# 그룹 소속을 예측
dataframe["group"] = clusterer.predict(features)

# 샘플 조회
print(dataframe.head(5))

# 결과
   feature_1  feature_2  group
0  -9.877554  -3.336145      0
1  -7.287210  -8.353986      2
2  -6.943061  -7.023744      2
3  -7.440167  -8.791959      2
4  -6.641388  -8.075888      2

 

누락된 값을 가진 샘플 삭제

import numpy as np

# 특성 행렬 생성
features = np.array([[1.1, 11.1], [2.2, 22.2], [3.3, 33.3], [4.4, 44.4], [np.nan, 55]])

# 누락된 값이 없는 샘플만 삼기기
print(features[~np.isnan(features).any(axis=1)])

# 결과
[[ 1.1 11.1]
 [ 2.2 22.2]
 [ 3.3 33.3]
 [ 4.4 44.4]]
 
 
# 판다스를 이용해 누락된 값 삭제

import pandas as pd

# 데이터 적재
df = pd.DataFrame(features, columns=['feature_1', 'feature_2'])

# 누락된 값이 있는 샘플 제거
print(df.dropna())

# 결과
   feature_1  feature_2
0        1.1       11.1
1        2.2       22.2
2        3.3       33.3
3        4.4       44.4

 

 

'AI > 빅데이터' 카테고리의 다른 글

텍스트 다루기  (0) 2021.06.24
범주형 데이터 다루기  (0) 2021.06.23
3.하둡-YARN  (0) 2021.02.18
3.하둡-맵리듀스  (0) 2021.02.18
3.하둡-2  (0) 2021.02.18