without haste but without rest

04. Interpolation / Normalization & Standardization 본문

Homework/DataMining

04. Interpolation / Normalization & Standardization

JinungKim 2020. 4. 21. 11:49

0. 개요

 

1. 결측치 보간법

- 데이터들의 null 값을 채우는 작업이다.

- 단, 타겟 데이터가 null인 경우는 삭제한다.

 

2. 정규화 & 표준화

- 정규화는 계산 결과값이 0과 1사이에 위치한다.

- 표준화는 표준편차 1을 갖고, 0을 중심으로 값들이 재배열된다.

 

* 따라서 정규화는 데이터를 특정 범위로 제한하는 것이고,

  표준화는 모수를 고정시켜서 모수를 중심으로 재배열하는 것이다.


1. 데이터 로드

# 모듈 없이 전처리
#===============================

import pandas as pd

iris = pd.read_csv("./iris_missing_values.csv")
print(iris.head())

# NA: Not available
# NaN: Not a number
# null


print(iris.index)

# 인덱스 추가하기, 컬럼 네임은 record
iris.index.name = "record"
print(iris.head())

 

# 레코드 컬럼 추가

 


2. 컬럼 리네임

print(iris.columns)


iris.rename(columns = {iris.columns[0] : 'Sepal.Length',  
                       iris.columns[1] : 'Sepal.Width',
                       iris.columns[2] : 'Petal.Length',
                       iris.columns[3] : 'Petal.Width',
                       iris.columns[4] : 'Species'}, 
                       inplace = True)
                       

 


★[결측치 보간]

 

3. 결측치 확인

## check whether missing values(NaN) is in
print(iris.describe().transpose())

print(iris['Sepal.Length'].isnull())				# 전체 데이터 출력

print(iris['Sepal.Length'].isnull().values.any())	# 하나라도 결측치가 있는가? 불리언 반환

# sum isnull values
print(iris['Sepal.Length'].isnull().values.sum())	# 결측치 개수 

print(iris.values)

 


4. 결측치 채우기

## fill NaN with new value
print(iris['Sepal.Length'].fillna(0.0))

## drop rows with missing data
print(iris.dropna(axis = 0)) # 0: row

## drop columns with missing data
print(iris.dropna(axis = 1)) # 1: col

 

 

sepal.length의 결측치를 0.0으로 채운다. 따라서 sepal.length 속성의 개수가 150개가 되었다.


5. 평균값으로 결측치 채우기

# 평균값으로 결측값 수정
import numpy as np

np.nanmean([1, 2, np.NaN, 4, 5])

np.mean([1, 2, np.NaN, 4, 5])

np.nanmean([1, 2, 3.0, 4, 5])


print(iris['Sepal.Length'].mean())


# skipna = True 지정을 안해주면 nan 값까지 같이 계산한다.
print(iris['Sepal.Length'].mean(skipna = False))
#


# sepal.length의 평균값으로 결측치를 보간한다.
Sepal_Length_mean = iris['Sepal.Length'].mean()
iris['Sepal.Length'] = iris['Sepal.Length'].fillna(Sepal_Length_mean)
print(iris.head())

 

나머지 변수도 위와 같은 방법으로 결측치를 전처리 한다.

 

*단, 타켓 데이터가 결측치인 경우 드랍 해주어야 한다. 

print(iris.describe().transpose())

Sepal_Width_mean = iris['Sepal.Width'].mean()
iris['Sepal.Width'] = iris['Sepal.Width'].fillna(Sepal_Width_mean)

Petal_Length_mean = iris['Petal.Length'].mean()
iris['Petal.Length'] = iris['Petal.Length'].fillna(Petal_Length_mean)

Petal_Width_mean = iris['Petal.Width'].mean()
iris['Petal.Width'] = iris['Petal.Width'].fillna(Petal_Width_mean)

print(iris.describe().transpose())

print(iris.isnull())

print(iris.isnull().values.any())

print(iris.isnull().values.sum())

print(iris.describe().transpose())

print(iris.values)

iris = iris.dropna(axis = 0)

print(iris.values)

 


6. scikit-learn imputer module

 

그러나 사이킷 런의 임퓨트 라이브러리로 결측치를 쉽게 처리할 수도 있다.

 

## scikit-learn SimpleImputer()
iris = pd.read_csv("./iris_missing_values.csv")
cols = iris.columns

print(cols[:-1])

from sklearn.impute import SimpleImputer

imputer = SimpleImputer(missing_values = np.nan, strategy = 'mean')

out_imp = imputer.fit_transform(iris[cols[:-1]])
print(out_imp)

iris_imp = pd.DataFrame(data = out_imp, columns = cols[:-1])
iris_imp = pd.concat([iris_imp, iris['species']], axis = 1)

print(iris_imp.values)

iris_imp = iris_imp.dropna(axis = 0)

print(iris_imp.values)

 

 

species는 타겟 데이터이고, 범주형 자료이므로 결측치를 보간하지 않고 삭제한다. -> 3개 삭제

따라서 전체 데이터의 row 는 147이다.

 

 

 


[정규화]

정규화와 표준화를 진행하더라도 이전의 데이터로 돌릴 수 있게 해두어야 한다.

 

다시 계산하는 것 보다는 원본 데이터를 남겨두고 _norm과 _stand 를 붙인 변수를 추가로 만들어주는 게 정신건강에 이로울 것 같다.

 

7. 정규화 (최소-최대 정규화)

 

Min-Max Norm  =  value - min / max - min

## Normalization

print(iris_imp.columns)

iris_imp.rename(columns = {iris.columns[0] : 'Sepal.Length',  
                       iris.columns[1] : 'Sepal.Width',
                       iris.columns[2] : 'Petal.Length',
                       iris.columns[3] : 'Petal.Width',
                       iris.columns[4] : 'Species'}, 
                       inplace = True)

print(iris_imp.columns)


## 가장 많이, 흔히 사용하는 방법 
## Min-Max Normalization

# x_new = (x - min(x)) / (max(x) - min(x))

Sepal_Length_min = iris_imp['Sepal.Length'].min()
Sepal_Length_max = iris_imp['Sepal.Length'].max()
iris_imp['Sepal.Length.norm'] = 
	(iris_imp['Sepal.Length'] - Sepal_Length_min) / (Sepal_Length_max - Sepal_Length_min)


print(iris_imp.head())

 

Sepal_Width_min = iris_imp['Sepal.Width'].min()
Sepal_Width_max = iris_imp['Sepal.Width'].max()
iris_imp['Sepal.Width.norm'] = (iris_imp['Sepal.Width'] - Sepal_Width_min) / (Sepal_Width_max - Sepal_Width_min)

Petal_Length_min = iris_imp['Petal.Length'].min()
Petal_Length_max = iris_imp['Petal.Length'].max()
iris_imp['Petal.Length.norm'] = (iris_imp['Petal.Length'] - Petal_Length_min) / (Petal_Length_max - Petal_Length_min)

Petal_Width_min = iris_imp['Petal.Width'].min()
Petal_Width_max = iris_imp['Petal.Width'].max()
iris_imp['Petal.Width.norm'] = (iris_imp['Petal.Width'] - Petal_Width_min) / (Petal_Width_max - Petal_Width_min)


print(iris_imp.describe().transpose())

 

시각화

import seaborn as sns
import matplotlib.pyplot as plt

sns.set(style = "white", palette = "muted", color_codes = True)

plt.figure(figsize = (8, 2.5))
sns.scatterplot(x = 'Sepal.Length', y = 'Petal.Width', hue = 'Species', data = iris_imp)
plt.show()

plt.figure(figsize = (8, 8))
sns.scatterplot(x = 'Sepal.Length.norm', y = 'Petal.Width.norm', hue = 'Species', data = iris_imp)
plt.show()

 

 

기존 데이터

 

정규화한 데이터

데이터를 시각화했을 때 더 자세히 볼 수 있다.

 


8. scikit-learn module for preprecessing

-*정규화 모듈

#===============================
# 사이킷런 사용 
from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler()

out_scaled = scaler.fit_transform(iris[iris.columns[:-1]])

print(out_scaled)



"""
이용하고자 하는 데이터가 양수를 전제로 하는지 등 데이터의 특색을 고려해서
어떤 방법이 더 적절한지 선택해야한다. (정규화, 표준화 )
"""


[표준화]

9. 표준화

정규화와 메커니즘은 같지만 식이 다르다.

value - mean / std(표준편차)

 

#===============================
## Standardization
## Z function

# x_new = (x - mean(x)) / std(x)

Sepal_Length_mean = iris_imp['Sepal.Length'].mean()
Sepal_Length_std = iris_imp['Sepal.Length'].std()
iris_imp['Sepal.Length.stand'] = (iris_imp['Sepal.Length'] - Sepal_Length_mean) / Sepal_Length_std

print(iris_imp.describe().transpose())

# 0.01 <-> 1E-2
# 10 <-> 1E+1

Sepal_Width_mean = iris_imp['Sepal.Width'].mean()
Sepal_Width_std = iris_imp['Sepal.Width'].std()
iris_imp['Sepal.Width.stand'] = (iris_imp['Sepal.Width'] - Sepal_Width_mean) / Sepal_Width_std

Petal_Length_mean = iris_imp['Petal.Length'].mean()
Petal_Length_std = iris_imp['Petal.Length'].std()
iris_imp['Petal.Length.stand'] = (iris_imp['Petal.Length'] - Petal_Length_mean) / Petal_Length_std

Petal_Width_mean = iris_imp['Petal.Width'].mean()
Petal_Width_std = iris_imp['Petal.Width'].std()
iris_imp['Petal.Width.stand'] = (iris_imp['Petal.Width'] - Petal_Width_mean) / Petal_Width_std


print(iris_imp.describe().transpose())


# hue 옵션에 그룹을 지정해주면 그룹별로 색상을 지정한다
plt.figure(figsize = (8, 8))
sns.scatterplot(x = 'Sepal.Length.stand', y = 'Petal.Width.stand', hue = 'Species', data = iris_imp)
plt.show()

 

 

 

표준화 한 아이리스 데이터의 스캐터 플롯


10. categorical data preprocessing (6강 자료로 넘어가기)

범주형 자료의 경우 수치화 시켜준다.

따라서 수치화를 진행시켜준 경우 이와 관련된 메모를 남겨두는 게 좋다.

# 범주형 자료
#===============================


## Categorical Data

# ordinal encoding

jump = pd.read_csv('./long_jump.csv')

print(jump)


print(jump.describe().transpose())

jump['Jersey Size cate'] = jump['Jersey Size']

for idx, js in enumerate(jump['Jersey Size']):
    if js == 'small':
        jump.loc[idx, 'Jersey Size cate'] = 0
    elif js == 'medium':
        jump.loc[idx, 'Jersey Size cate'] = 1
    elif js == 'large':
        jump.loc[idx, 'Jersey Size cate'] = 2

print(jump.transpose())

## loc 메소드는[row, col] 방법으로 접근함


# 위 코드의 접근 방법
for idx, val in enumerate(['a', 'b', 'c']):
    print('index %s, value %s' % (idx, val))




jump['Shoe Size cate'] = jump['Shoe Size']

for idx, js in enumerate(jump['Shoe Size']):
    if js == 7:
        jump.loc[idx, 'Shoe Size cate'] = 0
    elif js == 9:
        jump.loc[idx, 'Shoe Size cate'] = 1
    elif js == 10:
        jump.loc[idx, 'Shoe Size cate'] = 2
    elif js == 12:
        jump.loc[idx, 'Shoe Size cate'] = 3

print(jump.transpose())

 

 


11. scikit-learn OrdinalEncoder

# load data
df = pd.read_csv("./long_jump.csv")
df.set_index('Person', inplace=True)

# apply categories filter
cats = ['Jersey Size', 'Shoe Size']
print(df[cats])

# import module and initialize object
from sklearn.preprocessing import OrdinalEncoder
enc = OrdinalEncoder()


# transform object 
out_enc = enc.fit_transform(df[cats])
print('identified categories: ')
print(enc.categories_)
print('encoded data: ')
print(out_enc)

 

 


*정규화 vs 표준화

정규화는 계산 결과값이 0과 1사이에 위치한다.

반면에 표준화는 표준편차 1을 갖고, 0을 중심으로 값들이 재배열

 

따라서 정규화는 특정 범위로 제한하는 것이고, 표준화는 모수를 고정시켜서 모수를 중심으로

재배열하는 것이다.

 

'Homework > DataMining' 카테고리의 다른 글

06. Feature Selection  (0) 2020.05.01
05. One-Hot Encoding  (0) 2020.05.01
03. Visualization with Seabron  (0) 2020.04.14
02. Data Load with sqlite3  (0) 2020.04.07
01. Data Exploration & Visualization  (0) 2020.03.24
Comments