결측값의 랜덤 샘플 보간 — 분포와 분산을 유지하는 단변량 보간
요약
결측치를 평균이나 중앙값으로 채우면 데이터의 분산이 왜곡되는 문제가 있습니다. 이 글은 결측치를 같은 열의 관측치에서 무작위로 샘플링하여 채우는 '랜덤 샘플 보간(Random Sample Imputation)' 기법을 소개합니다. 이는 원래 데이터 분포와 변동성을 효과적으로 유지할 수 있는 장점이 있습니다.
핵심 포인트
- 평균/중앙값 보간은 분산을 축소하고 분포를 왜곡시킵니다.
- 랜덤 샘플 보간은 원본 데이터의 변동성 및 분포 형태를 잘 유지합니다.
- 구현 시 인덱스 재배열과 학습 데이터 풀(Pool) 사용에 주의해야 합니다.
- 수치형뿐 아니라 범주형 변수에도 적용 가능하여 활용도가 높습니다.

평균값이나 중앙값으로 결측치를 채우면 모든 결측치가 하나의 대표값으로 대체됩니다. 그 값 주변에 데이터가 인위적으로 집중하기 때문에, 분산이 축소되고 분포가 부자연스럽게 왜곡됩니다.
이 문제를 해결하는 것이 바로 “랜덤 샘플 보간(Random Sample Imputation)”입니다. 해당 열의 실제 값에서 무작위로 선택하여 채워 넣는 간단한 발상임에도 불구하고, “원래 데이터 분포를 그대로 유지할 수 있다”는 큰 장점이 있습니다. 본 글에서는 그 핵심을 간결하게 정리합니다.
랜덤 샘플 보간이란
결측치를 같은 열의 관측치(결측되지 않은 값) 중에서 무작위로 선택하여 채우는 방법입니다. 평균값 보간은 한 점에 집중되어 분산이 줄어들지만, 랜덤 샘플 보간은 실제로 존재하는 값들의 변동성을 이용해 채우기 때문에 원래 분포의 형태가 거의 유지됩니다.
다음과 같은 상황에 적합합니다.
- 결측이 MCAR(완전히 무작위한 결측)이라고 가정될 때
- 분포의 형태를 유지하면서 상관관계 분석이나 통계 모델링을 하고 싶을 때
- 수치형과 범주형 모두에 동일한 방법을 사용하고 싶을 때
구현은 3단계
“결측치를 세기 → 관측값에서 추출하기 → 인덱스를 맞추어 대입하기”의 3단계입니다.
import pandas as pd
import seaborn as sns
from sklearn.model_selection import train_test_split
...
결측치 수(보간 전): 140 37
결측치 수(보간 후): 0 0
유념해야 할 포인트가 3가지 있습니다.
- 인덱스 재배열: pandas는 인덱스로 위치를 맞춰 대입하기 때문에, 추출한 값들의 인덱스를 결측 위치에 맞추지 않으면 올바르게 대입되지 않습니다. -
- 풀(Pool)은 학습 데이터에서: 테스트 데이터의 결측치도 학습 데이터의 관측값에서 추출합니다. 테스트 데이터의 정보가 보간 과정에 섞이는 것을 방지하기 위함입니다. -
: 무작위로 선택하므로, 지정하지 않으면 실행할 때마다 결과가 달라집니다. 원문 예시에서는random_state를 고정하는 것이 좋습니다.
# random_state 설정의 중요성 예시
# random_state 미지정 시:
# 1회차: [4, 16, 50], 2회차: [27, 18, 35]
# random_state=42 지정 시:
# 몇 번을 호출해도 [2, 65, 33]으로 동일합니다
분산이 거의 유지됨
중앙값 보간과 비교하여 표준편차가 얼마나 변하는지 확인해 보겠습니다.
std_orig = df['age'].std()
age_median = df['age'].fillna(df['age'].median())
age_random = random_sample_impute(df['age'], df['age'].dropna())
...
원 데이터: 표준편차 14.5265
중앙값 보간: 표준편차 13.0197 (감소율 10.37%)
랜덤 샘플 보간: 표준편차 14.2953 (감소율 1.59%)
중앙값 보간에서는 표준편차가 약 10% 감소한 반면, 랜덤 샘플 보간에서는 겨우 1.59%의 감소에 그쳤습니다. 히스토그램으로 비교해도, 원 데이터와 거의 같은 형태를 유지하는 것은 랜덤 샘플 보간뿐이었습니다.
범주형 변수에도 그대로 사용 가능
평균값이나 중앙값을 사용할 수 없는 범주형 변수에도 동일한 함수를 적용할 수 있습니다.
emb = random_sample_impute(df['embarked'], df['embarked'].dropna())
print('보간 전:', df['embarked'].value_counts(normalize=True).round(4).to_dict())
print('보간 후:', emb.value_counts(normalize=True).round(4).to_dict())
보간 전: {'S': 0.7244, 'C': 0.189, 'Q': 0.0866}
보간 후: {'S': 0.725, 'C': 0.1886, 'Q': 0.0864}
최빈값 보간과 달리, 가장 많은 범주만 늘리는 일이 없기 때문에 범주의 구성비를 유지하기 쉽다는 장점이 있습니다.
단변량 보간 정리
| 기법 | 분포 보존 | 분산 보존 | 재현성 | 주요 용도 |
|---|---|---|---|---|
| 상수 보간 | × 강하게 왜곡됨 | × | ◎ 항상 동일 | 범주의 “미응답” 명시 |
| ... |
- 랜덤 샘플 보간(Random Sample Imputation)은 관측값 중에서 무작위로 선택하여 결측값을 채우는 기법입니다. 원래 분포의 형태와 분산을 거의 유지할 수 있다는 것이 가장 큰 장점입니다.
- '결측값 개수 세기 → 관측값에서 추출하기 → 인덱스를 맞추어 대입하기'의 3단계 과정이 필요합니다. 인덱스 교체를 잊으면 올바르게 대입되지 않습니다.
- 보간 값 풀(pool)은 학습 데이터에서 가져오며,
random_state를 고정하여 재현성을 확보합니다. 범주형 변수에도 그대로 사용할 수 있습니다. 다만, 변수 간의 관계는 반영되지 않으므로, 이 부분이 필요하다면 다변량 보간으로 가야 합니다.
더 자세히 알고 싶은 분들을 위해
이 글은 주식회사 세일즈애널리티크스(Sales Analytics) 블로그 게시물 '결측값 처리 시리즈 제7회: 단변량 보간③ — 랜덤 샘플 보간으로 분포 유지하기'의 핵심 내용을 요약한 것입니다.
원문 기사에서는 이번에 생략된 내용까지 포함하여 초보자도 이해할 수 있도록 단계별로 설명하고 있습니다.
- 학습 데이터 및 테스트 데이터 각각에서의 보간 과정을 한 줄씩 추적하는 해설
- 원본 데이터, 중앙값 보간, 랜덤 샘플 보간의 분포를 히스토그램으로 비교하는 시각화 코드
- 사용할 때 주의할 점(공분산에 미치는 영향, 메모리 사용 등)
결측값의 '탐지・분석・처리' 순서로 배울 수 있는 시리즈의 제7회입니다. 다음 시간에는 시계열 데이터의 결측값 보간(LOCF / NOCB / 선형 보간)을 다룰 예정이니, 원문 기사도 함께 참고해 주시기 바랍니다.
Discussion

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn ML의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기