데이터 분석이나 머신러닝 프로젝트를 시작할 때, 분석가들이 가장 먼저 마주하는 난관이자 가장 골치 아픈 장벽은 바로 '데이터의 빈 구멍', 즉 결측치(Missing Values)입니다. 교과서에 나오는 예제 데이터는 깔끔하게 정리되어 있지만, 현실 세계의 데이터는 센서 오류, 응답 거부, 전산 누락, 데이터 병합 과정의 오류 등 수만 가지 이유로 인해 곳곳에 NaN, Null, None과 같은 구멍이 뚫려 있기 마련입니다.
많은 초보 분석가들이 단순히 결측치를 삭제해 버리거나, 고민 없이 0으로 채우는 실수를 범하곤 합니다. 하지만 데이터 결측치 처리 방법을 어떻게 가져가느냐에 따라 최종 모델의 성능은 천차만별로 달라질 수 있습니다. 데이터 분석계의 오랜 격언인 'Garbage In, Garbage Out(쓰레기가 들어가면 쓰레기가 나온다)'이라는 말처럼, 부실하게 처리된 데이터는 결코 신뢰할 수 있는 결과를 낳지 못합니다. 잘못된 결측치 처리는 데이터의 편향(Bias)을 초래하고, 모델의 일반화 성능을 떨어뜨리는 주범이 됩니다.
이 글에서는 데이터 분석의 필수 과정인 전처리 단계에서 결측치를 현명하게 다루는 다양한 전략들을 심도 있게 살펴봅니다. 가장 기초적인 삭제법부터 통계적 기법, 그리고 머신러닝 알고리즘을 활용한 고도화된 예측 대체법까지 총망라하여 정리해 드리겠습니다. 여러분의 데이터 상황에 딱 맞는 최적의 솔루션을 찾아보세요.
1. 결측치, 무조건 채우는 게 답일까? (결측 유형 파악하기)
본격적인 데이터 결측치 처리 방법을 적용하기 전에, 데이터가 '왜' 비어있는지를 파악하는 것이 선행되어야 합니다. 결측의 원인을 모른 채 기계적으로 값을 채우는 것은 위험합니다. 통계학에서는 결측의 메커니즘을 크게 세 가지로 분류합니다.
- 완전 무작위 결측 (MCAR: Missing Completely At Random): 결측치가 발생한 원인이 다른 변수나 데이터 자체와 전혀 상관없는 경우입니다. 예를 들어, 데이터 입력자가 실수로 깜빡하고 누락했거나 전산 시스템의 일시적 오류로 데이터가 손실된 경우가 이에 해당합니다. 이 경우 데이터를 삭제해도 분석 결과에 편향(Bias)이 발생할 확률이 낮아 처리가 비교적 자유롭습니다.
- 무작위 결측 (MAR: Missing At Random): 결측된 자료가 특정 변수와 관련이 있지만, 결측된 값 자체와는 관련이 없는 경우입니다. 예를 들어, 설문조사에서 '여성' 응답자가 '몸무게' 기입을 누락할 확률이 높다면, 이는 성별이라는 다른 변수와 관련이 있는 MAR입니다. 대부분의 결측치 처리 기법들은 이 MAR 가정을 기반으로 합니다.
- 비무작위 결측 (MNAR: Missing Not At Random): 결측된 값 자체가 결측의 원인이 되는 경우입니다. 가장 까다로운 케이스로, 예를 들어 소득이 매우 높은 사람이 세무 조사를 우려해 소득 공개를 꺼려 응답을 하지 않은 경우가 대표적입니다. 이 경우 결측치를 함부로 평균값 등으로 대체하면 데이터의 진실을 심각하게 왜곡할 수 있습니다.
2. 가장 단순하지만 강력한 방법: 삭제 (Deletion)
결측치를 처리하는 가장 직관적이고 쉬운 방법은 해당 데이터가 포함된 행(Row)이나 열(Column)을 제거하는 것입니다. 하지만 이는 '데이터 손실'이라는 치명적인 단점을 동반하므로 신중해야 합니다.
리스트와이즈 삭제 (Listwise Deletion)
결측치가 하나라도 포함된 행을 통째로 삭제하는 방법입니다. Python Pandas의 dropna() 함수가 대표적입니다.
* 장점: 처리가 매우 간편하며, 남아있는 데이터는 완전한 상태를 유지하므로 분석 모델에 바로 적용하기 쉽습니다. MCAR(완전 무작위 결측)일 경우 통계적 편향 없이 유효한 추정치를 얻을 수 있습니다.
* 단점: 데이터의 양이 충분하지 않거나 결측 비율이 높을 경우, 학습에 사용할 데이터가 너무 적어져 모델의 성능이 급격히 저하될 수 있습니다. 특히 특정 패턴을 가진 데이터가 삭제될 경우(예: 특정 연령대의 데이터만 삭제됨) 분석 결과에 심각한 편향이 생깁니다.
변수 삭제 (Dropping Features)
특정 열(Feature)에 결측치가 지나치게 많다면(예: 전체 데이터의 70~80% 이상이 결측), 해당 변수 자체를 분석에서 제외하는 것이 나을 수 있습니다. 정보량이 거의 없는 변수를 억지로 채워서 사용하는 것은 오히려 모델에 노이즈를 주입하는 꼴이 될 수 있기 때문입니다. 단, 그 변수가 타겟 예측에 매우 중요한 변수라면 삭제보다는 정교한 대체법을 고려해야 합니다.
3. 통계적 수치를 활용한 단순 대체법 (Simple Imputation)
데이터 양이 중요하거나 삭제하기 아까운 경우, 우리는 빈칸을 합리적인 숫자로 채워 넣어야 합니다. 가장 보편적으로 사용되는 것이 통계적 대표값을 활용하는 것입니다. Scikit-learn의 SimpleImputer 클래스를 통해 쉽게 구현할 수 있습니다.
평균값(Mean) 대체
데이터가 정규분포를 따르거나 연속적인 수치형 데이터일 때 주로 사용합니다. * 활용: 해당 열의 전체 평균값으로 빈칸을 채웁니다. * 주의점: 이상치(Outlier)에 매우 취약합니다. 예를 들어, 소득 데이터에 재벌 총수가 포함되어 평균을 비정상적으로 끌어올린 경우, 일반인의 결측치를 이 평균으로 채우면 소득 수준을 과대평가하게 됩니다. 또한, 모든 결측치를 같은 값(평균)으로 채우므로 데이터의 분산(Variance)이 인위적으로 축소되어, 변수 간의 상관관계를 약화시키는 부작용이 있습니다.
중앙값(Median) 대체
평균값 대체의 단점을 보완하기 위해 사용됩니다. * 활용: 데이터를 크기순으로 나열했을 때 정중앙에 위치한 값을 사용합니다. * 장점: 이상치의 영향을 거의 받지 않으므로, 소득이나 주택 가격처럼 한쪽으로 치우친(Skewed) 분포를 가진 데이터에 적합합니다. 이상치가 많은 데이터라면 평균보다는 중앙값이 훨씬 안전한 선택입니다.
최빈값(Mode) 대체
수치형 데이터가 아닌 범주형 데이터(Categorical Data)의 결측치를 처리할 때 사용합니다. * 활용: '성별', '거주 지역', '선호 색상' 등과 같이 가장 많이 등장한 카테고리로 빈칸을 채웁니다. 때로는 결측치 자체를 'Unknown'이나 '기타'라는 새로운 범주로 분류하는 것이 더 나은 정보를 제공하기도 합니다.
4. 고도화된 통계 기법: 보간법 (Interpolation)
시계열 데이터(Time-series Data)처럼 데이터 간에 순서나 흐름이 있는 경우에는 단순 평균보다 '보간법'이 훨씬 효과적인 데이터 결측치 처리 방법입니다. 시간의 흐름에 따른 추세를 반영하기 때문입니다.
- 선형 보간 (Linear Interpolation): 결측치 직전 값과 직후 값을 직선으로 연결하여 그 사이의 값을 추정합니다. 예를 들어, 1시 온도가 20도, 3시 온도가 24도라면 결측된 2시 온도를 22도로 추정하는 방식입니다. 변화가 완만한 데이터에 적합합니다.
- 스플라인 보간, 다항 보간: 데이터의 추세를 곡선 형태로 반영하여 더 정교하게 값을 채웁니다. 주식 가격이나 기온 변화, 심전도 데이터처럼 연속적인 흐름과 파동이 중요한 데이터에서 필수적으로 고려해야 합니다.
5. 머신러닝을 활용한 예측 대체 (Model-Based Imputation)
단순 통계값 대체는 변수 간의 상관관계를 고려하지 못한다는 한계가 있습니다. 이를 극복하기 위해 머신러닝 알고리즘을 사용하여 결측치를 '예측'해 채워 넣는 방법이 각광받고 있습니다. 이는 결측치 처리를 또 하나의 예측 문제로 바라보는 관점입니다.
KNN (K-Nearest Neighbors) Imputer
'유유상종'의 원리를 이용합니다. 결측치가 있는 데이터와 가장 유사한 특성을 가진 '이웃' 데이터 K개를 찾습니다. 그 이웃들의 평균값(수치형)이나 최빈값(범주형)을 빌려와 결측치를 채웁니다. * 장점: 변수 간의 관계를 고려하므로 단순 평균보다 훨씬 정확도가 높습니다. 데이터의 국소적인 패턴을 잘 반영합니다. * 주의점: 거리 기반 알고리즘이므로 데이터의 스케일(단위)에 민감합니다. 적용 전 반드시 정규화(Normalization)나 표준화(Standardization) 과정이 선행되어야 합니다. 또한 데이터 양이 많을 경우 모든 데이터 간의 거리를 계산해야 하므로 연산 속도가 느려질 수 있습니다.
MICE (Multivariate Imputation by Chained Equations)
다변량 대체를 위한 연쇄 방정식이라고 불리는 MICE는 현존하는 가장 강력하고 대중적인 통계적 결측치 처리 기법 중 하나입니다. 1. 먼저 모든 결측치를 임시값(예: 평균)으로 채웁니다. 2. 결측치가 있는 한 변수를 '타겟(Target)'으로 설정하고, 나머지 변수들을 '특성(Feature)'으로 사용하여 회귀 분석(또는 분류)을 수행합니다. 3. 회귀 모델이 예측한 값으로 해당 변수의 결측치를 업데이트합니다. 4. 모든 변수에 대해 이 과정을 반복하며(Round-robin 방식), 값이 수렴할 때까지 계속합니다.
이 방식은 변수들 사이의 복잡한 상관관계를 모두 반영하여 값을 채워 넣기 때문에, 데이터의 불확실성을 가장 잘 보존하면서도 신뢰도 높은 대체값을 생성해냅니다. Scikit-learn의 IterativeImputer가 이 방식을 차용하고 있습니다.
딥러닝 활용 (Autoencoders, GANs)
최근에는 딥러닝 모델인 오토인코더(Autoencoder)나 생성적 적대 신경망(GAN)을 활용한 결측치 처리 연구도 활발합니다. 예를 들어 GAIN (Generative Adversarial Imputation Nets)과 같은 모델은 생성자(Generator)가 결측치를 채우고, 판별자(Discriminator)가 이것이 진짜 데이터인지 채워진 데이터인지 구별하는 경쟁을 통해 매우 정교한 값을 생성해냅니다. 다만, 구현이 복잡하고 많은 연산 리소스가 필요하며, 해석이 어렵다는 단점이 있어 실무에서는 신중하게 도입해야 합니다.
6. 결측치 처리 시 주의사항 및 모범 사례
성공적인 데이터 결측치 처리 방법 적용을 위해 다음의 원칙들을 기억해야 합니다.
- 도메인 지식(Domain Knowledge) 활용: 기계적인 처리보다 데이터의 맥락을 이해하는 것이 중요합니다. 예를 들어 특정 설문 항목의 결측값이 '해당 없음'을 의미한다면, 이를 평균으로 채우는 것은 명백한 오류입니다. 이런 경우 0이나 -1, 또는 'Unknown'이라는 새로운 범주로 할당하는 것이 맞습니다.
- 새로운 변수 생성 (Flagging): 결측치를 값으로 대체하되, 원래 이 값이 결측치였다는 정보를 담은 새로운 변수(예:
is_missing_age)를 추가하는 전략입니다. 모델에게 "이 값은 추정된 값이야"라는 힌트를 줌으로써, 모델이 결측 패턴 자체를 학습하게 도울 수 있습니다. 정보 손실을 막는 아주 유용한 팁입니다. - 성능 비교 검증: 하나의 방법만 고집하지 마세요. 평균 대체, KNN, MICE 등 여러 가지 방법으로 전처리한 데이터셋을 각각 만들어 모델을 학습시켜 보고, 가장 높은 성능을 내는 방법을 선택하는 실험적인 접근이 필요합니다.
마치며: 완벽한 데이터는 없다, 완벽한 처리가 있을 뿐
데이터 분석에서 결측치를 다루는 것은 단순히 빈칸 채우기 게임이 아닙니다. 그것은 데이터가 가진 본래의 의미를 최대한 보존하고 왜곡을 최소화하려는 분석가의 치열한 고민 과정입니다. 결측치를 어떻게 다루느냐가 여러분의 데이터 분석 역량을 보여주는 척도가 될 수 있습니다.
단순한 평균값 대체부터 KNN, MICE와 같은 예측 모델 활용까지, 오늘 소개한 다양한 데이터 결측치 처리 방법들은 각자의 장단점이 명확합니다. 여러분의 데이터가 가진 특성(분포, 결측 유형, 상관관계)을 면밀히 살피고, 상황에 맞는 최적의 도구를 선택하시길 바랍니다. 꼼꼼하게 처리된 결측치는 여러분의 AI/ML 모델 성능을 비약적으로 향상시키는 든든한 초석이 될 것입니다.