zenn.skin 무료버전 배포중!
자세히보기

DataScience

[ML] SimpleImputer (누락값 처리)

koosco! 2022. 8. 4. 04:39

데이터를 정제하는 과정에서 반드시 필요한 과정 중 하나는 누락값(Nan)의 처리입니다. 누락값을 처리하는 방법에는 1) 누락값을 갖고 있는 행의 삭제, 2) 누락값을 갖는 열(특성)의 삭제, 3) 대체값으로 대체하는 방법이 있습니다.

 

1. 일반적인 누락값 처리 방법

import pandas as pd

df = pd.DataFrame(data)

# 누락값을 갖는 행(레이블) 삭제
df.dropna(subset=['col1'])

# 누락값을 갖는 열(특성) 삭제
df.drop('col1', axis=1) 

# 누락값을 대체값으로 채움
mean = df['col1'].mean()
df['col1'].fillna(mean)

데이터를 모으는 과정에서 누락값의 처리는 꼭 필요한 작업입니다. 누락값을 너무 많이 제거해버리면 힘들게 모은 데이터를 못 쓰게 되버릴 수 있기 때문에 무분별하게 지우기보다는 가능한 한 사용할 수 있는 데이터를 살리는게 중요합니다.

열에 누락값이 너무 많이 포함되어 있거나 분석에 크게 영향을 미치지 않는다면 열(특성)을 삭제해버릴 수 있습니다. 누락값이 크게 많지 않다면 누락값을 갖고 있는 행을 지우거나 중심 경향치를 이용해 값을 채워넣을 수 있습니다. 

 

2. SimpleImputer

위 코드처럼 누락값을 계산한 후 fillna 메서드를 사용해서 값을 채울 수도 있지만 sklearn에서는 이런 과정을 도와주는 class가 있습니다. SimplerImputer는 strategy를 통해 중심 경향치를 어떻게 계산할지 입력받고 누락값을 일괄적으로 처리해줍니다.

from sklearn.impute import SimpleImputer

imputer = SimpleImputer(strategy='mean') 
# strategy: mean(평균값), median(중간값), most_frequency(최빈값), constant(fill_value값)

imputer.fit(df)
ndf = imputer.transform(df)

SimpleImputer는 다른 sklearn 변환기와 마찬가지로 fit과 transform으로 동작합니다. fit을 통해 데이터를 입력받고, 입력받은 데이터를 바탕으로 transform을 통해 누락값을 처리합니다.

주의할 점은 mean, median, most_frequency는 문자열을 처리하지 못하기 때문에 문자열을 처리하려면 문자열을 갖는 열과 갖지 않는 열로 나눈 후에 각각에 변환기를 적용해주어야 한다는 점입니다.

 

import pandas as pd
import numpy as np
from sklearn.impute import SimpleImputer

imputer = SimpleImputer(strategy='mean')

data = {'name': [np.nan, 'b', 'c', np.nan], 'age': [21, 22, np.nan, 26], 'score': [np.nan, 85, 92, np.nan]}
df = pd.DataFrame(data)
imputer.fit(df)
ndf = imputer.transform(df)
ndf # string을 float으로 변환할 수 없어 ValueError가 발생

String열과 float열이 같이 존재

 

import pandas as pd
import numpy as np
from sklearn.impute import SimpleImputer

imputer = SimpleImputer(strategy='constant')

data = {'name': [np.nan, 'b', 'c', np.nan], 'age': [21, 22, np.nan, 26], 'score': [np.nan, 85, 92, np.nan]}
df = pd.DataFrame(data)
imputer.fit(df)
ndf = imputer.transform(df)
ndf

strategy로 constant를 사용하면 'missing_value'로 누락값이 채워집니다.

constant를 이용해 채우는 값은 fill_value 파라미터를 통해 설정할 수 있습니다.

import pandas as pd
import numpy as np
from sklearn.impute import SimpleImputer

imputer = SimpleImputer(strategy='constant', fill_value=0)

data = {'name': [np.nan, 'b', 'c', np.nan], 'age': [21, 22, np.nan, 26], 'score': [np.nan, 85, 92, np.nan]}
df = pd.DataFrame(data)
imputer.fit(df)
ndf = imputer.transform(df)
ndf

 

3. ColumnTransformer와 Pipeline 사용

SimpleImputer를 데이터에 적용하기 전에 문자열로 된 범주형 자료형과 실수값을 갖는 연속형 자료형을 나눈 후, ColumnTransformer를 사용해 각각의 자료에 다른 pipeline을 적용해 데이터를 처리할 수 있습니다.

 

pipeline을 적용하면 연속적으로 변환기를 사용해 데이터를 변환할 수 있습니다.

마지막 단계에서만 추정기/변환기를 사용할 수 있고 그 외에는 모두 변환기만 사용할 수 있습니다.

from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler, OneHotEncoder

num_pipeline = Pipeline([
	('imputer', SimpleImputer(strategy='mean')),
	('std_scaler', StandardScaler()),
])

onehot_encoder = OneHotEncoder()

# data의 속성들
num_attribs = [length, weight, ...] # 연속형 데이터
cat_attribs = [color, hometown, ...] # 범주형 데이터

full_pipeline = ColumnTransformer([
	('num', num_pipeline, num_attribs),
	('cat', onehot_encoder, cat_attribs),
])

result_data = full_pipeline.fit_transform(data)

1. SimpleImputer를 사용하면 데이터에 일괄되게 누락값 처리를 적용할 수 있습니다.

2. 변환기를 적용하기 전에 범주형 데이터와 실수형 데이터를 분리한 후 각각에 다른 처리를 하도록 할 수 있습니다.

3. ColumnTransformer와 Pipeline을 사용하면 변환 과정을 순차적으로 진행할 수 있기 때문에 이해하기 쉽고 깔끔하게 변환할 수 있습니다.

4. SimpleImputer의 반환값은 ndarray이기 때문에 DataFrame으로 사용하려면 추가로 자료형을 바꿔주어야 합니다.

'DataScience'의 다른글

  • 현재글 [ML] SimpleImputer (누락값 처리)

관련글