데이터 분석 • 처리

데이터에 NULL이 포함되면 어떻게 처리해야할까? (결측치 처리)

AIstarter 2024. 3. 16. 22:23

데이터셋에서 NULL 값이 있을 경우, 어떻게 해야할까요?

이번에는 데이터셋에 NULL 값이 표함된 경우 어떻게 해결하면 되는지 다룹니다.

 

데이터 정보가 빈/ 없는 데이터은 NULL로 표시되는데, 이를 " 데이터가 결측치를 포함하고 있다"라고 표현합니다.

먼저, 데이터셋에 NULL값이 포함되어 있는지 확인하기 위해 isnull(), isna() 함수를 사용할 수 있습니다.

# true/false로 null인지 아닌지 출력하는 함수
df.isnull()
df.isna()

#null 값의 개수 확인
df.isnull().sum() 
df.isna().sum()

 

결측치가 존재할 때, 우리는 어떤 식으로 결측치가 만들어 지는 것이고? 그 결측치를 어떻게 처리해야되는가?를 고민해야합니다. 

 

전체 데이터셋의 1% 미만 정도면 결측치는 날려도 큰 영향은 없을 수 있습니다.

하지만, 결측치가 많아지면 결측값을 대체하거나 결측값이 포함된 행/열을 제거하는 방법으로 이를 해결해야 한다.

이를 결측치 처리라고 합니다. 결측치 처리데이터 전처리 기법 중에 가장 흔히 쓰이는 대표적인 방식입니다.


결측치는 크게 '채울 수 있는 경우'와 '채울 수 없는 경우'로 나뉩니다.

 

채울 수 없는 경우

채울 수 없는 경우는 dropna() 함수를 사용해서 null인 값을 삭제할 수 있습니다.

# null 값 삭제
df.dropna()

채울 수 있는 경우

채울 수 있는 경우에는 다양한 처리 기법들이 존재합니다.

이때, 도메인 지식을 고려하여 비지니스나, 데이터 베이스 로직에 따라서 데이터 결측치를 채워야합니다.

 

결측치를 채울 수 있는 대표적인 방법은 다음과 같습니다.

- 평균, 중위값 등등 통계적인 수치로 대입
- 보간법 사용
도메인 로직에 의한 데이터 결측치 처리
Machine Learning을 통한 데이터 결측치 처리

 

이 중에서 통계적인 수치 대입과 보간법을 사용한 결측치 처리 방법은 해당 포스팅에서 더 다루고자합니다.

 

1. 통계적인 수치 대입

fillna() 함수를 사용하여 대체하기

# Cases_Guinea column의 na값을 평균으로 넣는 경우
df_sp['Cases_Guinea'].fillna(df_sp['Cases_Guinea'].mean()).to_frame()

# na값에 대한 0값으로 대체
df_sp['Cases_Guinea'].fillna(0).to_frame()

- 상황에 따라, 평균값(mean), 중앙값(median), 최솟값(min), 최댓값(max) 등 다양한 통계적인 값을 적용할 수 있습니다.

 

결측치 포함 상태의 데이터
결측치 '0'으로 채운 경우
결측치를 '평균'으로 채운 경우
결측치를 '중앙값'으로 채운 경우

ffil, bfill 두 가지 방법도 사용 가능

# ffill 정방향으로 채우는 방법
df_sp['Cases_Guinea'].fillna(method='ffill').to_frame()

# bfill 역방향으로 채우는 방법
df_sp['Cases_Guinea'].fillna(method='bfill').to_frame()

결측값 포함 데이터 →  ffill로 결측값 처리 경우   →   bfill로 결측값 처리 경우

 

2. 보간법

보간법(補間法)은 알려진 데이터 지점의 고립점 내에서 새로운 데이터 지점을 구성하는 방식이다.

 

보간법에 여러 매서드 존재가 존재한다.

  • ['linear', 'time', 'index', 'values', 'nearest', 'zero', 'slinear', 'quadratic', 'cubic', 'barycentric', 'krogh', 'spline', 'polynomial', 'from_derivatives', 'piecew ise_polynomial', 'pchip', 'akima', 'cubicspline']

 

보간법은 아래와 같이 interpolate() 함수를 사용하면됩니다.

df_sp['Cases_Guinea'].interpolate().to_frame()

 

그 중 자주 사용하는 것은 다음과 같다.

- 선형보간 (linear)
- time 날짜별, 시간 단위로 차이 고려하여 간격처리
- index, values 인덱스 숫자로 진행
- nearest, slinear, quadratic, cubic, interploate(중위값), inter1d → 인덱스 숫자를 사용해서 진행
- spline, polynominal  → 2차,3차 다항식으로 보간하는 방법
- 기존의 보간을 다른 방식으로 다양하게 진행할 수 있습니다.

 

결측치 포함 상태의 데이터
보간법( '중앙값' )을 사용하여 결측치를 채운 경우

 

 

#median으로
dfe['Cases_Liberia'].interpolate().plot()
dfe['Cases_Liberia'].interpolate(method='quadratic').plot()
dfe['Cases_Liberia'].interpolate(method='slinear').plot()
dfe['Cases_Liberia'].interpolate(method='cubic').plot()

 

 

 

결측치 보간 패키지

보간 패키지를 사용하면, 통계치들을 쉽게 대입해서 결측치에 대처할 수 있습니다.

 

** 결측치 보간 패키지1 ㅣ Simpleimputer
missing value 채울 때 다양한 방법으로 쉽게 채울 수있다
- mean
- median
- most_frequent
- constant

사용 방법 : {평균저장 변수} = Simpleimputer (strategy = 'mean')

from sklearn.impute import SimpleImputer

sim_mean=SimpleImputer(strategy = 'mean') #strategy에 mean,median 등 사용할 방법 넣기
np.array(dfe['Cases_Liberia']).reshape(-1,1)
sim_mean.fit(np.array(dfe['Cases_Liberia']).reshape(-1,1))
print(sim_mean.transform(np.array(dfe['Cases_Liberia']).reshape(-1,1)))


** 결측치 보간 패키지2 ㅣ IterativeImputer

사용방법 : 
imputer = iterativeImputer(imputation_order = 'descending' , max_iter=10, randomstate= 111, n_nearest_feature=3)

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

imputer=IterativeImputer(imputation_order= 'descending', max_iter=10, random_state=111, n_nearest_features=3)
dfe_sp =dfe[['Cases_Guinea','Cases_Liberia','Cases_SierraLeone','Cases_Nigeria']] # 적용할 데이터 category
dfe_sp_imp=imputer.fit_transform(dfe_sp)

 

 

 

이번 포스팅은 여기까지 다루도록 하겠습니다. 

피드백이나 궁금한 점은 언제나 환영입니다:)