본문으로 건너뛰기

008 setup() 전처리 옵션 - 결측치 처리

키워드: 결측치, imputation

개요

실제 데이터에는 결측치(missing values)가 흔히 존재합니다. 결측치를 어떻게 처리하느냐에 따라 모델 성능이 크게 달라질 수 있습니다. PyCaret은 다양한 결측치 처리 옵션을 제공하며, 이 글에서는 각 옵션의 특징과 사용법을 알아보겠습니다.

실습 환경

  • Python 버전: 3.11 권장
    • Python 3.11은 2027년 말까지 지원되며, PyCaret 호환 최신 버전입니다.
  • 필요 패키지: pycaret[full]>=3.0, pandas, matplotlib
pip install pycaret[full]>=3.0 pandas matplotlib

Google Colab 사용 불가 Google Colab은 2025년 8월부터 Python 3.12만 지원하여 PyCaret(3.8~3.11) 실습이 불가능합니다. 로컬 환경이나 Docker를 사용해 주세요.

결측치 확인하기

데이터 로드 및 확인

from pycaret.datasets import get_data
import pandas as pd

# 008 타이타닉 데이터 (결측치 있음)
data = get_data('titanic')

# 008 결측치 확인
print("결측치 개수:")
print(data.isnull().sum())

print("\n결측치 비율 (%):")
print((data.isnull().sum() / len(data) * 100).round(2))

출력:

결측치 개수:
PassengerId 0
Survived 0
Pclass 0
Name 0
Sex 0
Age 177
SibSp 0
Parch 0
Ticket 0
Fare 0
Cabin 687
Embarked 2

결측치 비율 (%):
Age 19.87
Cabin 77.10
Embarked 0.22

시각화

import matplotlib.pyplot as plt
import seaborn as sns

# 008 결측치 히트맵
plt.figure(figsize=(10, 6))
sns.heatmap(data.isnull(), cbar=True, yticklabels=False, cmap='viridis')
plt.title('결측치 분포')
plt.tight_layout()
plt.savefig('missing_values.png')

PyCaret 기본 결측치 처리

setup() 함수는 기본적으로 결측치를 자동 처리합니다:

from pycaret.classification import *

# 008 기본 설정 (자동 결측치 처리)
clf = setup(
data=data,
target='Survived',
session_id=42
)

기본 동작:

  • 수치형 변수: 평균(mean)으로 대체
  • 범주형 변수: 최빈값(mode)으로 대체

수치형 결측치 처리 옵션

numeric_imputation 파라미터

clf = setup(
data=data,
target='Survived',
numeric_imputation='mean', # 기본값
session_id=42
)

사용 가능한 옵션

옵션설명적합한 경우
'mean'평균값 대체정규분포, 이상치 적음
'median'중앙값 대체이상치 있음, 비대칭 분포
'mode'최빈값 대체이산적 수치형
'drop'결측치 행 삭제결측치 적음
'knn'KNN 기반 대체변수 간 상관관계 있음
숫자특정 값으로 대체도메인 지식 활용

예제: 다양한 옵션 비교

from pycaret.classification import *
from pycaret.datasets import get_data

data = get_data('titanic')

# 008 평균 대체
clf_mean = setup(
data=data,
target='Survived',
ignore_features=['PassengerId', 'Name', 'Ticket', 'Cabin'],
numeric_imputation='mean',
session_id=42,
verbose=False
)
print(f"평균 대체 후 Age: {clf_mean.X_train['Age'].mean():.2f}")

# 008 중앙값 대체
clf_median = setup(
data=data,
target='Survived',
ignore_features=['PassengerId', 'Name', 'Ticket', 'Cabin'],
numeric_imputation='median',
session_id=42,
verbose=False
)
print(f"중앙값 대체 후 Age: {clf_median.X_train['Age'].median():.2f}")

# 008 특정 값 대체
clf_zero = setup(
data=data,
target='Survived',
ignore_features=['PassengerId', 'Name', 'Ticket', 'Cabin'],
numeric_imputation=0,
session_id=42,
verbose=False
)

KNN 기반 결측치 대체

clf = setup(
data=data,
target='Survived',
ignore_features=['PassengerId', 'Name', 'Ticket', 'Cabin'],
numeric_imputation='knn', # K-최근접 이웃 기반
session_id=42
)

KNN 대체의 장점:

  • 다른 특성과의 관계를 고려
  • 단순 통계값보다 정확할 수 있음

단점:

  • 계산 비용이 높음
  • 대용량 데이터에서 느림

범주형 결측치 처리 옵션

categorical_imputation 파라미터

clf = setup(
data=data,
target='Survived',
categorical_imputation='mode', # 기본값
session_id=42
)

사용 가능한 옵션

옵션설명적합한 경우
'mode'최빈값 대체일반적인 경우
'drop'결측치 행 삭제결측치 적음
문자열특정 값으로 대체별도 카테고리로 처리

예제: 범주형 결측치 처리

# 008 최빈값으로 대체
clf = setup(
data=data,
target='Survived',
ignore_features=['PassengerId', 'Name', 'Ticket', 'Cabin'],
categorical_imputation='mode',
session_id=42
)

# 008 'Unknown'으로 대체
clf = setup(
data=data,
target='Survived',
ignore_features=['PassengerId', 'Name', 'Ticket', 'Cabin'],
categorical_imputation='Unknown', # 새로운 카테고리
session_id=42
)

결측치 비율이 높은 컬럼 처리

자동 제거: remove_multicollinearity

# 008 결측치 비율이 높은 컬럼은 ignore_features로 제외
clf = setup(
data=data,
target='Survived',
ignore_features=['PassengerId', 'Name', 'Ticket', 'Cabin'], # Cabin: 77% 결측
session_id=42
)

결측치 비율 기준 제거

# 008 결측치 50% 이상인 컬럼 자동 제거
def remove_high_missing(df, threshold=0.5):
"""결측치 비율이 높은 컬럼 제거"""
missing_ratio = df.isnull().sum() / len(df)
cols_to_keep = missing_ratio[missing_ratio <= threshold].index.tolist()
return df[cols_to_keep]

# 008 전처리 후 setup
clean_data = remove_high_missing(data, threshold=0.5)
clf = setup(clean_data, target='Survived', session_id=42)

실전 예제: 결측치 전략 비교

from pycaret.classification import *
from pycaret.datasets import get_data
import pandas as pd

data = get_data('titanic')

# 008 전략 1: 평균/최빈값 대체
clf1 = setup(
data=data,
target='Survived',
ignore_features=['PassengerId', 'Name', 'Ticket', 'Cabin'],
numeric_imputation='mean',
categorical_imputation='mode',
session_id=42,
verbose=False
)
model1 = create_model('rf', verbose=False)
results1 = pull()
print(f"전략 1 (평균/최빈값): Accuracy = {results1['Accuracy'].mean():.4f}")

# 008 전략 2: 중앙값/Unknown 대체
clf2 = setup(
data=data,
target='Survived',
ignore_features=['PassengerId', 'Name', 'Ticket', 'Cabin'],
numeric_imputation='median',
categorical_imputation='Unknown',
session_id=42,
verbose=False
)
model2 = create_model('rf', verbose=False)
results2 = pull()
print(f"전략 2 (중앙값/Unknown): Accuracy = {results2['Accuracy'].mean():.4f}")

# 008 전략 3: KNN 대체
clf3 = setup(
data=data,
target='Survived',
ignore_features=['PassengerId', 'Name', 'Ticket', 'Cabin'],
numeric_imputation='knn',
categorical_imputation='mode',
session_id=42,
verbose=False
)
model3 = create_model('rf', verbose=False)
results3 = pull()
print(f"전략 3 (KNN): Accuracy = {results3['Accuracy'].mean():.4f}")

출력 예시:

전략 1 (평균/최빈값): Accuracy = 0.8127
전략 2 (중앙값/Unknown): Accuracy = 0.8095
전략 3 (KNN): Accuracy = 0.8159

결측치 처리 가이드라인

결측치 비율별 권장 전략

결측치 비율권장 전략
0~5%평균/중앙값/최빈값 대체
5~20%KNN 대체 또는 도메인 지식 활용
20~50%별도 카테고리('Unknown')로 처리 검토
50% 이상컬럼 제거 고려

데이터 특성별 권장 전략

데이터 특성권장 전략
정규분포 수치형mean
비대칭/이상치 있는 수치형median
변수 간 상관관계 높음knn
범주형 (카테고리 적음)mode
범주형 (결측이 의미 있음)'Missing' 문자열

정리

  • PyCaret은 기본적으로 수치형은 mean, 범주형은 mode로 결측치를 처리합니다.
  • numeric_imputationcategorical_imputation 파라미터로 전략을 변경할 수 있습니다.
  • KNN 대체는 더 정확할 수 있지만 계산 비용이 높습니다.
  • 결측치 비율이 50% 이상이면 해당 컬럼 제거를 고려하세요.
  • 여러 전략을 비교하여 최적의 방법을 찾는 것이 좋습니다.

다음 글 예고

다음 글에서는 setup() 전처리 옵션 - 인코딩에 대해 알아보겠습니다. 범주형 변수를 수치형으로 변환하는 다양한 인코딩 방법을 다룹니다.


PyCaret 머신러닝 마스터 시리즈 #008