Coding Diary.

(데이터분석) seaborn으로 Violin plot(바이올린 플롯) 나타내기 본문

Coding/Data analysis

(데이터분석) seaborn으로 Violin plot(바이올린 플롯) 나타내기

life-of-nomad 2024. 5. 27. 11:17
728x90
반응형

🔻(지난글) 지터형 산점도🔻

 

(데이터분석) seaborn의 투명도, 지터링으로 산점도 과다중첩 해결하기

차트에 과도하게 많은 점이 존재하거나 주어진 숫자 변수가 불연속적일 경우, 주어진 그대로 산점도를 그려서 정보를 확인하기 어려울 수 있습니다. 차트 상에서 너무 많은 데이터 포인트가 겹

life-of-nomad.tistory.com

 

지난 글에서 지터형 산점도에 비해 알아보았습니다. 
이번 글에서는 지터형 산점도에 비교하여 분포를 비교하기가 더 쉬운 바이올린 플롯에 대해 알아보겠습니다.
아래 그림과 같이 뚜렷한 곡선로 표현하면 변수가 범주형이어서 비교하기가 더 쉽습니다.

출처 ㅣ Udacity

1. Violin plot (바이올린 플롯)

  • 바이올린 플롯은 정량적 변수와 정성적 변수 간의 관계를 나타낼 떄 보편적으로 사용됩니다.
  • 바이올린 플롯은 단순하게 요약 통계를 차트로 나타내는 대신 커널 밀도 추정(Kernel Density Estimate, KDE)을 사용합니다.
  • KDE는 데이터의 확률 밀도 함수에 대한 추정으로써, 매끄럽게 다듬어진 히스토그램이라고 볼 수 있습니다.
  • 바이올린 플롯에서는 정성적 변수의 서로 다른 수준별로 정량적 변수의 값 분포가 그려집니다.
  • 하지만 이것은 밀도를 추정한 것일 뿐이므로 비현실적인 형태(특히 분포의 양쪽 끝 부분)가 나타날 수 있습니다.
  • 예를 들어, 비용을 나타내는 바이올린 플롯은 0 미만의 영역에도 걸쳐 나타날 수 있습니다. 
  • 바이올린 플롯은 seaborn의 violinplot()함수를 사용하면 나타낼 수 있습니다. 

 

2. 예시

1) 차급(정성적 변수)에 따른 연비(정량적 변수) 바이올린 플롯

  • 먼저, 필요한 라이브러리와 데이터를 불러오겠습니다. 
  • 데이터세트는 지난 글에서 이용한 연비 데이터세트를 이용하겠습니다.
import numpy as np
import pandas as pd

import matplotlib.pyplot as plt
import seaborn as sns
df = pd.read_csv('../data/fuel-econ/csv')
df.head(5)

  • 연비 변수와 정성적 변수인 차급 사이에 존재하는 관계에 대해 알아보겠습니다.
  • 먼저, 범주형 데이터에 대한 새로운 데이터 유형을 정의하겠습니다.
  • 이는 순서가 존재하는 데이터 유형으로써 그 순서에 따라 차트를 작성하는 데 사용됩니다.
#세단의 종류
sedan_classes = ['Minicompact Cars', 'Subcompact Cars', 'Compact Cars', 'Midsize Cars', 'Large Cars']

#sedan_classes에 정의된 분류들을 순서가 있는 범주형 데이터로 변환하기
vclasses = pd.CategoricalDtype(ordered=True, categories=sedan_classes)

#pandas.astype()을 통해 "VClass"열을 일반 객체 유형에서 순서가 있는 범주형으로 변환하기
df['VClass'] = df['VClass'].astype(vclasses);

sns.violinplot(data=df, x='VClass', y='comb');

 

2) 내부에 데이터 포인트가 존재하지 않는 바이올린 플롯

  • 위의 바이올린 플롯에서 보면 countplot()처럼 각 수준에 따라 서로 다른 색상이 적용되었습니다.
  • 이렇게 색상을 적용할 필요가 없으므로 매개변수 color을 설정해서 모든 곡선의 색상을 통일할 수 있습니다.
  • 또한, 각 커브 안에 중앙에 흰 점이 있는 검은 형상이 존재하는데 이는 상자 그림입니다.
  • 이 상자 그림을 제거하고 싶다면 violinplot에서 inner=None으로 매개변수를 설정하면 됩니다.
  • 그리고 x축 레이블도 서로 겹쳐 읽을수가 없으므로 레이블을 회전시키면 됩니다.
#인수 'inner'은 바이올린 내부의 데이터 포인트를 나타냅니다.
#이것은 {“box”, “quartile”, “point”, “stick”, None} 중 하나의 값으로 설정할 수 있습니다.
#"box"로 설정하면 내부에 작은 상자 그림이 추가됩니다.

sns.violinplot(data=df, x='VClass', y='comb', color='tab:blue', inner=None)
plt.xticks(rotation=15);

  • 차트를 살펴보며 주요 특징을 알아보겠습니다.
  • Subcompact cars : 확률밀도함수를 옆으로 회전시킨 것과 같음 => 23,24마일 부근에 대부분의 데이터가 분포
  • Large Cars : 평균 연비가 Subcompact 보다 훨씬 낮음, 이상치가 굉장히 많음
  • Minicompact Cars : 쌍봉 분포 => 20,21마일에 몰려있고 30부근에도 몰려있음

 

3) 내부에 사분위수 정보를 표시한 바이올린 플롯

  • 위에서 언급한 매개변수 inner을 None이 아니라 quartile로 설정해보겠습니다.
sns.violinplot(data=df, x='VClass', y='Comb', color='tab:blue', inner='quartile')
plt.xticks(rotation=30);

  • 차 급별 영역 내부에 세 개의 사분위수가 표시됩니다. 
  • 제일 아래는 25번째 백분위수, 중앙은 중앙값, 제일 위의 선은 75번째 백분위수 즉 제 3사분위수 입니다.
  • 이렇게 사분위수를 나타내면 본포 중심부의 양상을 파악하기가 용이해집니다.
  • 예를 들어, Large Cars 에서는 소수의 이상치들이 존재하므로 중심부에서 먼 곳까지 긴 꼬리가 있습니다.

 

2. 상자 그림과 바이올린 플롯 비교

  • 동일한 데이터 분포를 나타내는 상자 그림과 바이올린 플롯을 비교해보겠습니다.
#하나의 Figure에 두 개의 차트 넣기
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(16, 5))

#왼쪽 차트 : 상자 그림
sns.boxplot(data=df, x='VClass', y='comb', color='tab:red', ax=ax1)
plt.xticks(rotation=15);

#오른쪽 차트 : 바이올린 플롯 
sns.violinplot(data=df, x='VClass', y='comb', color='tab:red', ax=ax2)
plt.xticks(rotation=15);
plt.ylim(ax1.get_ylim()) #y축의 범위를 왼쪽 차트와 동일하게 설정하기

  • 두 차트를 동일한 기준으로 비교하기 위해서 오른쪽 차트에 ylim을 추가하여 두 차트의 y축 범위를 통일했습니다.
  • 상자 그림에서 상자 중앙의 선분은 분포의 중앙값을 나타내며 상자 상단과 하단은 각각 데이터의 제3사분위수와 제1사분위수를 나타냅니다. 
  • 상자의 높이는 사분범위(Interquartile Range, IQR)를 나타냅니다.
  • 상자의 하단과 상단으로부터 뻗어나가는 선은 각각 제1사분위수와 제3사분위수로부터 최솟값과 최댓값에 이르는 거리를 나타냅니다.
  • 일반적으로 이 길이는 IQR의 1.5배 까지로 제한됩니다.
  • 두 차트를 비교해보면 상자 그림이 바이올린 플롯보다 데이터를 훨씬 명확하게 요약한다는 것을 알 수 있습니ㅏㄷ.
  • 따라서 여러 그룹을 비교해야 하거나 설명적 시각화 자료를 작성할 때는 상자 그림을 선택하는 편이 더 적합합ㄴ다.
  • 하지만 상자 그림은 바이올린 플롯만큼 데이터 분포의 형태를 섬세하게 나타내지는 못합니다.
  • 예를 들어 Minisompact Cars 범주가 쌍봉을 형성한다는 것을 확인할 수 없습니다.
  • 바이올린 플롯은 탐색적 목적에 적합한 차트입니다. 

 

3. 바이올린 플롯 가로로 그리기

  • seaborn은 x와 y중에서 무엇이 범주형 변수를 나타내느냐에 따라서 바이올린 플롯의 방향을 적절하게 선택할 수 있습니다.
  • 하지만 두 변수 모두가 숫자 데이터라면 매개변수 orient를 사용하여 차트의 방향을 결정할 수 있습니다.
sns.violinplot(data=df, y='VClass', x='comb', color='tab:blue', inner=None);

 

728x90
반응형