모평균의 신뢰구간

단원 04 통계적 추정 · 「확률과 통계」 · 1차시(45분)

개념

모표준편차 \(\sigma\)를 아는 정규 모집단에서 크기 \(n\)인 표본을 뽑았을 때, 모평균 \(m\)신뢰구간은 표본평균 \(\bar{x}\) 주위로 다음과 같이 만듭니다.

\[\bar{x} - z\frac{\sigma}{\sqrt{n}} \;\le\; m \;\le\; \bar{x} + z\frac{\sigma}{\sqrt{n}} \qquad (z = 1.645,\ 1.96,\ 2.576)\]

구간의 폭은 \(2z\dfrac{\sigma}{\sqrt{n}}\)입니다. \(n\)을 4배로 하면 \(\sqrt{n}\)이 2배가 되어 폭이 절반으로 줄어듭니다.

신뢰수준 95%의 뜻에 주의해야 합니다. “이 구간에 \(m\)이 있을 확률이 95%”가 아니라, 같은 방법으로 조사를 반복하면 만들어지는 구간들 중 약 95%가 \(m\)을 포함한다는 뜻입니다. 아래 앱은 (우리만 모르는) 진짜 모평균을 두고 100번 조사를 반복해 이 뜻을 눈으로 보여 줍니다. \(m\)을 놓친 구간이 평균적으로 몇 개쯤 나오는지 세어 보세요.

만지며 배우기

#| '!! shinylive warning !!': |
#|   shinylive does not work in self-contained HTML documents.
#|   Please set `embed-resources: false` in your metadata.
#| standalone: true
#| viewerHeight: 640

# matplotlib·numpy 없이 stdlib + 인라인 SVG 로만 그린다
import random
from math import sqrt
from shiny import App, reactive, render, ui

ACCENT = "#2563eb"
INK = "#111827"
MUTED = "#6b7280"

M, SIGMA = 70, 10          # 진짜 모평균(조사자는 모른다고 가정)
Z = {"90": 1.645, "95": 1.96, "99": 2.576}

def ci_svg(intervals):
    W, H, ml, mr, mt, mb = 470, 320, 16, 16, 10, 26
    pw, ph = W - ml - mr, H - mt - mb
    xmin = min(lo for lo, hi in intervals)
    xmax = max(hi for lo, hi in intervals)
    pad = (xmax - xmin) * 0.05 or 1.0
    xmin, xmax = xmin - pad, xmax + pad
    def X(v):
        return ml + ((v - xmin) / (xmax - xmin)) * pw
    N = len(intervals)
    body = ""
    for k, (lo, hi) in enumerate(intervals):
        y = mt + (k + 0.5) * (ph / N)
        hit = lo <= M <= hi
        col = "#9ca3af" if hit else ACCENT
        w = 1 if hit else 2.2
        body += (f'<line x1="{X(lo):.1f}" y1="{y:.1f}" x2="{X(hi):.1f}" '
                 f'y2="{y:.1f}" stroke="{col}" stroke-width="{w}"/>')
    body += (f'<line x1="{X(M):.1f}" y1="{mt}" x2="{X(M):.1f}" y2="{mt+ph}" '
             f'stroke="{INK}" stroke-width="1" stroke-dasharray="5 3"/>'
             f'<text x="{X(M):.1f}" y="{mt+ph+16:.0f}" font-size="10" fill="{INK}" '
             f'text-anchor="middle">m = {M}</text>')
    return (f'<svg viewBox="0 0 {W} {H}" style="width:100%;height:auto;'
            f'font-family:-apple-system,sans-serif;">{body}</svg>')

app_ui = ui.page_sidebar(
    ui.sidebar(
        ui.input_slider("n", "표본 크기 n", min=10, max=100, value=25, step=10),
        ui.input_select("level", "신뢰수준", {"90": "90%", "95": "95%", "99": "99%"}),
        ui.input_action_button("redraw", "새로 100번 조사"),
        width=240,
    ),
    ui.card(
        ui.card_header("100개의 신뢰구간 — 모평균을 놓친 구간은 파랑"),
        ui.output_ui("ci_plot"),
    ),
    ui.card(ui.output_ui("readout")),
    fillable=True,
)

def server(input, output, session):
    @reactive.calc
    def intervals():
        input.redraw()  # 버튼을 누르면 새로 100번 조사
        n = input.n()
        z = Z[input.level()]
        half = z * SIGMA / sqrt(n)
        out = []
        for _ in range(100):
            xbar = sum(random.gauss(M, SIGMA) for _ in range(n)) / n
            out.append((xbar - half, xbar + half))
        return out

    @render.ui
    def ci_plot():
        return ui.HTML(ci_svg(intervals()))

    @render.ui
    def readout():
        ivs = intervals()
        hits = sum(1 for lo, hi in ivs if lo <= M <= hi)
        return ui.HTML(
            f'<p class="hs-readline">'
            f"이번 100번의 조사 중 <b>{hits}개</b> 구간이 모평균 m을 포함했습니다. "
            f"신뢰수준 {input.level()}%의 뜻: 같은 방법으로 반복하면 약 "
            f"{input.level()}%의 구간이 모평균을 포함한다 — 특정 구간 하나가 "
            f"맞을 확률이 {input.level()}%라는 뜻이 아닙니다. "
            f"신뢰수준을 높이거나 n을 줄이면 구간은 넓어집니다.</p>"
        )

app = App(app_ui, server)

신뢰구간 계산은 공식 그대로 몇 줄이면 충분합니다.

import random
from math import sqrt

sigma, n, z = 10, 25, 1.96          # σ를 아는 경우, 95% → z = 1.96

sample = [random.gauss(70, sigma) for _ in range(n)]   # 조사 한 번
xbar = sum(sample) / n

half = z * sigma / sqrt(n)                # 오차의 한계
print(xbar - half, xbar + half)           # 95% 신뢰구간 [x̄−1.96σ/√n, x̄+1.96σ/√n]

스스로 확인

구간이 넓어지고(\(z\)\(1.645 \to 2.576\)), 모평균을 놓치는 파란 구간이 줄어듭니다(평균 10개 → 1개). 더 확실하게 잡으려면 더 넓게 던져야 한다는 맞바꿈 관계입니다.

폭은 \(2z\sigma/\sqrt{n}\)이므로 \(n\)이 4배가 되면 폭은 절반이 됩니다. 95% 기준으로 \(2 \times 1.96 \times 10/\sqrt{25} = 7.84\)에서 \(2 \times 1.96 \times 10/\sqrt{100} = 3.92\)로 줄어듭니다. 정밀도를 2배 높이려면 조사 인원은 4배 필요합니다.