데이터 분석 작업에서 탐색적 데이터 분석(EDA, Exploratory Data Analysis)은 반드시 가장 먼저 수행해야 하는 단계입니다. EDA는 다음과 같은 목적을 달성하는 데 도움을 줍니다.
데이터셋에 대한 깊이 있는 인사이트를 제공합니다.
데이터 이면에 숨어 있는 구조를 이해할 수 있게 해줍니다.
중요한 변수(파라미터)와 변수 간의 관계를 추출합니다.
데이터에 담긴 기본 가정을 검증합니다.
샘플 데이터셋으로 이해하는 EDA
파이썬으로 EDA를 익혀 보기 위해 웹사이트나 로컬 디스크에서 샘플 데이터를 가져올 수 있습니다. 여기서는 공개된 UCI 머신러닝 저장소의 레드 와인 품질(Wine Quality) 데이터셋을 사용해, EDA로 데이터로부터 최대한 많은 인사이트를 도출해 보겠습니다.
import pandas as pd
df = pd.read_csv("https://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-red.csv")
df.head()
위 스크립트를 주피터 노트북에서 실행하면 아래와 같은 결과가 출력됩니다.

단계별로 살펴보면 다음과 같습니다.
먼저 필요한 라이브러리를 임포트합니다. 여기서는 pandas를 사용합니다.
pandas의 read_csv() 함수로 CSV 파일을 읽어 들입니다. 해당 데이터셋에서는 각 값이 구분자(delimiter) ';'로 구분되어 있습니다.
pandas가 제공하는 .head() 함수를 사용하면 데이터셋의 처음 다섯 개 관측치를 반환받을 수 있습니다. 마찬가지로 .tail() 함수를 사용하면 마지막 다섯 개 관측치도 확인할 수 있습니다.
.shape 속성을 사용하면 데이터셋의 전체 행(row)과 열(column) 개수를 알 수 있습니다.
df.shape

info() 함수를 활용하면 데이터셋에 어떤 열이 있는지, 각 열의 데이터 타입은 무엇인지, 그리고 비어 있는 값(결측값)이 존재하는지까지 한눈에 파악할 수 있습니다.
df.info()

위 출력 결과를 통해 다음 사실을 확인할 수 있습니다.
데이터는 float형과 정수(integer) 값으로만 구성되어 있습니다.
모든 열이 non-null 상태입니다. 즉, 비어 있거나 누락된 값이 없습니다.
pandas의 또 다른 유용한 함수인 describe()는 데이터의 개수(count), 평균(mean), 표준편차(std), 최솟값(min), 최댓값(max), 사분위수(quartile) 등 요약 통계를 한 번에 보여 줍니다.
df.describe()

위 결과에서 각 열의 평균값이 중앙값(median, 50%)보다 작다는 것을 알 수 있습니다.
'residual sugar', 'free sulfur dioxide', 'total sulfur dioxide' 변수들은 75% 지점 값과 최댓값 사이에 매우 큰 차이를 보입니다.
이 두 가지 관찰 결과는 데이터셋에 극단적인 값, 즉 이상치(outlier)가 존재할 가능성을 시사합니다.
종속변수(dependent variable)인 'quality'에서 얻을 수 있는 핵심 인사이트는 다음과 같습니다.
df.quality.unique()

'quality' 점수 척도는 1이 가장 낮은 점수(나쁨), 10이 가장 높은 점수(좋음)를 의미합니다.
위 결과에서 알 수 있듯이 1점(최하), 2점, 9점, 10점(최고)인 관측치는 하나도 없으며, 모든 점수는 3점에서 8점 사이에 분포합니다.
df.quality.value_counts()

위 처리된 데이터는 각 품질 점수별 관측치 수를 내림차순으로 보여 줍니다.
대부분의 품질 점수는 5~7 범위에 집중되어 있습니다.
가장 적은 관측치는 3점과 8점 범주에서 나타납니다.
데이터 시각화
결측값(Missing Values) 확인하기
seaborn 라이브러리를 활용하면 화이트 와인 CSV 데이터셋에 결측값이 있는지 손쉽게 확인할 수 있습니다. 아래 코드가 바로 그 방법입니다.
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
sns.set()
df = pd.read_csv("https://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-white.csv", sep=";")
sns.heatmap(df.isnull(), cbar=False, yticklabels=False, cmap='viridis')
출력 결과

위 히트맵에서 볼 수 있듯이 이 데이터셋에는 결측값이 없습니다. 만약 결측값이 있다면 보라색 배경 위에 다른 색조로 표현된 영역이 나타날 것입니다.
결측값이 포함된 다른 데이터셋에 동일한 코드를 적용해 보면 그 차이를 직접 확인할 수 있습니다.
상관관계(Correlation) 확인하기
데이터셋의 여러 변수 간 상관관계를 확인하려면 기존 코드에 아래 코드를 추가하면 됩니다.
plt.figure(figsize=(8,4)) sns.heatmap(df.corr(),cmap='Greens',annot=False)
출력 결과

위 히트맵에서 진한 색조는 양의 상관관계를, 연한 색조는 음의 상관관계를 나타냅니다.
annot=True로 값을 변경하면 격자 셀 안에 각 특성(feature) 간 상관계수 값이 함께 표시됩니다.
annot=True 옵션을 적용한 또 다른 상관관계 행렬도 생성해 보겠습니다. 기존 코드에 아래 코드를 추가하세요.
k = 12 cols = df.corr().nlargest(k, 'quality')['quality'].index cm = df[cols].corr() plt.figure(figsize=(8,6)) sns.heatmap(cm, annot=True, cmap = 'viridis')
출력 결과

위 결과를 보면 밀도(density)는 잔당(residual sugar)과 강한 양의 상관관계를 보이는 반면, 알코올(alcohol)과는 강한 음의 상관관계를 보입니다.
또한 유리 황(free sulfur dioxide)과 품질(quality) 사이에는 유의미한 상관관계가 없습니다.