" 기술통계와 추론통계란 "
수집한 데이터를 하나의 값으로 정리 / 요약 / 해석 / 표현,
ex) 평균, 중앙값, 분산, 표준편차 등
한 눈에 파악할 수 있어 흐름을 빠르게 이해하고 결정할 수 있음
표본으로 전체를 "추정"
모집단 : 내가 알고 싶은 전체 대상
전수조사 : 모집단을 전부 다 조사
표본 : 모집단의 일부
표본조사 : 모집단에서 일부만 추출하여 조사, 모집단을 추정
표본을 잘 뽑는 것이 중요 !
" 데이터 분석의 3가지 목적 "
많은 데이터를 하나로 요약하여 한 번에 파악하기 위함
방법
"무슨 일이 일어났는지" 보다는 "왜 그런 일이 일어났는지 찾는 것"
기존(과거) 데이터를 기준으로 예측, 확률적 패턴 기반 추정
" 도수분포표 "
단계
data = {
'계급' : ['145~150', '150~155', '155~160', '160~165', '165~170', '170~175'],
'도수' : [1, 15, 54, 85, 39, 6]
}
df = pd.DataFrame(data)
df['상대도수'] = df['도수']/(df['도수'].sum())
df['누적도수'] = df['상대도수'].cumsum() # cumsum() = 누적합 함수
fig = plt.figure(figsize=(8,6), facecolor='k')
ax= fig.add_subplot()
ax.patch.set_facecolor('k')
plt.bar(df['계급'], df['도수'], color = '#7FFFD4')
plt.title('중학생 키 도수분포표', color = 'white')
plt.xlabel('키 구간 (cm)', color = 'white')
plt.xticks(color='white')
plt.ylabel('학생 수', color = 'white')
plt.yticks(color = 'white')
plt.gca().set_axisbelow(True)
plt.grid(axis='y', color = 'lightgray', linewidth = 0.3)
plt.show()
" 시각화 조건 "
범주형(문자형) 변수(Categorical)
연속형(수치형) 변수(Continuous)
이산형(수치형) 변수(Discrete)
변수의 개수에 따라 그래프 종류가 달라짐
" 막대 그래프 "
특징
종류
장점
단점
# 누적 막대 그래프
fig = plt.figure(figsize=(8,6), facecolor='k')
ax= fig.add_subplot()
ax.patch.set_facecolor('k')
pay_counts = df['pay_method'].value_counts()
plt.bar(pay_counts.index, pay_counts.values, width = 0.4, edgecolor = 'black', color = '#7FFFD4')
plt.bar(pay_counts.index, pay_counts.values * 0.5, width = 0.4, edgecolor = 'black', color = '#00BFFF')
plt.title('Payment Method Distribution', color='w')
plt.xlabel('Method', color='w')
plt.xticks(color='w')
plt.ylabel('Count', color='w')
plt.yticks(color='w')
plt.gca().set_axisbelow(True)
plt.grid(axis='y', color = 'lightgray', linewidth = 0.3)
plt.show()
# 그룹형 막대 그래프
fig = plt.figure(figsize=(8,6), facecolor='k')
ax= fig.add_subplot()
ax.patch.set_facecolor('k')
sns.countplot(data=df, x='pay_method', hue = 'gender', order = ['QuickPay', 'Cash', 'Card'], dodge=True, palette={'Male':'#7FFFD4', 'Female':'#00BFFF'})
plt.title('Payment Method Distribution', color='w')
plt.xlabel('Method', color='w')
plt.xticks(color='w')
plt.ylabel('Count', color='w')
plt.yticks(color='w')
plt.gca().set_axisbelow(True)
plt.grid(axis='y', color = 'lightgray', linewidth = 0.3)
plt.show()
![]() |
![]() |
" 원 그래프 "
특징
종류
장점
단점
사용하기 적절한 경우
fig = plt.figure(figsize=(8,6), facecolor='k')
ax= fig.add_subplot()
ax.patch.set_facecolor('k')
colors = ['#7FFFD4', '#87CEFA', '#00BFFF']
wedges, texts, autotexts = plt.pie(pay_counts.values, labels=pay_counts.index, autopct='%1.1f%%', startangle=90, colors=colors, textprops={'color': 'w', 'fontsize': 12})
plt.title('Payment Method Share', color='w')
# autopct 텍스트의 색상 변경
for text in autotexts:
text.set_color('k')
plt.show()
# 폭발형
fig = plt.figure(figsize=(8,6), facecolor='k')
ax= fig.add_subplot()
ax.patch.set_facecolor('k')
colors = ['#7FFFD4', '#87CEFA', '#00BFFF']
wedges, texts, autotexts = plt.pie(pay_counts.values, labels=pay_counts.index, autopct='%1.1f%%', startangle=90, colors=colors, textprops={'color': 'w', 'fontsize': 12}, explode = [0, 0.2, 0.3])
plt.title('Payment Method Share', color='w')
# autopct 텍스트의 색상 변경
for text in autotexts:
text.set_color('k')
plt.show()
![]() |
![]() |
" 기타 범주형 그래프 "
특징

특징
from statsmodels.graphics.mosaicplot import mosaic
import matplotlib.pyplot as plt
# 데이터
data_dict = {('남자','예'): 30,
('남자','아니오'): 70,
('여자','예'): 20,
('여자','아니오'): 80}
# 색상 매핑
colors = {
('남자','예'): '#B2F7EF',
('남자','아니오'): '#7FFFD4',
('여자','예'): '#66CDAA',
('여자','아니오'): '#00CED1'
}
# Figure 생성 (배경 검정)
fig = plt.figure(figsize=(8,6), facecolor='black')
ax = fig.add_subplot(111)
ax.set_facecolor('black')
# 모자이크 플롯
mosaic(data_dict, gap=0, ax=ax,
properties=lambda key: {'facecolor': colors[key], 'edgecolor': None})
# 제목
plt.title("성별과 흡연 여부 모자이크 플롯 (Mint~Blue)", color='white', fontsize=16)
# 축 제거 + 텍스트 색상 흰색으로 변경
ax.tick_params(colors='white', which='both') # 눈금, 숫자 색상 흰색
ax.xaxis.label.set_color('white')
ax.yaxis.label.set_color('white')
plt.axis('off')
plt.show()
| 특징 | 모자이크 플롯 | 트리맵 |
|---|---|---|
| 용도 | 범주형 데이터의 교차 관계/빈도 | 계층적 데이터의 크기/비율 비교 |
| 변수 | 주로 범주형 값 (빈도) | 주로 수치형 값 (크기) |
| 계층 | 분할된 사각형 | 내포된 사각형 |
| 예시 | 하드 드라이브 폴더 크기 | 성별에 따른 타이타닉 생존율 |
" 히스토그램 "
특징
해석
fig = plt.figure(figsize=(8,6), facecolor='k')
ax= fig.add_subplot()
ax.patch.set_facecolor('k')
plt.hist(df['height_cm'], bins=15,range = (160, 180), density = True, histtype = 'bar', edgecolor='#00BFFF', color = '#7FFFD4', linewidth = 0.7)
plt.title('Histogram of Height (cm)', color='w')
plt.xlabel('Height (cm)', color='w')
plt.xticks(color='w')
plt.ylabel('Count', color='w')
plt.yticks(color='w')
plt.gca().set_axisbelow(True)
plt.grid(axis='y', color = 'lightgray', linewidth = 0.3)
plt.show()
# hue로 그룹 구분 및 밀도 곡선 추가한 계단식
fig = plt.figure(figsize=(8,6), facecolor='k')
ax= fig.add_subplot()
ax.patch.set_facecolor('k')
sns.histplot(data = df, x='height_cm', bins=15, hue = 'gender', kde=True, stat='count', multiple = 'dodge', element = 'step', palette={'Male':'#7FFFD4', 'Female':'#00BFFF'})
plt.title('남/여 키 분포', color='w')
plt.xlabel('키', color='w')
plt.xticks(color='w')
plt.ylabel('빈도', color='w')
plt.yticks(color='w')
plt.gca().set_axisbelow(True)
plt.grid(axis='y', color = 'lightgray', linewidth = 0.3)
plt.show()
![]() |
![]() |
" 박스플롯 "
구성요소
해석
fig = plt.figure(figsize=(8,6), facecolor='k')
ax= fig.add_subplot()
ax.patch.set_facecolor('k')
colors = ['#7FFFD4', '#00BFFF']
grouped = [df.loc[df['gender']=='Male','spend_10k'],
df.loc[df['gender']=='Female','spend_10k']]
bplot = plt.boxplot(grouped, labels=['Male','Female'], showfliers=True, patch_artist=True, whiskerprops=dict(linewidth=0.7), capprops=dict(linewidth=0.7), medianprops={'color': 'w', 'linewidth':0.7}, notch = True)
for patch, color in zip(bplot['boxes'], colors):
patch.set_facecolor(color)
for whisker, color in zip(bplot['whiskers'], [colors[0], colors[0], colors[1], colors[1]]):
whisker.set(color=color, linewidth=1.2)
for cap, color in zip(bplot['caps'], [colors[0], colors[0], colors[1], colors[1]]):
cap.set(color=color, linewidth=1.2)
for flier, color in zip(bplot['fliers'], colors):
flier.set(marker='o', markeredgecolor=color, markersize=3)
plt.title('Spend (10k KRW) by Gender', color='w')
plt.xlabel('Gender', color='w')
plt.xticks(color='w')
plt.ylabel('Spend (10k KRW)', color='w')
plt.yticks(color='w')
plt.gca().set_axisbelow(True)
plt.grid(axis='y', color = 'lightgray', linewidth = 0.3)
plt.show()
# 결제수단별 박스플롯
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import matplotlib
import matplotlib.collections as mcoll
fig, ax = plt.subplots(figsize=(8,6), facecolor='k')
ax.set_facecolor('k')
ax.patch.set_facecolor('k')
colors = ['#7FFFD4', '#87CEFA', '#00BFFF']
flierprops = dict(
marker='o',
markerfacecolor='none', # 내부 채우기 없애기
markeredgewidth=0.7,
markersize=3,
markeredgecolor='#AFEEEE' # 원하는 색
)
sns.boxplot(
data=df, x='gender', y='spend_10k',
showfliers=True, hue = 'pay_method',
dodge = True, palette=colors, medianprops={'color': 'w', 'linewidth':0.7},
boxprops={'edgecolor':'none'}, notch = True, flierprops=flierprops, ax=ax)
line_colors = ['#7FFFD4', '#7FFFD4','#7FFFD4', '#7FFFD4','w','k','#7FFFD4', '#7FFFD4','#7FFFD4', '#7FFFD4','w','k',
'#87CEFA', '#87CEFA', '#87CEFA', '#87CEFA','w','k','#87CEFA', '#87CEFA', '#87CEFA', '#87CEFA','w','k',
'#00BFFF', '#00BFFF', '#00BFFF', '#00BFFF','w','k','#00BFFF', '#00BFFF', '#00BFFF', '#00BFFF','w','k']
for i, line in enumerate(ax.lines):
line.set_color(line_colors[i])
line.set_linewidth(0.7)
# 스타일 정리
ax.set_title('Spend (10k KRW) by Gender', color='w')
ax.set_xlabel('Gender', color='w')
ax.set_ylabel('Spend (10k KRW)', color='w')
ax.tick_params(colors='w')
ax.grid(axis='y', color='lightgray', linewidth=0.3)
plt.show()
![]() |
![]() |
" 산점도 "
특징
장점
단점
# 산점도
fig = plt.figure(figsize=(8,6), facecolor='k')
ax= fig.add_subplot()
ax.patch.set_facecolor('k')
colors = ['#7FFFD4', '#00BFFF']
sns.scatterplot(data=df, x='height_cm', y='weight_kg', hue='gender', palette=colors, style='pay_method')
ax.set_title('Height vs Weight', color='w')
ax.set_xlabel('Height (cm)', color='w')
ax.set_ylabel('Weight (kg)', color='w')
ax.spines['bottom'].set_color('w')
ax.spines['left'].set_color('w')
ax.tick_params(colors='w')
# 산점도 행렬
colors = ['#7FFFD4', '#87CEFA', '#00BFFF']
hue_colors = ['#DDA0DD', '#FFFFE0']
vars_list = ['height_cm', 'weight_kg', 'spend_10k']
g = sns.pairplot(df, vars=vars_list, diag_kind='kde', hue='gender', palette=hue_colors)
g.fig.set_facecolor('k')
for ax in g.axes.flatten():
ax.set_facecolor('k') # subplot 배경
ax.tick_params(colors='w') # 눈금 색상
ax.set_xlabel(ax.get_xlabel(), color='w')
ax.set_ylabel(ax.get_ylabel(), color='w')
for spine in ax.spines.values():
spine.set_color('w')
for i in range(len(vars_list)):
for j in range(len(vars_list)):
ax = g.axes[i,j]
color = colors[j] if i!=j else colors[i] # 대각선과 비대각선 구분
# 대각선 KDE 선 색상
if i==j:
for line in ax.lines:
line.set_color(color)
for poly in ax.collections:
poly.set_facecolor('none') # fill 제거
poly.set_edgecolor(color)
else:
# 산점도 점 색상
for pathcoll in ax.collections:
pathcoll.set_edgecolor(color)
pathcoll.set_facecolor('none')
pathcoll.set_sizes([40])
g.fig.suptitle('Height vs Weight vs Spend', color='w')
![]() |
![]() |
" 선 그래프 "
특징
해석
장점
단점
import matplotlib.dates as mdates
fig = plt.figure(figsize=(8,6), facecolor='k')
ax= fig.add_subplot()
ax.patch.set_facecolor('k')
colors = ['#7FFFD4', '#00BFFF']
plt.plot(ts.index, ts['visitors'], color='#7FFFD4')
ax.set_title('Daily Visitors Trend', color='w')
ax.set_xlabel('Date', color='w')
ax.set_ylabel('Visitors', color='w')
ax.tick_params(colors='w')
ax.spines['bottom'].set_color('w')
ax.spines['left'].set_color('w')
# 날짜 포맷 지정 (예: '2025-06-01', '2025-07-01' …)
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))
# 눈금 간격 (예: 한 달 단위)
plt.gca().xaxis.set_major_locator(mdates.MonthLocator())
plt.tight_layout()
plt.show()
" 히트맵 "
특징
해석
장점
단점
import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap
import numpy as np
import pandas as pd
# 예시 데이터
np.random.seed(0)
data = np.random.rand(3,3)
df = pd.DataFrame(data, columns=['height_cm', 'weight_kg', 'spend_10k'])
# 상관행렬 계산
corr = df.corr()
# 사용자 색상
colors = ['#7FFFD4', '#87CEFA', '#00BFFF']
cmap = LinearSegmentedColormap.from_list("custom_cmap", colors)
# 히트맵
fig, ax = plt.subplots(figsize=(8,6))
sns.heatmap(corr, annot=True, fmt=".2f", vmin=-0.15, vmax=0.1, center=0,
cmap=cmap, ax=ax, cbar_kws={"label": "Correlation"})
# dark theme
fig.set_facecolor('k')
ax.set_facecolor('k')
# x/y tick label (변수명) 흰색
ax.set_xticklabels(ax.get_xticklabels(), color='w')
ax.set_yticklabels(ax.get_yticklabels(), color='w')
# tick, spine
ax.tick_params(colors='w', which='both')
for spine in ax.spines.values():
spine.set_color('w')
# 컬러바
cbar = ax.collections[0].colorbar
cbar.ax.yaxis.set_tick_params(color='w')
plt.setp(cbar.ax.yaxis.get_ticklabels(), color='w')
cbar.outline.set_edgecolor('w')
# title
ax.set_title('Height vs Weight vs Spend', color='w', fontsize=14)
plt.show()
불펌~♡