«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
Recent Posts
Today
Total
관리 메뉴

짜리몽땅 매거진

[Python] 데이터에서의 Missing Value 처리 본문

Data/Python

[Python] 데이터에서의 Missing Value 처리

쿡국 2024. 3. 29. 11:23

 

우리가 흔히 분석하고 시각화, 더 나아가 모델링을 하는 과정까지 이어나가기 위해서는 앞단에서 데이터를 분석할 수 있는 형태로 잘 가공하고 전처리해야한다. 전처리해야하는 요소는 여러가지가 있지만 그 중에서 데이터프레임에 빈칸/None/NaN 으로 표시되는 결측값(Missing Value) 처리에 대해 알아보고자 한다.

 

실제 데이터는 우리 입맛에 맞게 원하는 변수(=칼럼), 결측치 없이 모든 값이 들어가 있는 행 등 이미 가공된 형태로 제공되지 않는다. 전처리되지 않은 데이터를 분석하거나 모델에 적용하게 되면 그 결과는 엉망이 되어버린다. 따라서 오늘 다루고자 하는 '결측값'은 꼭 적절한 방법으로의 처리가 필요하다.


0. 결측값의 종류

- MCAR : Missing Completely at Random (완전 무작위 결측) : 다른 변수들과 아무런 관련 없이 완전히 무작위로 결측값이 발생하는 경우

- MNAR : Missing at not Random (비무작위 결측) : 결측값이 다른 변수들과 관련이 있고 해당 변수들로 설명되지 않는 경우
- MAR : Missing at Random (무작위 결측) : 결측값이 다른 변수들과 관련이 있지만 해당 변수들로 설명되는 경우

 

1. 결측값 단순 제거

df 라는 변수명의 데이터프레임이 있다고 가정해보자.

# 모든 컬럼이 결측값인 행 제거(결측값 없는 컬럼이 있으면 제거가 안 된다.)
df_dropall = df.dropna(how='all')

# 두 개 이상의 컬럼이 결측값인 행 제거
df_droptwo= df.dropna(컬럼명 = 2)

# 특정 컬럼을 지정해서 결측값을 제거
df_컬렴명_drop = df.dropna(subset=['컬럼명'])

# 한 컬럼이라도 결측치가 있으면 행 제거 
df_any_drop =df.dropna(how='any')

 

2. 결측값 단순 대체

결측값을 대체하는 방법은 정말 다양한데, 데이터의 분포나 도메인에 따라 다른 방법이 적용된다. 모델링을 위한 대체가 될 수도 있고, 기술적인 집계를 보기 위한 대체일 수도 있기 때문에 다양한 목적에 맞게 접근해야한다.

# 0으로 대체 
df_0fill = df.fillna(0)

# 문자로로 대체 가능
df_hifill = df.fillna('안녕?')

# 평균, 분산, 표준편차, 최대, 최소, 중위 등등 다 가능
# 평균 대체
df_meanfill =df.fillna(df['칼럼명'].mean())

# 컬럼에 따라 대체하는 방법을 다르게 하고 싶은 경우
df_meanfill_sp=df.fillna({'칼럼명':df['칼럼명'].mean()})

 

3. 보간법

보간법은 양쪽 값들 사이에서 중간의 Missing Value를 주변의 값들을 통해서 유추하고 대체한다.

 

보간법에서 interpolate() 함수는 주어진 데이터 프레임 또는 시리즈의 결측값을 선형 또는 다항식 등의 방법을 사용하여 채우는  쓰이며, 여러 옵션을 제공하여 사용자가 원하는 보간 방법을 선택할 수 있다.

 

method 매개변수를 사용하여 선형 이외의 보간 방법을 지정할 수 있는데, 보간 방법에는 선형('linear'), 다항식('polynomial'), 시간('time'), 최근접 이웃('nearest') 등이 있다. 또한 interpolate() 함수는 데이터가 시계열 데이터인 경우 시간 간격을 고려하여 보간을 수행할 수도 있습니다.

#전 시점의 값들로 대체
df['칼럼명'].fillna(method='pad',inplace=True) 

#뒤 시점의 값으로 대치하는 것
df.fillna(method='bfill')

#결측값을 여러 번 대치할지 아니면 한 번만 할지 방법을 조절할 수 있다.
#연속된 결측값이 있으면 한 번만 대치
df.fillna(method='bfill', limit= 1)

#수학적 방법이 아닌 특정 값으로 대치
df_sp_lin=df.interpolate(method='values')

 

4. Simple Imputer

보간법은 양쪽 값들 사이에서 중간의 Missing Value를 주변의 값들을 통해서 유추하고 대체한다.

 

보간법에서 interpolate() 함수는 주어진 데이터 프레임 또는 시리즈의 결측값을 선형 또는 다항식 등의 방법을 사용하여 채우는  쓰이며, 여러 옵션을 제공하여 사용자가 원하는 보간 방법을 선택할 수 있다.

 

method 매개변수를 사용하여 선형 이외의 보간 방법을 지정할 수 있는데, 보간 방법에는 선형('linear'), 다항식('polynomial'), 시간('time'), 최근접 이웃('nearest') 등이 있다. 또한 interpolate() 함수는 데이터가 시계열 데이터인 경우 시간 간격을 고려하여 보간을 수행할 수도 있습니다.

#단순하게 대체할 수 있는 패키지
from sklearn.impute import SimpleImputer

#constant로 지정해 상수로 대체하겠다는 뜻, 이외에도 다양한 strategy가 존재
constant_imputer =SimpleImputer(strategy='constant')

#모델에 fit시키기, 여러개 칼럼도 지정할 수 있다.
df_simple=constant_imputer.fit_transform(df['칼럼명'])

 

5. KNN Imputer

머신러닝 지도 학습의 KNN알고리즘을 활용해 거리 기반으로 결측치를 대체하는 방법이다.

from sklearn.impute import KNNImputer

df_knn = df.copy(deep=True)

#근처 3개 값을 기준으로 대치하고, 각 변수에 동일한 가중치 부여 
knn_imputer = KNNImputer(n_neighbors=3, weights = 'uniform')

# 1차원 컬럼만 넣기 때문에 모델에 fit한 후 행,열 개념으로 바꿔서 배열로 변환
df_knn['칼럼명'] = knn_imputer.fit_transform(np.array(df_knn['칼럼명']).reshape(-1,1)) # 1차원 컬럼만 넣으니깐 행,열 transpoze 개념으로 바꿔서 형식 맞춘 것 배열로 형변환

 

KNNImputer의 하이퍼파라미터로 'weights'가 존재하는데 이에 대한 설명을 덧붙인다.

  • weights = 'uniform' (균일한 가중치): 이 경우, KNN 알고리즘은 각 변수에 동일한 가중치를 부여한다. 즉, 결측값을 채우기 위해 이웃을 선택할 때 각 변수의 거리가 동등하게 고려된다.
  • weights = 'distance' (거리 기반 가중치): 방법에서는 이웃을 선택할 변수 간의 거리에 따라 가중치를 부여한다. 예를 들어, 가까운 변수일수록 높은 가중치를 부여하고, 변수일수록 낮은 가중치를 부여할 있다.

 

5. MICE 다중대치법

Round robin 방식을 반복하여 결측 값을 회귀하는 방식으로 결측치를 처리한다. 결측값을 회귀하는 방식으로 처리하기 때문에 이 방식은 수치형 변수에 자주 사용한다.

from sklearn.experimental import enable_iterative_imputer
from sklearn.impute import IterativeImputer

mice_imputer = IterativeImputer()
df_mice['칼럼명'] = mice_imputer.fit_transform(np.array(train_mice['칼럼명']).reshape(-1,1))

데이터에서 결측값을 처리하는 여러 방식을 살펴보았는데 주의할 점을 다시 한 번 강조하려 한다.

 

- 결측값을 확인하는 과정에서는 데이터의 도메인 지식이 필요하다. 결측값이 유의미한 데이터일 수도 있기 때문에 도메인 지식을 잘 파악하는 것이 중요하다.

 

- 결측치를 삭제하는 방법으로 처리를 하는 것은 많은 리스크가 따른다. 데이터의 삭제는 데이터의 누락으로 이어질 수 있기 때문에 꼭 신중하게 해야하고, 적절한 대치 방법을 탐색해야 한다.