"결측치를 어떻게 채울까"보다 먼저 "왜 비어 있는가"를 물어야 합니다. 결측 메커니즘에 대한 가정이 틀리면, 아무리 정교한 대치도 편향을 만듭니다.
pandas의 isna·dropna·fillna, sklearn.impute의 SimpleImputer·KNNImputer·IterativeImputer핵심 질문: 결측이 발생할 확률이 무엇에 의존하는가.
결측 확률이 관측값·미관측값 어느 것과도 무관합니다. 예: 설문지 일부가 인쇄 오류로 누락. 이때 결측 행은 전체의 무작위 부분집합이므로, 완전 케이스 분석(행 삭제)이 편향을 만들지 않습니다(표본 크기만 줄어듦). 실제로 순수 MCAR는 드뭅니다.
결측 확률이 관측된 다른 변수에는 의존하지만, 결측된 값 자체에는 의존하지 않습니다. 예: 고소득 응답자일수록 나이를 적게 기입 → 소득(관측됨)으로 결측 여부를 설명 가능. MAR 하에서는 관측 변수를 조건으로 하는 대치(회귀·KNN·다중 대치)가 유효합니다.
결측 확률이 결측된 값 그 자체에 의존합니다. 예: 소득이 매우 높은 사람이 소득 항목을 비움. 관측 변수만으로는 보정할 수 없으며, 결측 원인을 모델링하거나 추가 데이터를 확보하지 않으면 어떤 대치도 편향됩니다.
주의(사실): 데이터만으로 MAR과 MNAR을 확정적으로 구분하는 검정은 존재하지 않습니다. 도메인 지식과 결측 패턴 분석(다른 변수와의 관계, 결측 행의 특성 비교)으로 "어느 가정이 그럴듯한가"를 판단합니다. Little's MCAR 검정은 MCAR 여부만 반증적으로 검토합니다.
df["age"] = df["age"].fillna(df["age"].median())범주형은 "Unknown" 같은 별도 범주로, 수치형은 -1이나 0 같은 센티널로 채우는 방법이 있습니다. 이때 결측 여부를 나타내는 이진 표시자 열을 추가하면(사실), 결측 자체가 정보를 가진 경우(MNAR 근처)에 모델이 그것을 학습할 수 있습니다.
df["income_missing"] = df["income"].isna().astype("int8")한 번이 아니라 여러 벌(예: m=5~20)의 완성 데이터셋을 만들고, 각각 분석한 뒤 결과를 규칙(Rubin's rules)으로 합칩니다. 대치의 불확실성이 최종 추정치의 분산에 반영된다는 것이 핵심 장점입니다. IterativeImputer(MICE 계열)가 이 아이디어의 구현입니다.
from sklearn.impute import KNNImputer
imputer = KNNImputer(n_neighbors=5)
X_train_imp = imputer.fit_transform(X_train) # train에서 fit
X_test_imp = imputer.transform(X_test) # test에는 transform만실무 강조점(권고): 대치기의 통계(평균, 이웃, 회귀계수)는 반드시 train에서만 fit하고 test에는 transform만 적용합니다. 전체 데이터로 fit하면 test 정보가 train 파이프라인으로 새어 성능이 낙관적으로 왜곡됩니다(데이터 전처리 이론 06. 불균형·데이터 누수·재현성).
행 삭제(listwise deletion)는 여러 열에 결측이 흩어져 있으면 표본이 급격히 줄고, MCAR가 아니면 표본이 편향됩니다(사실).
댓글
GitHub 계정으로 의견이나 질문을 남길 수 있습니다.