관계 시각화 및 산점도 이해
From the 데이터 사이언스 curriculum
TL;DR
관계 시각화는 데이터 포인트 간의 연결이나 패턴을 보여주는 방법이며, 산점도는 두 변수 간의 관계를 파악하는 데 가장 기본적인 도구입니다. 데이터의 추세, 군집, 이상치를 시각적으로 빠르게 발견하는 데 탁월합니다. 산점도 행렬은 여러 변수 간의 모든 쌍별 관계를 한눈에 볼 수 있게 해줍니다.
1. The Mental Model
데이터 분석에서 우리는 종종 여러 정보들이 서로 어떤 영향을 주는지 궁금해합니다. 관계 시각화는 이런 "누가 누구와 관련이 있나요?"라는 질문에 대한 시각적인 답변입니다. 마치 여러 사람들의 인맥 지도를 그리는 것과 같아서, 어떤 사람들이 서로 친하고 어떤 사람들은 멀리 떨어져 있는지 한눈에 알 수 있게 해줍니다.
2. The Core Material
데이터에서 변수들이 서로 어떻게 관련되어 있는지를 시각적으로 탐색하는 것은 인사이트를 얻는 데 매우 중요합니다. 관계 시각화(Relationship Visualization)는 이러한 연결과 패턴을 드러내는 데 사용되는 다양한 그래프들을 말합니다.
2.1 산점도(Scatter Plot)

Photo by RDNE Stock project on Pexels
산점도는 두 개의 연속형 변수 간의 관계를 시각화하는 가장 일반적이고 강력한 도구입니다. 한 변수를 x축에, 다른 변수를 y축에 놓고 각 데이터 포인트를 점으로 표시합니다.
- 용도: 두 변수 간의 추세(경향성), 군집(클러스터), 이상치(아웃라이어) 등을 파악하는 데 효과적입니다.
- 해석:
- 양의 상관관계(Positive Correlation): 점들이 왼쪽 아래에서 오른쪽 위로 향하는 경향을 보이면, 한 변수가 증가할 때 다른 변수도 증가하는 경향이 있습니다.
- 음의 상관관계(Negative Correlation): 점들이 왼쪽 위에서 오른쪽 아래로 향하는 경향을 보이면, 한 변수가 증가할 때 다른 변수는 감소하는 경향이 있습니다.
- 무상관(No Correlation): 점들이 특별한 패턴 없이 흩어져 있으면, 두 변수 사이에 선형적인 관계가 거의 없다는 것을 의미합니다.
- 비선형 관계: 점들이 곡선 형태를 보이면 비선형 관계가 있을 수 있습니다.
2.2 산점도 행렬(Scatter Plot Matrix)

Photo by RDNE Stock project on Pexels
여러 개의 변수가 있을 때, 모든 변수 쌍 간의 관계를 한 번에 보고 싶을 때 산점도 행렬을 사용합니다. 각 변수 쌍에 대한 산점도를 격자 형태로 배열합니다. 대각선에는 보통 각 변수의 분포를 보여주는 히스토그램이나 커널 밀도 추정 그래프가 표시됩니다.
- 용도: 여러 변수 간의 다중 비교 및 초기 탐색적 데이터 분석(EDA)에 매우 유용합니다. 복잡한 데이터셋에서 어떤 변수들이 서로 관련이 있는지 빠르게 파악할 수 있습니다.
graph TD
A["데이터 준비 (관심 변수 선택)"] --> B["변수 쌍 선택"];
B --> C{"두 변수 모두 연속형인가?"};
C -- "예" --> D["산점도 생성 (x축: 변수1, y축: 변수2)"];
C -- "아니오" --> E["다른 적절한 시각화 기법 고려 (예: 박스 플롯)"];
D --> F["관계 패턴 확인 (선형, 비선형, 군집 등)"];
F --> G{"추가 변수 고려?"};
G -- "예 (3개 이상)" --> H["산점도 행렬 생성"];
H --> I["모든 변수 쌍의 관계 탐색"];
I --> J["이상치 및 군집 시각적으로 파악"];
J --> K["인사이트 도출 및 다음 분석 단계 결정"];
K --> L["분석 종료"];
G -- "아니오" --> L;
2.3 matplotlib과 seaborn으로 산점도 그리기

Photo by Matthew Jesús on Pexels
파이썬에서는 matplotlib과 seaborn 라이브러리를 사용하여 산점도를 쉽게 그릴 수 있습니다.
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np
# 가상 데이터 생성
np.random.seed(42)
data = {
'점수_1': np.random.normal(loc=70, scale=10, size=100),
'점수_2': np.random.normal(loc=65, scale=12, size=100) + np.random.normal(loc=0, scale=3, size=100) * 0.5,
'공부시간': np.random.normal(loc=5, scale=2, size=100).clip(1, 10), # 1시간 ~ 10시간
'만족도': np.random.randint(1, 6, size=100) # 1~5점
}
df = pd.DataFrame(data)
# 공부시간과 점수_1에 양의 상관관계를 추가
df['점수_1'] = df['점수_1'] + df['공부시간'] * 2
df['점수_2'] = df['점수_2'] + df['공부시간'] * 1.5
print("데이터 미리보기:")
print(df.head())
# 1. 기본적인 산점도
plt.figure(figsize=(8, 6))
plt.scatter(df['공부시간'], df['점수_1'])
plt.title('공부시간과 점수_1 간의 관계')
plt.xlabel('공부 시간 (시간)')
plt.ylabel('점수 1')
plt.grid(True)
plt.show()
# 2. Seaborn을 이용한 산점도 (추세선 추가)
plt.figure(figsize=(8, 6))
sns.regplot(x='공부시간', y='점수_1', data=df, ci=95) # ci는 신뢰구간
plt.title('공부시간과 점수_1 간의 관계 (Seaborn, 추세선 포함)')
plt.xlabel('공부 시간 (시간)')
plt.ylabel('점수 1')
plt.grid(True)
plt.show()
# 3. 색상으로 세 번째 변수 추가 (범주형)
# 만족도를 범주형으로 변환 (산점도에서 색상으로 구분하기 위해)
df['만족도_그룹'] = df['만족도'].astype('category')
plt.figure(figsize=(10, 7))
sns.scatterplot(x='공부시간', y='점수_1', hue='만족도_그룹', data=df, palette='viridis', s=100, alpha=0.7)
plt.title('공부시간, 점수_1, 만족도 간의 관계')
plt.xlabel('공부 시간 (시간)')
plt.ylabel('점수 1')
plt.grid(True)
plt.legend(title='만족도')
plt.show()
# 4. 산점도 행렬 (pairplot)
# 모든 숫자형 변수들 간의 관계를 한눈에 보기
sns.pairplot(df[['공부시간', '점수_1', '점수_2', '만족도']], diag_kind='kde') # 대각선에 분포 표시
plt.suptitle('변수들 간의 산점도 행렬', y=1.02) # 전체 제목
plt.show()
3. Worked Example
어떤 온라인 상점의 고객 데이터를 가지고 있다고 상상해 봅시다. 우리는 고객의 월별 구매 횟수와 평균 구매 금액이 서로 어떤 관계를 가지는지 궁금합니다. 또한, 이 관계가 고객의 멤버십 등급(일반, VIP)에 따라 어떻게 달라지는지도 알고 싶습니다.
```python
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np
가상 고객 데이터 생성
np.random.seed(42)
n_customers = 200
customer_data = {
'월별_구매_횟수': np.random.poisson(lam=3, size=n_customers) + 1, # 최소 1회 구매
'평균_구매_금액': np.random.normal(loc=50, scale=15, size=n_customers),
'멤버십_등급': np.random.choice(['일반', 'VIP'], size=n_customers, p=[0.7, 0.3])
}
df_customers = pd.DataFrame(customer_data)
멤버십 등급에 따라 데이터 조정 (VIP 고객이 더 많이 구매하고 더 비싸게 구매하는 경향)
df_customers.loc[df_customers['멤버십_등급'] == 'VIP', '월별_구매_횟수'] = \
df_customers.loc[df_customers['멤버십_등급'] == 'VIP', '월별_구매_횟수'] * 1.5 + 2
df_customers.loc[df_customers['멤버십_등급'] == 'VIP', '평균_구매_금액'] = \
df_customers.loc[df_customers['멤버십_등급'] == 'VIP', '평균_구매_금액'] * 1.2 + 20
구매 횟수와 금액이 음수가 되지 않도록 조정
df_customers['월별_구매_횟수'] = df_customers['월별_구매_횟수'].clip(1).round().astype(int)
df_customers['평균_구매_금액'] = df_customers['평균_구매_금액'].clip(10).round(2)
print("고객 데이터 미리보기:")
print(df_customers.head())
산점도를 사용하여 월별 구매 횟수와 평균 구매 금액 간의 관계 시각화
plt.figure(figsize=(10, 7))
sns.scatterplot(x='월별_구매_횟수', y='평균_구매_금액', hue='멤버십_등급',
data=df_customers, palette={'일반': 'skyblue', 'VIP': 'salmon'},
s=100, alpha=0.7)
plt.title('월별 구매 횟수와 평균 구매 금액 (멤버십 등급별)')
plt.xlabel('월별 구매 횟수')
plt.ylabel('평균 구매 금액 (
Frequently asked about 관계 시각화 및 산점도 이해
Study this next
Get the full 데이터 사이언스 curriculum
Clone the complete plan to your dashboard for unlimited AI-generated notes, practice quizzes, and a personalised revision schedule.
Save this course free