쟈는 필연적 존재
여러분은 바닷가에 하면 무엇이 떠오르십니까. 힘껏 밀려와서 부서지는 파도나 갈매기도 있을 테고, 알려진 해변이면 맛집간판이나 백사장도 있겠군요. 전 포구 근처에서 자라서 그런가 특이하게 갯강구가 먼저 떠오릅니다. 방파제에서 뭔가 부리나케 사라지는 기척이 느껴지면 '내가 바닷가에 왔구나' 느낌이 들거든요. 후다다닥.
데이터 분석에서 결측값은 갯강구 같다는 느낌이 듭니다. 막상 찾으려고 보면 없는데 한 발만 떨어져서 보면 분명히 보이거든요. 결측값 존재 자체는 세금이나 죽음처럼 자연스럽게 받아들이는 게 좋습니다. 강의나 샘플과 다르게 필드에서 받아 드는 데이터는 어딘가 비어있기 마련이니까요.
열은 받지만 어떻게든 처리해야 합니다.
정말 잘 처리해야 합니다.
복잡하고 까다로운데 귀찮아
결측값 처리순서는 대강 이렇습니다. 우선 결측의 원인을 파악해 둡니다. 막 하나하나 따져보는 게 아니라 '아 이래서 생겼구나' 정도입니다. 반복되면 곤란하니 확인 정도는 해두자는 취지입니다.
예를 들어, 한 회사의 서비스 만족도 조사에서 일부 응답자들이 소득 관련 질문에 답하지 않았다고 가정해 봅시다. 이게 단순히 실수로 누락된 것일 수도 있고, 질문이 부담스러워서 의도적으로 응답을 거부한 것일 수도 있습니다. 집계 시스템 오류로 인해 데이터가 손실되었을 가능성도 있습니다. 일회성 수집이 아니라면 어떻게든 조치를 해둬야겠죠.
이 과정에선 패턴도 같이 파악해 둡니다. 결측 값이 완전히 무작위로 발생했는지(MCAR), 관찰된 다른 변수와 관련이 있는지(MAR), 아니면 결측된 변수 자체의 특성과 관련이 있는지(MNAR) 구분하는 것은 중요합니다. 이게 구분이 안되면 처리방법을 정할 때 골머리 앓게 됩니다.
대충 파악이 되었으면 버릴 건지 메울 건지 결정해야 합니다. 통상 비율에 따라 결정하는데 5% 미만의 결측값은 별 문제가 되지 않겠지만, 그 이상이면 고민이 필요합니다. 처리 방법에 따라 분석 결과가 달라질 수 있거든요.
OpenAI의 O1처럼 정말 좋은 모델을 써서 고객 이탈 예측 모델을 개발한다고 가정해 봅시다. 결측값 비율이 7%라 제거한 데이터셋과 15%라 보간법으로 대체한 데이터셋의 예측 결과가 같을까요. 사실 어떤 데이터셋이 더 적합할지는 뚜껑을 열어봐야 압니다. 둘 다 만들어 넣던가 하나만 넣는다고 하면 머리를 써야겠죠.
복잡하고 까다로운데.... 귀찮습니다(먼산).
계급장 떼고 다 제거할까
결측값을 처리하는 가장 쉬운 방법은 데이터를 제거하는 겁니다. 간단하고 빠른 방법이지만, 주의해야 할 부분이 있습니다. 덮어놓고 자르다 보면 샘플이 줄어들거든요. 1000명의 고객 데이터에 10개의 구분 값이 있고, 각 구분 값마다 1%의 결측값이 있다고 가정해 봅시다. 모든 변수에 결측값이 없는 완전한 샘플만 쓴다면, 최대 10%의 데이터를 지워야 합니다. 분석의 신뢰성에도 문제가 생기겠지만 귀하게 모은 샘플을 날리는 과정에서 받는 스트레스도 적지 않습니다.
결측값의 패턴이 특정 변수와 연계되어 있다면 제거는 신중해야 합니다. 편향된 결과를 얻을 수 있거든요. 일례로 소득이 높은 응답자일수록 자신의 소득 노출을 꺼립니다. 반대의 경우에도 비슷한 경향을 보이죠. 응답자 중 일부가 소득 관련 질문에 답하지 않는 경향이 발견되었을 때 제거처리하면 어떻게 될까요. 경우에 따라선 집단의 소득 분포가 왜곡될 수 있습니다. 원했던 결과와 다른 결과를 받아 드는 셈이죠.
시계열 데이터나 패널 데이터도 조심해야 합니다. 결측값을 포함한 데이터 뭉치를 제거해 버리면 자칫 시계열 구조가 깨질 수 있거든요. 주식 시장 데이터에서 특정 날짜의 거래량이 누락되었다고 해서 해당 날짜의 모든 정보를 제거하면, 시장의 연속성을 파악하기 어려워집니다. 그나마 거래량은 복구가 가능하니 빨리 찾아 넣으면 되긴 하겠군요.
앞뒤로 잘 살펴보고 넣으세요
결측값을 채워 넣을(imputation) 때도 생각할 지점들이 있습니다. 채워넣을 데이터의 특성과 분포를 고려해야 합니다. 예를 들어, 센서 측정 데이터에서 결측값이 발생했다면, 인접한 시간대의 값들을 활용하여 보간법을 적용할 수 있습니다. 하지만 설문 데이터에서 발생한 결측값에 그러면 큰일 납니다. 본의 아니게 조작이 되는 거죠.
복잡성과 정확성 사이의 균형도 고려해야 합니다. 단순하게 평균값이나 중간값 대체부터 예측모델을 사용한 예측 기법(Predictive Techniques)까지 다양한 방법이 있습니다. 최신의 인공지능 추론 모델을 활용하여 결측값을 채워넣는 방법도 고려해 볼 수 있습니다. 하지만 복잡한 방법이 항상 좋은 것은 아닙니다. 되려 복잡성 때문에 더 꼬이는 사례도 많습니다. 데이터의 특성과 분석 목적에 맞는 방법을 선택해야 합니다.
대체된 값은 실제 값이 아니라는 점도 염두에 두어야 합니다. 일정 부분 불확실성을 고려한 분석이 필요합니다. 예를 들어, 다중대체법을 사용하면 여러 개의 대체된 데이터셋을 생성하고, 각 데이터셋에 대해 분석을 수행한 후 결과를 종합하여 불확실성을 반영할 수 있습니다. 손이 많이가긴 하죠.
앞서 파악한 결측값의 패턴도 고려해야 합니다. 우연히 발생한 무작위 결측값이라면 단순 대체도 가능할 수 있지만, 다른 변수에 영향을 받았거나 변수 자체에 문제가 있는 결측값인 경우 일이 복잡해집니다.
기억하자, 모든 데이터는 깨끗하지 않다
정리해 봅시다. 우리가 어떤 유통 회사의 매출 데이터를 의뢰받아 분석한다고 가정해 봅시다. 시스템 오류로 인해 특정 날짜의 판매 데이터가 누락된 상황, 아마 우리는 이런 순서로 결측값에 대처할 수 있을 겁니다.
1. 결측값의 패턴을 파악합니다. 특정 제품군이나 지역에 집중되어 있는지, 무작위로 발생했는지 확인합니다.
2. 결측값의 비율을 계산합니다. 전체 데이터의 10% 언저리나 그 이상이면 문제가 될 수 있습니다.
3. 대체 방법을 선택합니다. 시계열 특성을 고려하면 전주 동일 요일의 매출 데이터나 이동 평균을 쓰겠죠.
4. 인공지능을 활용하여 예측해 볼 수도 있습니다. 날짜, 요일, 계절성 등의 자료도 함께 활용하지 않을까요.
5. 결과의 불확실성을 써둡니다. 결측값이 있는 날짜의 분석 결과는 별도로 표시해 두면 좋겠죠.
(+) 혹시 모르니 마지막에 시스템 개선이나 백업 시스템까지 제안해 둡니다. 재구매가 들어올지 모르니까요.
결측값은 데이터 분석의 필연적 부분입니다. '인간이 그러하듯 데이터 역시 완벽하지 않다 누군가 돌봐줘야 한다'라는 마음가짐이 중요합니다. 따지고 보면 데이터도 불완전한 인간이 만든 거니까요. 불완전함을 적절히 다루는 능력도 분석가의 중요한 역량입니다.
우리 0과 null에 너무 스트레스 받지 말자구요.