데이터 사이언스 - 3. 데이터 핸들링과 전처리 (3.2 결측치 처리 (Missing Values))

2025. 3. 20. 12:05데이터 분석/데이터 사이언스

3.2 결측치 처리 (Missing Values)

데이터 분석을 수행할 때 가장 먼저 해야 할 작업 중 하나가 결측치(Missing Values) 처리이다.
결측치는 데이터셋에 누락된 값이 포함된 경우를 의미하며, 잘못된 분석 결과를 초래할 수 있으므로 적절히 처리해야 한다.

이 장에서는 결측치를 찾고, 제거(dropna), 대체(fillna), 그리고 머신러닝 기반으로 처리(SimpleImputer)를 활용하는 방법을 다룬다.
또한, 결측치를 시각적으로 분석하는 방법도 소개한다.


3.2.1 결측치 찾기 및 확인

결측치를 확인하는 기본적인 방법은 isnull() 또는 info()를 활용하는 것이다.

import pandas as pd
import numpy as np

# 샘플 데이터 생성
data = {
    "Name": ["Alice", "Bob", "Charlie", "David", np.nan],
    "Age": [25, np.nan, 30, 35, 40],
    "Score": [85, 90, np.nan, 88, 92]
}

df = pd.DataFrame(data)

# 결측치 확인
print(df.isnull().sum())  # 각 열의 결측치 개수 확인
print(df.info())  # 전체 데이터 정보 확인

결측치 확인 방법

  • df.isnull().sum() → 각 열(column)별 결측치 개수 확인
  • df.info() → 데이터 타입과 결측치 개수 확인

출력 결과 예시:

Name     1
Age      1
Score    1
dtype: int64

3.2.2 결측치 제거 (dropna())

결측치가 적고, 특정 행을 삭제해도 데이터 분석에 큰 영향을 주지 않는다면 dropna()를 사용하여 제거할 수 있다.

# 결측치가 포함된 행 제거
df_drop_rows = df.dropna()
print(df_drop_rows)

옵션 설명

  • dropna() → 결측치가 있는 모든 행 제거
  • dropna(axis=1) → 결측치가 포함된 열 제거
# 결측치가 포함된 열 제거
df_drop_columns = df.dropna(axis=1)
print(df_drop_columns)

주의:
dropna()를 사용하면 결측치가 있는 행/열이 삭제되므로, 데이터가 많이 손실될 수 있다.
데이터 손실을 최소화하려면 결측값을 대체(fillna())하는 방법을 고려하는 것이 좋다.


3.2.3 결측치 대체 (fillna())

fillna()를 사용하면 결측치를 특정 값으로 채울 수 있다.

① 평균, 중앙값, 최빈값으로 대체

# 평균(mean)으로 채우기
df["Age"].fillna(df["Age"].mean(), inplace=True)

# 중앙값(median)으로 채우기
df["Score"].fillna(df["Score"].median(), inplace=True)

print(df)

옵션 설명

  • df.fillna(값) → 특정 값으로 결측치를 채움
  • df.fillna(df["열이름"].mean()) → 평균값으로 채움
  • df.fillna(df["열이름"].median()) → 중앙값으로 채움
  • df.fillna(df["열이름"].mode()[0]) → 최빈값(가장 많이 등장한 값)으로 채움

② 앞/뒤 값으로 채우기 (ffill, bfill)

이전 값(ffill), 다음 값(bfill)을 활용하여 결측치를 채울 수도 있다.

# 앞(이전) 값으로 채우기
df.fillna(method="ffill", inplace=True)

# 뒤(다음) 값으로 채우기
df.fillna(method="bfill", inplace=True)

옵션 설명

  • method="ffill" → 결측치를 앞의 값으로 채움
  • method="bfill" → 결측치를 뒤의 값으로 채움

3.2.4 머신러닝을 활용한 결측치 처리 (SimpleImputer)

결측치를 대체하는 보다 정교한 방법으로 머신러닝 모델을 활용할 수도 있다.
Scikit-learn의 SimpleImputer를 사용하면 평균, 중앙값, 최빈값, 특정 전략을 기반으로 결측치를 자동으로 채울 수 있다.

from sklearn.impute import SimpleImputer

# 평균값으로 결측치 채우기
imputer = SimpleImputer(strategy="mean")
df[["Age", "Score"]] = imputer.fit_transform(df[["Age", "Score"]])

print(df)

옵션 설명

  • strategy="mean" → 평균값으로 채움
  • strategy="median" → 중앙값으로 채움
  • strategy="most_frequent" → 최빈값으로 채움
  • strategy="constant", fill_value=0 → 특정 값(예: 0)으로 채움

3.2.5 결측치 시각화 및 분석 (missingno 라이브러리 활용)

결측치를 효과적으로 분석하기 위해 missingno 라이브러리를 활용할 수 있다.
이 라이브러리는 데이터셋 내 결측치를 시각적으로 표현하여 어떤 변수에 결측치가 많은지 쉽게 파악할 수 있도록 도와준다.

missingno 설치

pip install missingno

결측치 시각화 (missingno.matrix())

import missingno as msno
import matplotlib.pyplot as plt

# 결측치 매트릭스 시각화
msno.matrix(df)
plt.show()

결과 해석

  • 흰색 부분 → 결측치가 있는 영역
  • 검은색 부분 → 데이터가 존재하는 영역

결측치 막대그래프 (missingno.bar())

msno.bar(df)
plt.show()

결과 해석

  • 각 열의 결측치 개수를 막대그래프로 표현
  • 특정 열에 결측치가 집중되어 있는지 쉽게 확인 가능

변수 간 결측치 상관관계 (missingno.heatmap())

msno.heatmap(df)
plt.show()

결과 해석

  • 상관관계가 높은 경우 → 특정 변수의 결측치는 다른 변수의 결측치와 연관이 있을 가능성이 높음
  • 상관관계가 낮은 경우 → 특정 변수의 결측치는 독립적일 가능성이 높음

3.2.6 결측치 처리 방법 선택 가이드

결측치 상황 추천 처리 방법
결측치가 적은 경우 dropna()로 제거
수치형 데이터 결측치 fillna()를 사용하여 평균, 중앙값, 최빈값으로 대체
범주형 데이터 결측치 최빈값(mode()) 또는 "Unknown" 등의 값으로 대체
시간 순서가 있는 데이터 ffill() 또는 bfill()로 앞/뒤 값 채우기
고급 결측치 처리 SimpleImputer()를 활용한 머신러닝 기반 대체

결론

결측치는 데이터 분석 결과에 큰 영향을 미칠 수 있으므로, 적절한 방법으로 처리하는 것이 중요하다.

  • dropna() → 결측치가 적은 경우 삭제
  • fillna() → 평균, 중앙값, 최빈값, 앞/뒤 값으로 채우기
  • SimpleImputer() → 머신러닝을 활용하여 결측치를 대체
  • missingno → 결측치를 시각적으로 분석하여 패턴을 파악

이러한 방법을 적절히 활용하면 데이터 품질을 높이고, 신뢰할 수 있는 분석 결과를 도출할 수 있다.