Post

[사전학습] 4.4 다변량 시각화

4.4 다변량 시각화

다변량 시각화

두 개 이사의 변수로 구성된 데이터의 관계를 시각화 기반으로 파악하는 데이터 탐색 유형
=> 주어진 변수 간의 패턴 및 관계를 다양한 그래프의 시각화를 토앻 전체적으로 파악

다변량 시각화의 종류

데이터 조합비시각화 방안목적
범주형-범주형모자이크플롯두 개 범주형 변수 내 범주 별 조합의 빈도 크기를 개략적으로 파악
범주형-연속형박스플롯
평행좌표
범주 별 기술통계량 및 경향성을 개략적으로 파악
연속형-연속형산점도연속형 변수 간 관계성을 개략적으로 파악(선형/비선형 및 음양 방향 등)

모자이크 플롯

범주형 - 범주형 변수 조합 내 그롭(Subgroup) 크기 비교

  • 범주 그룹 간 비중의 차이를 전체적으로 파악 가능
  • 범주 수가 많고, 각 조합별 비중 차이가 크지 않을 경우 전체적 파악이 어려울 수 있음

박스 플롯

범주형 - 연속형 변수 조합 간 전반적 요약 통계량 파악

  • 많은 데이터를 눈으로 직접 확인하기 어렵고, 대표적 통계 값만으로 파악하기 어려울 땐 용이함
  • 범주 그룹(범주형 변수) 간 수치(연속형 변수)의 집합 범위와 중앙값, 이상치 등을 빠르게 확인할 수 있음
  • 비시각화 기반의 단순 수치값 비교보다 데이터가 설명하는 많은 정보 획득 가능

평행좌표

범주형 - 연속형 변수 조합 간 경향성 파악

  • 연속형 데이터 기반으로 범주 별 경향성 파악에 용이함
  • 데이터의 트렌드 판단 가능
  • 연속형 변수 간 단위 표준화가 이루어지기 전의 데이터로 시각화할 경우 파악이 어려울 수 있음

산점도

연속형 - 연속형 변수 조합 간 상관도 파악

  • 연속형 데이터 간의 관계를 그래프상으로 어떠한 관계가 있는지 파악하기 위함
  • 변수 간 분포를 통해 선형 혹은 비선형 관계 및 음양의 방향 등을 빠르게 파악할 수 있음
  • 범주 Label 간 비교가 필요할 경우, 해당 부분의 그룹 정보를 표시하면 변수 간 관계 및 범주 그룹 간 관계를 함께 파악 가능

실습

1
2
3
4
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
1
2
3
4
5
6
import warnings
from sklearn.datasets import load_boston
with warnings.catch_warnings():
    warnings.filterwarnings("ignore")
    data = load_boston()

1
2
3
4
5
6
X = pd.DataFrame(data.data, columns=data.feature_names)
y = pd.DataFrame(data.target, columns=['MEDV'])

housing = pd.merge(X, y, left_index=True, right_index=True, how='inner')

housing_data = housing.copy()

범주형-범주형 다변량 시각화

모자이크플롯

1
2
housing_data = housing_data.astype({'CHAS':'object'})
housing_data.info()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 506 entries, 0 to 505
Data columns (total 14 columns):
 #   Column   Non-Null Count  Dtype  
---  ------   --------------  -----  
 0   CRIM     506 non-null    float64
 1   ZN       506 non-null    float64
 2   INDUS    506 non-null    float64
 3   CHAS     506 non-null    object 
 4   NOX      506 non-null    float64
 5   RM       506 non-null    float64
 6   AGE      506 non-null    float64
 7   DIS      506 non-null    float64
 8   RAD      506 non-null    float64
 9   TAX      506 non-null    float64
 10  PTRATIO  506 non-null    float64
 11  B        506 non-null    float64
 12  LSTAT    506 non-null    float64
 13  MEDV     506 non-null    float64
dtypes: float64(13), object(1)
memory usage: 55.5+ KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
medv_bins = [
    0,
    np.mean(housing_data['MEDV']),
    np.max(housing_data['MEDV'])
]
medv_names = ['cheap', 'expensive']
housing_data['MEDV_G'] = pd.cut(housing_data['MEDV'], medv_bins, labels=medv_names)

INDUS_bins = [
    0,
    np.mean(housing_data['INDUS']),
    np.max(housing_data['INDUS'])
]
INDUS_names = ['INDUS_LOW', 'INDUS_HIGH']
housing_data['INDUS_G'] = pd.cut(housing_data['INDUS'], INDUS_bins, labels=INDUS_names)

RAD_bins = [
    0,
    np.mean(housing_data['RAD']),
    np.max(housing_data['RAD'])
]
RAD_names = ['RAD_LOW', 'RAD_HIGH']
housing_data['RAD_G'] = pd.cut(housing_data['RAD'], RAD_bins, labels=RAD_names)
1
2
3
4
from statsmodels.graphics.mosaicplot import mosaic

mosaic(housing_data, ['MEDV_G', 'INDUS_G'])
plt.show()

png

1
2
mosaic(housing_data, ['MEDV_G', 'RAD_G'])
plt.show()

png

1
2
mosaic(housing_data, ['MEDV_G', 'INDUS_G', 'RAD_G'], gap=0.03)
plt.show()

png

범주형-연속형 다변량 시각화

박스플롯

1
2
3
plt.figure(figsize=(10, 10))
sns.boxplot(data=housing_data, x='MEDV_G', y='RM')
plt.show()

png

1
2
3
4
plt.figure(figsize=(10, 10))
sns.boxplot(data=housing_data, x='MEDV_G', y='RM')
sns.stripplot(data=housing_data, x='MEDV_G', y='RM', color="0.4")
plt.show()

png

평행좌표

1
2
3
4
5
6
7
from pandas.plotting import parallel_coordinates

sub_data = housing_data[['CRIM', 'AGE', 'INDUS', 'RAD', 'RM', 'MEDV_G']]

plt.figure(figsize=(10, 10))
parallel_coordinates(sub_data, 'MEDV_G', colormap=plt.get_cmap('jet'), alpha=0.5)
plt.show()

png

1
2
3
4
5
6
7
8
9
10
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
x_df = sub_data[['CRIM', 'AGE', 'INDUS', 'RAD', 'RM']]
x_norm = pd.DataFrame(scaler.fit_transform(x_df), columns=['CRIM', 'AGE', 'INDUS', 'RAD', 'RM'])

sub_data_scale = pd.merge(x_norm, sub_data[['MEDV_G']], left_index=True, right_index=True, how='inner')

plt.figure(figsize=(10, 8))
parallel_coordinates(sub_data_scale, 'MEDV_G', colormap=plt.get_cmap('jet'), alpha=0.5)
plt.show()

png

연속형-연속형 다변량 시각화

산점도

1
2
3
housing_data = housing.copy()

housing_data = housing_data.astype({'CHAS':'object'})
1
2
3
plt.figure(figsize=(10, 8))
sns.scatterplot(x='LSTAT', y='RM', data=housing_data)
plt.show()

png

1
2
import scipy.stats as stats
stats.pearsonr(housing_data.LSTAT, housing_data.RM)
1
(-0.6138082718663956, 1.033009132965579e-53)
1
2
3
plt.figure(figsize=(10, 8))
sns.scatterplot(x='RM', y='MEDV', data=housing_data)
plt.show()

png

1
stats.pearsonr(housing_data.RM, housing_data.MEDV)
1
(0.6953599470715388, 2.4872288710082904e-74)

Heatmap

1
2
3
4
5
6
7
8
9
sample_data ={
    'city' : ['seoul', 'seoul', 'seoul', 'newyork', 'newyork', 'newyork', 'london', 'london', 'london'],
    'year' : ['2020', '2021', '2022', '2020', '2021', '2022', '2020', '2021', '2022'],
    'visitor' : [998712, 873164, 124502, 3376442, 2478621, 874510, 2129451, 1878551, 688781]
}

columns = ['city', 'year', 'visitor']
sample_df = pd.DataFrame(sample_data, columns=columns)
sample_df
cityyearvisitor
0seoul2020998712
1seoul2021873164
2seoul2022124502
3newyork20203376442
4newyork20212478621
5newyork2022874510
6london20202129451
7london20211878551
8london2022688781
1
2
pivot_df = sample_df.pivot('city', 'year', 'visitor')
pivot_df
year202020212022
city
london21294511878551688781
newyork33764422478621874510
seoul998712873164124502
1
2
3
plt.figure(figsize=(10, 8))
sns.heatmap(pivot_df, annot=True, fmt='d')
plt.show()

png

This post is licensed under CC BY 4.0 by the author.

[사전학습] 4.3 다변량 비시각화

[사전학습] 5.1~3 정적 시각화