보간과 고급 대치
시간 기반 값을 자연스럽게 채울 때 interpolate()를 사용하고, 평균과 중앙값 중 언제 어떤 대치 방법이 적절한지 이해합니다.
보간과 고급 대치은(는) CoddyKit의 무료 Pandas & NumPy Academy 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Pandas & NumPy Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Pandas & NumPy Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
interpolate()이 fillna()보다 나은 경우
앞방향 채우기와 뒤방향 채우기는 데이터의 추세를 고려하지 않고 가장 가까운 알려진 값을 전달합니다. 보간은 알려진 값 사이가 매끄럽게 이어진다고 가정하여 결측값을 추정합니다. 예를 들어 월요일의 기온이 20°C이고 금요일의 기온이 30°C라면 보간은 수요일의 기온을 25°C로 추정합니다. 이를 통해 센서 데이터, 가격 또는 인구 수와 같이 부드럽게 변하는 신호를 더 현실적으로 대치할 수 있습니다.
import pandas as pd
import numpy as np
df = pd.DataFrame({
'day': [1, 2, 3, 4, 5],
'temp': [20.0, np.nan, np.nan, np.nan, 30.0]
})
# Linear interpolation fills gaps smoothly
df['temp_interp'] = df['temp'].interpolate(method='linear')
print(df)
# day temp temp_interp
# 0 1 20.0 20.0
# 1 2 NaN 22.5
# 2 3 NaN 25.0
# 3 4 NaN 27.5
# 4 5 30.0 30.0interpolate() 메서드
판다스의 interpolate()는 여러 메서드를 지원합니다. 가장 흔한 메서드는 'linear'(알려진 값 사이를 같은 간격으로 채움), 'time'(DatetimeIndex가 설정된 경우 서로 다른 시간 간격을 반영함), 'polynomial'(다항 곡선을 적합하며 order 인수가 필요함), 'spline'(매끄러운 구간별 다항식을 사용함)입니다. 선형 방식이 가장 안전한 기본값이며, 고차 메서드는 짧은 공백 구간에 과적합할 수 있습니다.
import pandas as pd
import numpy as np
s = pd.Series([0, np.nan, np.nan, 8.0])
print('linear:', s.interpolate('linear').tolist())
# [0.0, 2.6666..., 5.3333..., 8.0]
print('polynomial(2):', s.interpolate('polynomial', order=2).tolist())
# [0.0, 2.222..., 5.111..., 8.0]DatetimeIndex를 사용한 time 보간
Series에 서로 다른 시간 간격을 가진 DatetimeIndex가 있을 때(예: 평일만 있고 주말은 누락된 경우), method='time'은 단순한 위치가 아니라 실제 경과 시간에 비례하여 보간합니다. 각 행을 달력상의 간격과 관계없이 동일한 간격으로 취급하는 선형 보간보다 정확합니다.
import pandas as pd
import numpy as np
# Unequal gaps: Jan 1, Jan 3, Jan 10
idx = pd.to_datetime(['2024-01-01', '2024-01-03', '2024-01-10'])
s = pd.Series([100.0, np.nan, 170.0], index=idx)
# linear treats gaps as equal (position-based)
print(s.interpolate('linear').tolist()) # [100.0, 135.0, 170.0]
# time accounts for actual day count
# Jan 1 to Jan 3 = 2 days, Jan 1 to Jan 10 = 9 days
# fraction: 2/9 of the way from 100 to 170
print(s.interpolate('time').tolist()) # [100.0, 115.55..., 170.0]보간 범위 제한하기
ffill()과 마찬가지로 interpolate()는 연속된 NaN 위치를 몇 개까지 채울지 제한하는 limit 매개변수를 지원합니다. 제한을 초과한 나머지 NaN은 결측 상태로 남습니다. 이를 통해 실제 값이 무엇이든 될 수 있는 매우 긴 공백 구간을 가로질러 보간하는 것을 방지할 수 있습니다. 긴 공백 구간은 수동 검토 대상으로 표시해야 합니다.
import pandas as pd
import numpy as np
s = pd.Series([1.0, np.nan, np.nan, np.nan, np.nan, 10.0])
# Only fill the first 2 NaN positions
filled = s.interpolate('linear', limit=2)
print(filled.tolist())
# [1.0, 2.8, 4.6, NaN, NaN, 10.0]평균과 중앙값 대치 중 선택하기
평균과 중앙값 대치는 간단하지만 중요한 장단점이 있습니다. mean은 이상치에 민감합니다. 매우 큰 값이 몇 개만 있어도 평균이 높아지므로 소득이나 주택 가격처럼 오른쪽으로 치우친 분포를 채우는 데 적합하지 않습니다. median은 이상치에 강하므로 치우친 열에 더 적합합니다. 데이터가 대략 대칭이고 극단적인 이상치가 없는 경우에만 평균을 사용하세요.
import pandas as pd
import numpy as np
# Skewed income data with an outlier
income = pd.Series([30000, 35000, 32000, 1_000_000, np.nan])
print('Mean: ', income.mean()) # ~274000 — pulled by outlier
print('Median:', income.median()) # ~33500 — robust choice
# Prefer median for skewed data
filled = income.fillna(income.median())
print(filled.tolist())
# [30000, 35000, 32000, 1000000, 33500.0]KNN 대치 개념
K-Nearest Neighbour (KNN) 대치는 누락된 값을 결측이 아닌 특성 전반의 거리를 기준으로 가장 유사한 k개 행의 평균(또는 가중 평균)으로 바꿉니다. 이는 다변량 전략이므로 다른 열의 정보를 활용하여 채울 값을 정합니다. 특성 사이에 상관관계가 있을 때 단일 열의 평균으로 대치하는 것보다 정확합니다.
사이킷런의 KNNImputer는 NumPy 배열 및 판다스 DataFrame과 직접 통합됩니다.
import pandas as pd
import numpy as np
from sklearn.impute import KNNImputer
df = pd.DataFrame({
'age': [25, 35, np.nan, 45],
'income': [50000, 70000, 60000, np.nan]
})
imputer = KNNImputer(n_neighbors=2)
df_imputed = pd.DataFrame(
imputer.fit_transform(df),
columns=df.columns
)
print(df_imputed.round(1))
# age income
# 0 25.0 50000.0
# 1 35.0 70000.0
# 2 30.0 60000.0 <- filled from neighbours
# 3 45.0 65000.0 <- filled from neighboursIterativeImputer를 사용한 다중 대치
다중 대치는 통계 연구에서 결측 데이터를 처리하는 표준적인 방법입니다. 사이킷런의 IterativeImputer는 MICE(연쇄 방정식에 의한 다중 대치) 접근 방식을 구현합니다. 즉, 결측값이 있는 각 열을 다른 열의 함수로 모델링하고, 값이 수렴할 때까지 대치를 반복합니다. 이를 통해 단일 열 전략보다 특성 간 관계를 더 잘 반영할 수 있습니다.
import pandas as pd
import numpy as np
from sklearn.experimental import enable_iterative_imputer # noqa
from sklearn.impute import IterativeImputer
df = pd.DataFrame({
'x1': [1, 2, np.nan, 4, 5],
'x2': [2, np.nan, 6, 8, 10],
'y': [3, 5, 7, np.nan, 11]
})
imp = IterativeImputer(max_iter=10, random_state=0)
df_filled = pd.DataFrame(imp.fit_transform(df), columns=df.columns)
print(df_filled.round(2))결측 데이터를 위한 지시자 열
값이 대치되었다는 사실을 숨기기보다는, 대치하기 전에 결측값이 있었던 행을 표시하는 이진 지시자 열을 추가하는 것이 좋습니다. 이를 통해 이후 모델이 결측 패턴 자체를 학습할 수 있습니다. 경우에 따라 값이 누락되었는지가 값 자체만큼 예측에 유용할 수 있습니다.
import pandas as pd
import numpy as np
df = pd.DataFrame({'salary': [50000, np.nan, 70000, np.nan, 90000]})
# Add indicator before filling
df['salary_was_missing'] = df['salary'].isna().astype(int)
# Then fill
df['salary'] = df['salary'].fillna(df['salary'].median())
print(df)
# salary salary_was_missing
# 0 50000.0 0
# 1 70000.0 1
# 2 70000.0 0
# 3 70000.0 1
# 4 90000.0 0대치와 데이터 누수
기계 학습 파이프라인의 중요한 원칙은 대치 통계량(평균, 중앙값, 최빈값)을 학습 세트에서만 계산한 다음 동일한 값을 테스트 세트에 적용하는 것입니다. 분할 전에 전체 데이터 세트에서 통계량을 계산하면 데이터 누수가 발생합니다. 모델이 학습 중 테스트 데이터를 간접적으로 보게 되어 성능 추정치가 부풀려집니다. 항상 학습 데이터에 대치기를 적합하고 학습 데이터와 테스트 데이터 모두에 변환을 적용하세요.
import pandas as pd
import numpy as np
from sklearn.impute import SimpleImputer
from sklearn.model_selection import train_test_split
df = pd.DataFrame({'feature': [1, 2, np.nan, 4, np.nan, 6, 7, 8]})
train, test = train_test_split(df, test_size=0.25, random_state=0)
# Fit ONLY on training data
imp = SimpleImputer(strategy='mean')
train['feature'] = imp.fit_transform(train[['feature']])
# Transform test using training statistics
test['feature'] = imp.transform(test[['feature']])
print('Train mean used:', imp.statistics_[0])대치 전략을 시각적으로 비교하기
여러 대치 방법을 적용한 후 원래 열과 대치된 열의 분포를 나란히 그려 그 영향을 비교하세요. 좋은 대치는 원래 분포의 형태(평균, 분산, 왜도)를 가능한 한 가깝게 보존해야 합니다. 평균 대치는 분포를 좁히는 반면, KNN과 MICE는 분포를 더 잘 보존하는 경향이 있습니다.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(0)
original = np.random.exponential(scale=5, size=200)
with_nan = original.copy()
with_nan[np.random.choice(200, 40, replace=False)] = np.nan
s = pd.Series(with_nan)
fig, axes = plt.subplots(1, 2, figsize=(10, 4))
s.dropna().hist(ax=axes[0], bins=20, title='Original (no NaN)')
s.fillna(s.mean()).hist(ax=axes[1], bins=20, title='Mean-imputed')
plt.tight_layout()
plt.savefig('imputation_comparison.png')
print('Saved comparison chart')적절한 대치 전략 선택하기
모든 경우에 가장 좋은 대치 전략은 없으며, 적절한 선택은 상황에 따라 달라집니다. 결측이 적은 단순한 일변량 사례에는 mean/median을 사용하세요. 안정적인 추세를 보이는 시계열에는 ffill/bfill을 사용하세요. 특성 간 상관관계가 있고 그 관계를 활용하려면 KNN 또는 IterativeImputer를 사용하세요. 결측값에 명확한 업무적 의미가 있을 때는 도메인 상수(예: 없음에는 0, 알 수 없음에는 -1)를 사용하세요. 선택한 방법은 항상 문서화해야 합니다.
# Decision guide (no runnable code)
#
# Missing < 5% AND data is MCAR? -> Mean/median fill is fine
# Time series with stable trend? -> ffill() with limit
# Features are correlated? -> KNNImputer or IterativeImputer
# Categorical column? -> Mode fill or 'Unknown' sentinel
# Going into ML model? -> Add indicator column + fill
# Research / publication quality? -> Multiple imputation (MICE)
print('Strategy selected based on context')빠른 확인
보간과 고급 대치에 대한 이해도를 확인해 보세요.
레슨 요약
이 레슨에서는 다음을 배웠습니다. interpolate()는 알려진 값 사이에 매끄러운 추세가 있다고 가정하여 결측값을 추정하고, method='time'은 DatetimeIndex의 서로 다른 간격을 처리하며, KNNImputer와 IterativeImputer 같은 고급 전략은 다른 열의 정보를 활용하여 값을 채웁니다. 데이터 누수를 방지하려면 대치 전에 항상 지시자 열을 추가하고, 통계량은 학습 세트에서만 적합하세요. 다음으로 DataFrame 열의 데이터 형식을 확인하고 변환하는 방법을 알아봅니다.
AI 튜터와 함께 Python을(를) 배우세요 — 무료
브라우저에서 실제 코드를 작성하고 실행하며, 24/7 AI 튜터로부터 즉각적인 도움을 받고, 웹이나 앱에서 중단한 부분부터 계속 학습하세요.
- 코스
- 30
- 레슨
- 120
자주 묻는 질문
“보간과 고급 대치” 강의는 무료인가요?
네 — “보간과 고급 대치” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Pandas & NumPy Academy 강의 전체를 잠금 해제할 수 있습니다. Pandas & NumPy Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“보간과 고급 대치”에서 뭘 배우나요?
시간 기반 값을 자연스럽게 채울 때 interpolate()를 사용하고, 평균과 중앙값 중 언제 어떤 대치 방법이 적절한지 이해합니다. 브라우저에서 직접 실행하는 실습 코드로 Pandas & NumPy Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Pandas & NumPy Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Pandas & NumPy Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.
“보간과 고급 대치” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Pandas & NumPy Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Pandas & NumPy Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.