๐ก ํต์ฌ : CI๋ PI๋ฅผ ๊ณ์ฐํด์ ์ธก์
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_diabetes # ๋น๋จ๋ณ ์์ธก
import scipy.stats as st
#from pathlib import Path
np.random.seed(42)
data = load_diabetes(as_frame=True)
df = data.frame.copy()
df
def ci_for_mean_t(sample, alpha=0.05):
n = len(sample)
xbar = np.mean(sample) # ํ๋ณธ ํ๊ท
s = np.std(sample, ddof=1) # ํ๋ณธ ํ์คํธ์ฐจ๋ฅผ ๊ณ์ฐํ๊ธฐ ์ํด์ ์์ ๋๋ฅผ n-1๋ก ๋์ด์ผ ํ๊ธฐ ๋๋ฌธ์ ddof = 1
se = s / np.sqrt(n) # ํ์ค์ค์ฐจ
tcrit = st.t.ppf(1 - alpha / 2, df=n-1) # t๋ถํฌ์ ๊ฐ ์ฐพ๊ธฐ. ์ ์ฒด ๋ฉด์ ์ค ํน์ ๋น์จ์ ์ฐจ์งํ๋ ์ง์
low, high = xbar - tcrit * se, xbar + tcrit * se # ์ ๋ขฐ๊ตฌ๊ฐ์ ํํ๊ณผ ์ํ ๊ณ์ฐ
return low, high, xbar, s, se, tcrit
# ์์ ํ๋ณธ ๋ฝ์๋ณด๊ธฐ
n = 20
sample = df["target"].sample(n=n, replace=True, random_state=7).to_numpy() # replace : ๋์ผํ ๊ฐ ๋ฝ๊ฒ ํ ๊ฑฐ๋?
low, high, xbar, s, se, tcrit = ci_for_mean_t(sample)
true_mu = df["target"].mean()
ci_summary = pd.DataFrame({
"n": [n],
"sample_mean": [xbar],
"sample_sd": [s],
"SE": [se],
"t* (0.975, df=n-1)": [tcrit],
"CI_low": [low],
"CI_high": [high],
"contains_true_mu?": [bool(low <= true_mu <= high)],
"true_mu (from full data)": [true_mu]
})
ci_summary

st.t.ppf(q, df)
spicy.stats ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ t๊ฐ ๊ตฌํ๋ ํจ์.
๊ฐ์ค ๊ฒ์ ์ด๋ ์ ๋ขฐ ๊ตฌ๊ฐ์ ๊ณ์ฐํ ๋ ํน์ ์ ์ ์์ค์ (ex. 5%) ํด๋นํ๋ ์๊ณ๊ฐ์ ์ฐพ๊ธฐ ์ํด ์ฌ์ฉ
q : ํด๋น t๊ฐ์ ๊ตฌํ ๋์ ํ๋ฅ . 0~1 ์ฌ์ด.
df : t๋ถํฌ์ ์์ ๋.
1 - alpha / 2 โ alpha๋ ํ๋ผ๋ฏธํฐ์์ 0.05๋ฅผ ์ค์ ํด๋์์ผ๋ฏ๋ก, 0.05 / 2 ๋ 0.025
1 - 0.025 = 0.975
df=n1 โ ํ๋ณธ ํฌ๊ธฐ n์์ ํ๊ท ์ ์ด๋ฏธ ์ผ๊ธฐ ๋๋ฌธ์ ์์ ๋๊ฐ n-1
plt.figure()
plt.axvline(true_mu, linestyle="--", label="True ฮผ (full data)", color="#f69256")
plt.plot([low, high], [0, 0], marker="|", color="#00b3ca")
plt.xlabel("target")
plt.yticks([])
plt.title("95% t-CI for ฮผ (Diabetes target)")
plt.legend()
plt.show()

โ ์ ๋ขฐ๊ตฌ๊ฐ์ ๋น๋ ์ฃผ์์ ์ผ๋ก ํด์ํด์ผ ํจ
โ : ์ด๋ฒ ๊ตฌ๊ฐ์ด ฮผ๋ฅผ 95% ํ๋ฅ ๋ก ํฌํจํ๋ค
โญ : ์ด ์ ์ฐจ๋ก ๋ฐ๋ณตํด ๋ง๋ ๊ตฌ๊ฐ๋ค ์ค ์ฝ 95%๊ฐ ฮผ๋ฅผ ํฌํจํ๋ค
๐ ํต๊ณ์ ์ ๋ขฐ๊ตฌ๊ฐ์ ์ค์ ์ปค๋ฒ๋ฆฌ์ง(coverage)๋ฅผ ์คํ์ ์ผ๋ก ๊ฒ์ฆํ๋ ์๋ฎฌ๋ ์ด์ ํจ์
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]
low, high, *_ = ci_for_mean_t(smp, alpha=alpha)
intervals.append((low, high))
hits += int(low <= mu_true <= high)
return mu_true, intervals, hits / reps
mu_true, intervals, cov = coverage_experiment(df["target"], n=25, reps=400, alpha=0.05, seed=11)
plt.figure()
k = 40
for i, (low_i, high_i) in enumerate(intervals[:k]):
plt.plot([low_i, high_i], [i, i], marker="|")
plt.axvline(mu_true, linestyle="--")
plt.title(f"Coverage experiment (first {k} CIs), estimated coverageโ{cov:.3f}")
plt.xlabel("target")
plt.ylabel("sample index")
plt.show()

๐ ์ ๋ขฐ๊ตฌ๊ฐ์ ํ๊ท ๋๋น๋ฅผ ๊ณ์ฐํ์ฌ, ํ๋ณธ ํฌ๊ธฐ์ ์ ๋ขฐ๊ตฌ๊ฐ ๋๋น ์ฌ์ด์ ๊ด๊ณ ๋ณด์ฌ์ค - ์ด๋ ํต๊ณํ์ ์ค์ํ ์๋ฆฌ์ธ "ํ๋ณธ ํฌ๊ธฐ๊ฐ ์ปค์ง์๋ก ์ ๋ขฐ๊ตฌ๊ฐ์ ๋๋น๊ฐ ์ข์์ง๋ค"๋ ๊ฐ๋ ์ ๊ฒ์ฆ