" 결과 ⊂ 사건 ⊂ 표본공간 "
관계 정리
" 확률 "
계산
특징
유형
실무 사례
" 기댓값 "


" 조건부 확률 "



실무 사례
사례
" 이론적 확률분포 "
종류
특징
" 정규분포 "
역할
서로 다른 스케일의 데이터를 정규분포에서 비교 시
역할
서로 다른 스케일의 데이터를 표준정규분포에서 비교 시
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
# 모집단 평균과 표준편차 가정 (예시)
mean_m, std_m = 175, 7 # 남성 평균, 표준편차
mean_f, std_f = 162, 6 # 여성 평균, 표준편차
# 키값 예시
heights_m = [180]
heights_f = [161]
# x축 범위
x_m = np.linspace(mean_m - 4*std_m, mean_m + 4*std_m, 500)
x_f = np.linspace(mean_f - 4*std_f, mean_f + 4*std_f, 500)
# 정규분포 확률밀도
pdf_m = norm.pdf(x_m, mean_m, std_m)
pdf_f = norm.pdf(x_f, mean_f, std_f)
# 시각화
fig=plt.figure(figsize=(12,8), facecolor='k')
ax= fig.add_subplot()
ax.patch.set_facecolor('k')
plt.plot(x_m, pdf_m, label="남성 분포", color='skyblue')
plt.plot(x_f, pdf_f, label="여성 분포", color='pink')
# z-score 계산 및 표시
for h in heights_m:
z = (h - mean_m) / std_m
plt.scatter(h, norm.pdf(h, mean_m, std_m), color='purple')
plt.text(h, norm.pdf(h, mean_m, std_m)+0.002, f'{h}cm\n(z={z:.2f})', ha='center', color='w')
for h in heights_f:
z = (h - mean_f) / std_f
plt.scatter(h, norm.pdf(h, mean_f, std_f), color='cyan')
plt.text(h, norm.pdf(h, mean_f, std_f)+0.002, f'{h}cm\n(z={z:.2f})', ha='center', color='w')
ax.set_title('남성과 여성 키 분포와 z값 비교', color='w')
ax.set_xlabel('키 (cm)', color='w')
ax.set_ylabel('확률밀도', color='w')
plt.legend()
ax.tick_params(colors='w')
ax.spines['bottom'].set_color('w')
ax.spines['left'].set_color('w')
plt.gca().set_axisbelow(True)
plt.grid(axis='x', alpha=0.3, color='lightgray')
plt.show()
# --- 표준정규분포 ---
# z = (x - mean) / std
z_m = (x_m - mean_m) / std_m
z_f = (x_f - mean_f) / std_f
fig=plt.figure(figsize=(12,8), facecolor='k')
ax= fig.add_subplot()
ax.patch.set_facecolor('k')
plt.plot(z_m, pdf_m, label="남성 표준정규분포", color='skyblue')
plt.plot(z_f, pdf_f, label="여성 표준정규분포", color='pink')
# z-score 표시
for h in heights_m:
z = (h - mean_m) / std_m
plt.scatter(z, norm.pdf(h, mean_m, std_m), color='pink')
plt.text(z, norm.pdf(h, mean_m, std_m)+0.002, f'{h}cm\n(z={z:.2f})', ha='center', color='w')
for h in heights_f:
z = (h - mean_f) / std_f
plt.scatter(z, norm.pdf(h, mean_f, std_f), color='cyan')
plt.text(z, norm.pdf(h, mean_f, std_f)+0.002, f'{h}cm\n(z={z:.2f})', ha='center', color='w')
ax.set_title('남성과 여성 키 표준정규분포와 z값 비교', color='w')
ax.set_xlabel('z-score', color='w')
ax.set_ylabel('확률밀도', color='w')
plt.legend()
ax.tick_params(colors='w')
ax.spines['bottom'].set_color('w')
ax.spines['left'].set_color('w')
plt.gca().set_axisbelow(True)
plt.grid(axis='x', alpha=0.3, color='lightgray')
plt.show()
![]() |
![]() |

특징

특징
" 68-95-99.7 법칙 "
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
# 일반 정규분포 평균과 표준편차
mu, sigma = 175, 7
# x 범위
x = np.linspace(mu - 4*sigma, mu + 4*sigma, 1000)
# 정규분포 pdf
pdf = norm.pdf(x, mu, sigma)
fig=plt.figure(figsize=(8,6), facecolor='k')
ax= fig.add_subplot()
ax.patch.set_facecolor('k')
plt.plot(x, pdf, color='w', label='남성 키 분포')
# 영역 색칠: ±1σ, ±2σ, ±3σ
colors = ['#7FFFD4', '#87CEFA', '#00BFFF']
# 68-95-99.7 범위 색칠
plt.fill_between(x, pdf, 0, where=(x > mu - sigma) & (x < mu + sigma), color=colors[0], alpha=0.7, label='68% 영역')
plt.fill_between(x, pdf, 0, where=(x > mu - 2*sigma) & (x < mu + 2*sigma), color=colors[1], alpha=0.5, label='95% 영역')
plt.fill_between(x, pdf, 0, where=(x > mu - 3*sigma) & (x < mu + 3*sigma), color=colors[2], alpha=0.3, label='99.7% 영역')
ax.set_title('남성 키 분포와 68-95-99.7 법칙', color='w')
ax.set_xlabel('키 (cm)', color='w')
ax.set_ylabel('확률밀도', color='w')
plt.legend()
ax.tick_params(colors='w')
ax.spines['bottom'].set_color('w')
ax.spines['left'].set_color('w')
plt.gca().set_axisbelow(True)
plt.grid(axis='x', alpha=0.3, color='lightgray')
plt.show()
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
import scipy.stats as stats
# 한글 폰트 설정 (Mac용)
plt.rcParams['font.family'] = 'AppleGothic'
# 마이너스 기호 깨짐 방지
mpl.rcParams['axes.unicode_minus'] = False
# 표준정규분포 정의 (평균=0, 표준편차=1)
x = np.linspace(-4, 4, 1000)
y = stats.norm.pdf(x, 0, 1)
# 그래프 그리기
fig=plt.figure(figsize=(8,6), facecolor='k')
ax= fig.add_subplot()
ax.patch.set_facecolor('k')
plt.plot(x, y, color='w')
# 영역 색칠: ±1σ, ±2σ, ±3σ
colors = ['#7FFFD4', '#87CEFA', '#00BFFF']
# ±1σ 영역
plt.fill_between(x, y, where=(x >= -1) & (x <= 1),
color=colors[0], alpha=0.7, label='±1σ ≈ 68%')
# ±2σ 영역
plt.fill_between(x, y, where=(x >= -2) & (x <= 2),
color=colors[1], alpha=0.5, label='±2σ ≈ 95%')
# ±3σ 영역
plt.fill_between(x, y, where=(x >= -3) & (x <= 3),
color=colors[2], alpha=0.3, label='±3σ ≈ 99.7%')
# 그래프 꾸미기
ax.set_title('표준정규분포와 68-95-99.7 법칙', color='w')
ax.set_xlabel('z 값 (표준화 점수)', color='w')
ax.set_ylabel('확률밀도', color='w')
plt.legend()
ax.tick_params(colors='w')
ax.spines['bottom'].set_color('w')
ax.spines['left'].set_color('w')
plt.gca().set_axisbelow(True)
plt.grid(axis='x', alpha=0.3, color='lightgray')
plt.show()
![]() |
![]() |
" 정규 근사, 정규 경계 "
" 예언구간, 신뢰구간 "
특징
계산

특징
계산

예시
def coverage_experiment(series, n=25, reps=400, alpha=0.05, seed=7):
# n = 표본 크기(개수)
# reps = 실험을 몇번 반복할지?
# alpha = 유의수준 (0.5면 95% 신뢰구간)
rng = np.random.default_rng(seed) # PCG64 라는 알고리즘을 쓰는 난수 생성기, 최근 더 안정적이고 빠르다고 인정받는 최신 알고리즘
mu_true = series.mean()
intervals = []
hits = 0
for i in range(reps):
idx = rng.integers(0, len(series), size=n)
smp = series.to_numpy()[idx]
lo, hi, *_ = ci_for_mean_t(smp, alpha=alpha)
intervals.append((lo, hi))
hits += int(lo <= mu_true <= hi)
return mu_true, intervals, hits / reps
mu_true, intervals, cov = coverage_experiment(df["target"], n=25, reps=400, alpha=0.05, seed=11)
fig = plt.figure(figsize=(12,8), facecolor='k')
ax = fig.add_subplot()
ax.patch.set_facecolor('k')
k = 40
for i, (lo_i, hi_i) in enumerate(intervals[:k]):
if lo_i <= mu_true <= hi_i:
color = 'skyblue' # 포함되는 경우 파란색
else:
color = '#CD5C5C' # 포함되지 않는 경우 빨간색
plt.plot([lo_i, hi_i], [i, i], marker="|", color=color, markersize=10)
plt.axvline(mu_true, linestyle="--", color='lightgreen', alpha=0.7)
ax.set_title(f"Coverage experiment (first {k} CIs), estimated coverage≈{cov:.3f}", color='w')
ax.set_xlabel('target', color='w')
ax.set_ylabel('sample index', color='w')
ax.tick_params(colors='w')
ax.spines['bottom'].set_color('w')
ax.spines['left'].set_color('w')
plt.show()

표본의 무작위성, 대표성, 독립성이 보장되지 않으면 추정은 왜곡된다
" 표본오차, 표준오차 "
계산
표본이 크면 표본오차는 줄고, 표준오차는 작아지고, 신뢰구간이 좁아짐
def avg_ci_width_vs_n(series, ns=(10, 20, 30, 50, 100, 200), reps=300, seed=2024):
rng = np.random.default_rng(seed)
widths = []
for n in ns:
ws = []
for _ in range(reps):
idx = rng.integers(0, len(series), size=n) # 0부터 len(series)-1까지 정수 중에서 n개를 복원 추출 -> 즉 series에서 n개의 임의 표본을 뽑음
smp = series.to_numpy()[idx]
lo, hi, *_ = ci_for_mean_t(smp)
ws.append(hi - lo)
widths.append(np.mean(ws))
return np.array(ns), np.array(widths)
ns, widths = avg_ci_width_vs_n(df["target"], ns=(10, 20, 30, 50, 100, 200), reps=200)
fig = plt.figure(figsize=(8,6), facecolor='k')
ax = fig.add_subplot()
ax.patch.set_facecolor('k')
plt.plot(ns, widths, marker="o", color='#7FFFD4', markerfacecolor='#87CEFA')
ax.set_title("CI width vs n (real data resampling)", color='w')
ax.set_xlabel('sample size n', color='w')
ax.set_ylabel('Average 95% CI width', color='w')
ax.tick_params(colors='w')
ax.spines['bottom'].set_color('w')
ax.spines['left'].set_color('w')
plt.gca().set_axisbelow(True)
plt.grid(axis='y', color = 'lightgray', linewidth = 0.3)
plt.show()

1빠 마초녀의 벨로그는 계속된다