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_imputation과categorical_imputation파라미터로 전략을 변경할 수 있습니다.- KNN 대체는 더 정확할 수 있지만 계산 비용이 높습니다.
- 결측치 비율이 50% 이상이면 해당 컬럼 제거를 고려하세요.
- 여러 전략을 비교하여 최적의 방법을 찾는 것이 좋습니다.
다음 글 예고
다음 글에서는 setup() 전처리 옵션 - 인코딩에 대해 알아보겠습니다. 범주형 변수를 수치형으로 변환하는 다양한 인코딩 방법을 다룹니다.
PyCaret 머신러닝 마스터 시리즈 #008