데이터 결측치 처리
1. 파이썬의 결측치: 유형과 중요성
데이터 분석에서 결측치는 피할 수 없는 문제이며, 이를 효과적으로 다루는 것이 분석의 정확성을 좌우한다.
1.1. 결측치 유형
파이썬에서는 데이터의 종류에 따라 결측치를 다음과 같이 구분하여 표현한다.
| 유형 | 설명 | 사용 예시 |
|---|---|---|
| NaN (Not a Number) | 수치 데이터의 결측치를 나타낸다. 파이썬 Pandas에서는 R의 영향을 받아 na(잘못된 값)와 Null(아직 정해지지 않은 값)을 모두 NaN으로 통일하여 처리한다. | numpy.nan |
| None | 비수치 데이터(예: 문자열)의 결측치를 표현할 때 사용된다. | None |
| Inf (Infinity) | 무한대를 나타내는 값으로, 연산 과정에서 발생할 수 있다. | numpy.inf |
1.2. 결측치 처리의 필요성
결측 데이터를 처리하지 않고 방치할 경우 다음과 같은 심각한 문제가 발생할 수 있다.
- 예측 결과 왜곡: 결측치는 모델의 학습 과정을 방해하여 예측 결과에 큰 오차를 유발하고, 궁극적으로 잘못된 결론을 도출하게 만들 수 있다.
- 데이터 신뢰도 저하: 특히 외부에서 수집한 데이터는 결측치가 발생할 가능성이 높으므로,
철저한 확인 및 처리 과정이 데이터의 신뢰도를 보장하는 핵심 단계가 된다.
2. 결측치 식별 및 처리 기법
Pandas 라이브러리는 결측치를 효율적으로 다룰 수 있는 다양한 함수를 제공한다.
2.1. 결측치 확인 함수
데이터셋 내 결측치의 존재 여부와 개수를 파악하는 함수는 다음과 같다.
| 함수 | 설명 |
|---|---|
| 데이터셋.isna() | 각 데이터가 결측치(NaN)인지 여부를 Boolean 값으로 반환한다. .isnull()과 동일한 기능을 수행한다. |
| 데이터셋.isnull() | isna()와 동일하게 결측치 여부를 확인한다. |
| 데이터셋.isnull().sum() | 각 열(column)별 결측치의 총 개수를 계산하여 반환한다. |
| 데이터셋.isnull().any() | 각 열에 결측치가 하나라도 존재하는지 여부를 Boolean 값으로 반환한다. |
| 데이터셋.isnull().all() | 각 열의 모든 데이터가 결측치인지 여부를 Boolean 값으로 반환한다. |
| 데이터셋.isin([값1, 값2]) | 데이터셋에 특정 값들(예: np.nan, np.inf)이 포함되어 있는지 확인한다. 이상치(outlier) 검색 시 유용하다. |
2.2. 결측치 처리 방법
결측치는 데이터의 특성과 분석 목적에 따라 대체하거나 삭제하는 방식으로 처리한다.
1. NaN 대체 (치환)
.fillna(value): 모든 NaN 값을 지정된 value로 치환한다..fillna({'col1': val1, 'col2': val2...}): 열별로 다른 값을 지정하여 치환한다..fillna(method = 'ffill'): NaN 값을 바로 앞 행의 유효한 값으로 치환한다. (Forward Fill).fillna(method = 'bfill'): NaN 값을 바로 뒤 행의 유효한 값으로 치환한다. (Backward Fill)
2. NaN 포함 행 삭제
.dropna(): NaN 값이 하나라도 포함된 행 전체를 삭제한다..dropna(how='all'): 행의 모든 값이 NaN인 경우에만 해당 행을 삭제한다..dropna(thresh = n): NaN이 아닌 유효한 데이터의 개수가 n개 이상인 행만 남기고 나머지는 삭제한다.
2.3. 결측치 포함 데이터 연산
- Pandas DataFrame: NaN 값이 포함되어 있어도 .sum(), .mean()과 같은 기본적인 집계 연산이 가능하다. 연산 시 NaN은 자동으로 제외된다.
- NumPy Array: 배열 내에 NaN 값이 하나라도 있으면 집계 연산이 불가능하며 결과는 NaN으로 반환된다.
이 경우, 해당 데이터를 Pandas DataFrame으로 변환 후 연산을 수행해야 한다.
3. 데이터 결측치 시각화
결측치의 분포와 패턴을 시각적으로 확인하는 것은 데이터 분석 과정에서 매우 중요한 단계이다.
파이썬의 Seaborn과 Missingno 라이브러리가 주로 사용된다.
3.1. Seaborn을 활용한 시각화
Seaborn은 matplotlib을 기반으로 동작하며, 결측치 분포를 직관적으로 표현하는 데 효과적이다.
타이타닉 데이터셋 예제에서 .sns.heatmap(train.isnull(), cbar=False) 코드는 결측치를 히트맵 형태로 시각화한다.
- 히트맵 분석: 이를 통해 'Age' 열에는 변동성이 있는 결측치가 존재하고, 'Cabin' 열은 거의 모든 데이터가 결측치임을 한눈에 파악할 수 있다.
- 변수 간 관계 분석: chart 함수와 막대그래프(kind='bar')를 사용하여 객실 등급('Pclass'), 성별('Sex'), 동승한 가족 수('SibSp') 등 특정 변수에 따른 생존자 현황을 시각화하여 데이터의 특성을 깊이 있게 탐색할 수 있다.
3.2. Missingno를 활용한 시각화
Missingno는 결측치 시각화에 특화된 라이브러리로, 데이터의 "비어 있는 부분"을 분석하는 데 강력한 기능을 제공한다.
- missingno.matrix(데이터셋): 데이터셋 전체의 결측치 위치를 매트릭스 형태로 시각화하여 데이터의 밀도를 직관적으로 보여준다.
- missingno.bar(데이터셋): 각 열의 데이터 완성도(결측치가 아닌 값의 수)를 바 차트로 보여준다.
- missingno.heatmap(데이터셋): 열 간의 결측치 발생 상관관계를 히트맵으로 보여준다. 특정 열에 결측치가 있을 때 다른 열에도 결측치가 발생하는 경향을 파악할 수 있다.
- missingno.dendrogram(데이터셋): 계층적 클러스터링 알고리즘을 사용하여 결측치 발생 패턴이 유사한 열들을 그룹화하여 보여준다.