Skip to Content

๊ธฐ์ˆ ํ†ต๊ณ„

์ดˆ๊ธ‰

ํ•™์Šต ๋ชฉํ‘œ

์ด ๋ ˆ์‹œํ”ผ๋ฅผ ์™„๋ฃŒํ•˜๋ฉด ๋‹ค์Œ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

  • ์ค‘์‹ฌ ๊ฒฝํ–ฅ ์ง€ํ‘œ (ํ‰๊ท , ์ค‘์•™๊ฐ’, ์ตœ๋นˆ๊ฐ’) ๊ณ„์‚ฐ
  • ์‚ฐํฌ๋„ ์ง€ํ‘œ (ํ‘œ์ค€ํŽธ์ฐจ, ๋ถ„์‚ฐ, IQR) ์ดํ•ด
  • ๋ถ„ํฌ ํ˜•ํƒœ ํŒŒ์•… (์™œ๋„, ์ฒจ๋„)
  • Pandas์™€ SQL๋กœ ๊ธฐ์ˆ ํ†ต๊ณ„ ๊ณ„์‚ฐ

0. ์‚ฌ์ „ ์ค€๋น„ (Setup)

๋ฐ์ดํ„ฐ ์‹ค์Šต์„ ์œ„ํ•ด CSV ํŒŒ์ผ์„ ๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค.

import pandas as pd import numpy as np import seaborn as sns import matplotlib.pyplot as plt from scipy import stats # Load Data orders = pd.read_csv('src_orders.csv', parse_dates=['created_at']) items = pd.read_csv('src_order_items.csv') products = pd.read_csv('src_products.csv') users = pd.read_csv('src_users.csv') # Merge for Analysis df = orders.merge(items, on='order_id').merge(products, on='product_id').merge(users, on='user_id')

1. ์ค‘์‹ฌ ๊ฒฝํ–ฅ ์ธก์ •

์ด๋ก 

์ค‘์‹ฌ ๊ฒฝํ–ฅ(Central Tendency)์€ ๋ฐ์ดํ„ฐ๊ฐ€ ์–ด๋””์— ๋ชจ์—ฌ์žˆ๋Š”์ง€๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

์ง€ํ‘œ์„ค๋ช…์žฅ์ ๋‹จ์ 
ํ‰๊ท (Mean)๋ชจ๋“  ๊ฐ’์˜ ํ•ฉ รท ๊ฐœ์ˆ˜๋ชจ๋“  ๋ฐ์ดํ„ฐ ๋ฐ˜์˜์ด์ƒ์น˜์— ๋ฏผ๊ฐ
์ค‘์•™๊ฐ’(Median)์ •๋ ฌ ํ›„ ์ค‘๊ฐ„๊ฐ’์ด์ƒ์น˜์— ๊ฐ•๊ฑด๋ถ„ํฌ ๊ผฌ๋ฆฌ ๋ฌด์‹œ
์ตœ๋นˆ๊ฐ’(Mode)๊ฐ€์žฅ ๋นˆ๋ฒˆํ•œ ๊ฐ’๋ฒ”์ฃผํ˜•์— ์œ ์šฉ์œ ์ผํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Œ

Pandas๋กœ ๊ณ„์‚ฐ

import pandas as pd import numpy as np # ๊ธฐ๋ณธ ํ†ต๊ณ„ print("=== ์ค‘์‹ฌ ๊ฒฝํ–ฅ ===") print(f"ํ‰๊ท : ${df['sale_price'].mean():.2f}") print(f"์ค‘์•™๊ฐ’: ${df['sale_price'].median():.2f}") print(f"์ตœ๋นˆ๊ฐ’: ${df['sale_price'].mode()[0]:.2f}") # describe()๋กœ ํ•œ๋ฒˆ์— print("\n=== describe() ===") print(df['sale_price'].describe())
์‹คํ–‰ ๊ฒฐ๊ณผ
=== ์ค‘์‹ฌ ๊ฒฝํ–ฅ ===
ํ‰๊ท : $59.73
์ค‘์•™๊ฐ’: $39.99
์ตœ๋นˆ๊ฐ’: $25.00

=== describe() ===
count    181026.000000
mean         59.728416
std          67.142661
min           0.020000
25%          24.900000
50%          39.990002
75%          69.949997
max         999.000000
Name: sale_price, dtype: float64

SQL๋กœ ๊ณ„์‚ฐ

SELECT AVG(sale_price) as mean_price, PERCENTILE_CONT(sale_price, 0.5) OVER() as median_price, MIN(sale_price) as min_price, MAX(sale_price) as max_price FROM src_order_items

2. ์‚ฐํฌ๋„ ์ธก์ •

์ด๋ก 

์‚ฐํฌ๋„(Dispersion)๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์–ผ๋งˆ๋‚˜ ํผ์ ธ์žˆ๋Š”์ง€๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

์ง€ํ‘œ์„ค๋ช…๊ณต์‹
๋ฒ”์œ„(Range)์ตœ๋Œ€ - ์ตœ์†Œmax - min
๋ถ„์‚ฐ(Variance)ํ‰๊ท ๊ณผ์˜ ์ฐจ์ด ์ œ๊ณฑ์˜ ํ‰๊ท ฮฃ(x-ฮผ)ยฒ / n
ํ‘œ์ค€ํŽธ์ฐจ(SD)๋ถ„์‚ฐ์˜ ์ œ๊ณฑ๊ทผโˆšVariance
IQRQ3 - Q175% - 25%
๋ณ€๋™๊ณ„์ˆ˜(CV)์ƒ๋Œ€์  ๋ณ€๋™SD / Mean ร— 100%

Pandas๋กœ ๊ณ„์‚ฐ

print("=== ์‚ฐํฌ๋„ ===") print(f"๋ฒ”์œ„: {df['sale_price'].max() - df['sale_price'].min():.2f}") print(f"๋ถ„์‚ฐ: {df['sale_price'].var():.2f}") print(f"ํ‘œ์ค€ํŽธ์ฐจ: {df['sale_price'].std():.2f}") print(f"IQR: {df['sale_price'].quantile(0.75) - df['sale_price'].quantile(0.25):.2f}") print(f"๋ณ€๋™๊ณ„์ˆ˜: {df['sale_price'].std() / df['sale_price'].mean() * 100:.1f}%")
์‹คํ–‰ ๊ฒฐ๊ณผ
=== ์‚ฐํฌ๋„ ===
๋ฒ”์œ„: 998.98
๋ถ„์‚ฐ: 4508.14
ํ‘œ์ค€ํŽธ์ฐจ: 67.14
IQR: 45.05
๋ณ€๋™๊ณ„์ˆ˜: 112.4%

๋ณ€๋™๊ณ„์ˆ˜ ํ™œ์šฉ

# ๋‹จ์œ„๊ฐ€ ๋‹ค๋ฅธ ๋ณ€์ˆ˜ ๋น„๊ต cv_price = df['sale_price'].std() / df['sale_price'].mean() * 100 cv_age = df['age'].std() / df['age'].mean() * 100 print(f"๊ฐ€๊ฒฉ ๋ณ€๋™๊ณ„์ˆ˜: {cv_price:.1f}%") print(f"๋‚˜์ด ๋ณ€๋™๊ณ„์ˆ˜: {cv_age:.1f}%") # ๋ณ€๋™๊ณ„์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ƒ๋Œ€์ ์œผ๋กœ ๋” ํผ์ ธ์žˆ์Œ
์‹คํ–‰ ๊ฒฐ๊ณผ
๊ฐ€๊ฒฉ ๋ณ€๋™๊ณ„์ˆ˜: 112.4%
๋‚˜์ด ๋ณ€๋™๊ณ„์ˆ˜: 41.6%

3. ๋ถ„ํฌ ํ˜•ํƒœ

์™œ๋„ (Skewness)

์™œ๋„๋Š” ๋ถ„ํฌ์˜ ๋น„๋Œ€์นญ์„ฑ์„ ์ธก์ •ํ•ฉ๋‹ˆ๋‹ค.

  • ์™œ๋„ = 0: ๋Œ€์นญ ๋ถ„ํฌ
  • ์™œ๋„ > 0: ์˜ค๋ฅธ์ชฝ ๊ผฌ๋ฆฌ (์–‘์˜ ์™œ๋„)
  • ์™œ๋„ < 0: ์™ผ์ชฝ ๊ผฌ๋ฆฌ (์Œ์˜ ์™œ๋„)
from scipy import stats skewness = stats.skew(df['sale_price'].dropna()) print(f"์™œ๋„: {skewness:.3f}") if skewness > 0.5: print("โ†’ ์˜ค๋ฅธ์ชฝ์œผ๋กœ ์น˜์šฐ์นจ (๊ณ ๊ฐ€ ์ œํ’ˆ์ด ์ผ๋ถ€ ์žˆ์Œ)") elif skewness < -0.5: print("โ†’ ์™ผ์ชฝ์œผ๋กœ ์น˜์šฐ์นจ") else: print("โ†’ ๋Œ€์นญ์— ๊ฐ€๊นŒ์›€")
์‹คํ–‰ ๊ฒฐ๊ณผ
์™œ๋„: 5.062
โ†’ ์˜ค๋ฅธ์ชฝ์œผ๋กœ ์น˜์šฐ์นจ (๊ณ ๊ฐ€ ์ œํ’ˆ์ด ์ผ๋ถ€ ์žˆ์Œ)

์ฒจ๋„ (Kurtosis)

์ฒจ๋„๋Š” ๋ถ„ํฌ์˜ ๋พฐ์กฑํ•œ ์ •๋„๋ฅผ ์ธก์ •ํ•ฉ๋‹ˆ๋‹ค.

  • ์ฒจ๋„ = 0: ์ •๊ทœ๋ถ„ํฌ์™€ ์œ ์‚ฌ
  • ์ฒจ๋„ > 0: ๋” ๋พฐ์กฑํ•จ (๊ทน๋‹จ๊ฐ’ ๋งŽ์Œ)
  • ์ฒจ๋„ < 0: ๋” ํ‰ํ‰ํ•จ
kurtosis = stats.kurtosis(df['sale_price'].dropna()) print(f"์ฒจ๋„: {kurtosis:.3f}")
์‹คํ–‰ ๊ฒฐ๊ณผ
์ฒจ๋„: 45.596

4. ๊ทธ๋ฃน๋ณ„ ๊ธฐ์ˆ ํ†ต๊ณ„

Pandas groupby + agg

# ๋ถ€์„œ๋ณ„ ๊ธฐ์ˆ ํ†ต๊ณ„ dept_stats = df.groupby('department')['sale_price'].agg([ ('๊ฐœ์ˆ˜', 'count'), ('ํ‰๊ท ', 'mean'), ('์ค‘์•™๊ฐ’', 'median'), ('ํ‘œ์ค€ํŽธ์ฐจ', 'std'), ('์ตœ์†Œ', 'min'), ('์ตœ๋Œ€', 'max') ]).round(2) print("๋ถ€์„œ๋ณ„ ๊ฐ€๊ฒฉ ํ†ต๊ณ„:") print(dept_stats)
์‹คํ–‰ ๊ฒฐ๊ณผ
๋ถ€์„œ๋ณ„ ๊ฐ€๊ฒฉ ํ†ต๊ณ„:
             ๊ฐœ์ˆ˜  ...     ์ตœ๋Œ€
department         ...       
Men         90612  ...  999.0
Women       90414  ...  903.0

[2 rows x 6 columns]

SQL๋กœ ๊ทธ๋ฃน๋ณ„ ํ†ต๊ณ„

SELECT department, COUNT(*) as count, AVG(sale_price) as mean, STDDEV(sale_price) as std, MIN(sale_price) as min, MAX(sale_price) as max FROM src_order_items oi JOIN src_products p ON oi.product_id = p.product_id GROUP BY department ORDER BY mean DESC

ํ€ด์ฆˆ 1: ๊ธฐ์ˆ ํ†ต๊ณ„ ๊ณ„์‚ฐ

๋ฌธ์ œ

์ฃผ๋ฌธ ๋ฐ์ดํ„ฐ์—์„œ ์ฃผ๋ฌธ๋‹น ์•„์ดํ…œ ์ˆ˜(num_of_item)์— ๋Œ€ํ•ด:

  1. ํ‰๊ท , ์ค‘์•™๊ฐ’, ํ‘œ์ค€ํŽธ์ฐจ ๊ณ„์‚ฐ
  2. ํ‰๊ท ๊ณผ ์ค‘์•™๊ฐ’์˜ ์ฐจ์ด ํ•ด์„
  3. ๋ณ€๋™๊ณ„์ˆ˜ ๊ณ„์‚ฐ

์ •๋‹ต ๋ณด๊ธฐ

# 1. ๊ธฐ๋ณธ ํ†ต๊ณ„ mean_items = df['num_of_item'].mean() median_items = df['num_of_item'].median() std_items = df['num_of_item'].std() print(f"ํ‰๊ท : {mean_items:.2f}") print(f"์ค‘์•™๊ฐ’: {median_items:.2f}") print(f"ํ‘œ์ค€ํŽธ์ฐจ: {std_items:.2f}") # 2. ํ•ด์„ if mean_items > median_items: print("\nโ†’ ํ‰๊ท  > ์ค‘์•™๊ฐ’: ์˜ค๋ฅธ์ชฝ ๊ผฌ๋ฆฌ ๋ถ„ํฌ (๋Œ€๋Ÿ‰ ์ฃผ๋ฌธ์ด ์ผ๋ถ€ ์žˆ์Œ)") elif mean_items < median_items: print("\nโ†’ ํ‰๊ท  < ์ค‘์•™๊ฐ’: ์™ผ์ชฝ ๊ผฌ๋ฆฌ ๋ถ„ํฌ") else: print("\nโ†’ ๋Œ€์นญ ๋ถ„ํฌ") # 3. ๋ณ€๋™๊ณ„์ˆ˜ cv = std_items / mean_items * 100 print(f"\n๋ณ€๋™๊ณ„์ˆ˜: {cv:.1f}%")
์‹คํ–‰ ๊ฒฐ๊ณผ
ํ‰๊ท : 1.89
์ค‘์•™๊ฐ’: 2.00
ํ‘œ์ค€ํŽธ์ฐจ: 1.06

โ†’ ํ‰๊ท  < ์ค‘์•™๊ฐ’: ์™ผ์ชฝ ๊ผฌ๋ฆฌ ๋ถ„ํฌ

๋ณ€๋™๊ณ„์ˆ˜: 55.9%

์ •๋ฆฌ

ํ•ต์‹ฌ ํ•จ์ˆ˜ ์š”์•ฝ

ํ†ต๊ณ„๋Ÿ‰PandasSQL
ํ‰๊ท df['col'].mean()AVG(col)
์ค‘์•™๊ฐ’df['col'].median()PERCENTILE_CONT(col, 0.5)
ํ‘œ์ค€ํŽธ์ฐจdf['col'].std()STDDEV(col)
๋ถ„์‚ฐdf['col'].var()VARIANCE(col)
์ตœ์†Œ/์ตœ๋Œ€min(), max()MIN(), MAX()
๋ฐฑ๋ถ„์œ„์ˆ˜quantile(0.25)PERCENTILE_CONT(col, 0.25)

ํ†ต๊ณ„๋Ÿ‰ ์„ ํƒ ๊ฐ€์ด๋“œ

์ƒํ™ฉ์ถ”์ฒœ
์ด์ƒ์น˜ ์—†์Œํ‰๊ท , ํ‘œ์ค€ํŽธ์ฐจ
์ด์ƒ์น˜ ์žˆ์Œ์ค‘์•™๊ฐ’, IQR
๋ถ„ํฌ ๋น„๊ต๋ณ€๋™๊ณ„์ˆ˜
๋น„๋Œ€์นญ ํ™•์ธ์™œ๋„

๋‹ค์Œ ๋‹จ๊ณ„

๊ธฐ์ˆ ํ†ต๊ณ„๋ฅผ ๋งˆ์Šคํ„ฐํ–ˆ์Šต๋‹ˆ๋‹ค! ๋‹ค์Œ์œผ๋กœ ์ƒ๊ด€๊ด€๊ณ„ ๋ถ„์„์—์„œ ๋ณ€์ˆ˜ ๊ฐ„ ๊ด€๊ณ„๋ฅผ ๋ถ„์„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ฐฐ์›Œ๋ณด์„ธ์š”.

Last updated on

๐Ÿค–AI Mock InterviewPractice with real questions