1 포아송 분포란 무엇인가
포아송 분포(Poisson Distribution)는 일정한 시간·공간 구간에서 발생하는 희귀 사건의 횟수를 모형화하는 분포이다. 시메옹 드니 포아송(Simeon Denis Poisson, 1781–1840)의 이름을 딴 이 분포는 카운트 데이터의 자연스러운 모형이다.
포아송 분포가 등장하는 전형적인 질문:
- 1시간 동안 콜센터에 걸려오는 전화는 몇 건인가?
- 1페이지에 인쇄 오류가 몇 개인가?
- 1년 동안 특정 교차로에서 교통사고가 몇 건 발생하는가?
- 웹 서버에 1초 동안 도착하는 요청은 몇 개인가?
이 모든 질문의 공통점: (1) 사건이 독립적으로 발생하고, (2) 단위 구간에서의 평균 발생률이 일정하며, (3) 동시 발생이 무시할 수 있을 정도로 드물다.
2 정의
확률변수 \(X\) 가 포아송 \((\lambda)\) 분포를 따르면:
\[ P(X = x \mid \lambda) = \frac{e^{-\lambda}\lambda^x}{x!}, \quad x = 0, 1, 2, \ldots \]
\(\lambda > 0\) 은 강도 모수(intensity parameter)로, 단위 시간(또는 공간)당 평균 발생 횟수이다 (Casella & Berger, 2002, Ch.3).
\(\lambda^x\): 평균 \(\lambda\) 번 발생하는 사건이 \(x\) 번 일어날 “원시 확률 척도”이다. 발생률이 \(\lambda\) 인 환경에서 \(x\) 번 발생할 가능성의 크기를 나타낸다.
\(e^{-\lambda}\): 모든 \(x\) 에 대한 확률의 합이 1이 되도록 정규화하는 인수이다. \(\sum_{x=0}^{\infty} \lambda^x/x! = e^{\lambda}\) 이므로, 역수 \(e^{-\lambda}\) 를 곱하면 전체 합이 1로 맞춰진다.
\(x!\): 사건이 일어나는 순서가 중요하지 않아 중복 계산을 제거하는 값이다. 3개의 사건이 순서 없이 \(x\) 번 발생하는 것은 \(x!\) 가지 순서 배열을 하나로 묶은 것이다.
항을 하나씩 제거하면:
- \(e^{-\lambda}\) 가 없으면: 모든 \(x\) 에 대한 확률의 합이 \(e^{\lambda} \neq 1\) 이 되어 확률 분포가 아니다.
- \(x!\) 가 없으면: 같은 사건의 다른 순서를 별개로 계산하여 확률이 부풀어 오른다.
- \(\lambda^x\) 가 없으면: 발생 빈도와 무관한 상수 분포가 되어 \(\lambda\) 의 의미가 사라진다.
2.1 정규화 확인
테일러 급수 \(e^{\lambda} = \sum_{x=0}^{\infty} \frac{\lambda^x}{x!}\) 에 의해:
\[ \sum_{x=0}^{\infty} \frac{e^{-\lambda}\lambda^x}{x!} = e^{-\lambda} \sum_{x=0}^{\infty} \frac{\lambda^x}{x!} = e^{-\lambda} \cdot e^{\lambda} = 1 \quad \checkmark \]
2.2 표본공간
이항 분포가 \(\{0, 1, \ldots, n\}\) 으로 유한한 반면, 포아송 분포의 표본공간은 \(\{0, 1, 2, \ldots\}\) 로 무한이다. 이론적으로 발생 횟수에 상한이 없다.
3 포아송 과정의 공리
포아송 분포는 다음 세 가지 공리를 만족하는 확률 과정(Poisson process)에서 자연스럽게 도출된다.
시간 \([0, t]\) 에서 발생하는 사건의 수 \(N(t)\) 에 대해:
- 독립 증분: 겹치지 않는 시간 구간의 사건 수는 독립이다
- 정상성: 사건 수의 분포는 구간의 위치가 아닌 길이에만 의존한다
- 희소성: 매우 짧은 구간 \(\Delta t\) 에서 2건 이상 발생할 확률은 \(o(\Delta t)\) 이다
이 세 공리 하에서 \(N(t) \sim \text{Poisson}(\lambda t)\) 이다.
직관: 시간을 \(n\) 개의 아주 짧은 구간으로 나누면, 각 구간에서 사건이 발생할 확률은 \(p = \lambda t/n\) 으로 매우 작고, 각 구간은 독립적인 베르누이 시행이 된다. 따라서 총 발생 수는 \(\text{Binomial}(n, \lambda t/n)\) 을 따르고, \(n \to \infty\) 에서 포아송 \((\lambda t)\) 으로 수렴한다.
4 평균과 분산: 등산포 (Equidispersion)
4.1 기대값
\[ E[X] = \sum_{x=0}^{\infty} x \cdot \frac{e^{-\lambda}\lambda^x}{x!} = \sum_{x=1}^{\infty} \frac{e^{-\lambda}\lambda^x}{(x-1)!} \]
\(y = x - 1\) 로 치환하면:
\[ E[X] = \lambda e^{-\lambda} \sum_{y=0}^{\infty} \frac{\lambda^y}{y!} = \lambda e^{-\lambda} \cdot e^{\lambda} = \lambda \]
4.2 분산
\(E[X(X-1)]\) 을 먼저 구한다:
\[ E[X(X-1)] = \sum_{x=2}^{\infty} x(x-1) \cdot \frac{e^{-\lambda}\lambda^x}{x!} = \lambda^2 e^{-\lambda} \sum_{y=0}^{\infty} \frac{\lambda^y}{y!} = \lambda^2 \]
\[ \text{Var}(X) = E[X(X-1)] + E[X] - (E[X])^2 = \lambda^2 + \lambda - \lambda^2 = \lambda \]
4.3 등산포의 의미
\[ \boxed{E[X] = \text{Var}(X) = \lambda} \]
포아송 분포는 이항 \(\text{Binomial}(n, p)\) 의 \(n \to \infty\), \(p \to 0\), \(np = \lambda\) 극한이다.
이항의 분산은 \(np(1-p) = \lambda(1-p)\) 이다. \(p \to 0\) 이면 \((1-p) \to 1\) 이므로 분산이 \(\lambda\) 로 수렴한다.
달리 말하면: 사건이 매우 드물게 발생하는 환경에서는 “성공-실패의 이중성”이 사라진다. 거의 대부분의 시간 구간에서 사건이 발생하지 않으므로, 각 구간이 “실패할 확률”이 1에 가까워진다. 이 희소성의 결과로 분산이 평균과 동일해진다.
실무적 의미: 관측 데이터에서 분산이 평균보다 눈에 띄게 크다면(과산포), 포아송 가정이 위반된 것이다. 이는 사건들이 독립적으로 발생하지 않거나 발생률이 일정하지 않다는 신호이다.
평균과 분산이 동일한 이 성질을 등산포(equidispersion)라 한다. 이 특성은 포아송 분포의 가장 중요한 진단 기준이다.
실제 카운트 데이터에서 \(\text{Var}(X) > E[X]\) (과산포, overdispersion)인 경우가 훨씬 흔하다. 과산포를 무시하고 포아송을 강제하면:
- 표준오차가 과소 추정된다
- 유의하지 않은 효과를 유의하다고 판단하는 제1종 오류가 증가한다
- 신뢰구간이 실제보다 좁아져 거짓 정밀도를 보여준다
과산포 진단: \(\text{분산}/\text{평균}\) 비율(dispersion index)이 1보다 유의하게 크면 음이항 분포나 quasi-Poisson을 사용한다.
5 적률생성함수 (MGF)
\[ M_X(t) = E[e^{tX}] = \sum_{x=0}^{\infty} e^{tx} \cdot \frac{e^{-\lambda}\lambda^x}{x!} = e^{-\lambda} \sum_{x=0}^{\infty} \frac{(\lambda e^t)^x}{x!} = e^{-\lambda} \cdot e^{\lambda e^t} \]
\[ \boxed{M_X(t) = e^{\lambda(e^t - 1)}} \]
지수 함수 안에 또 지수 함수가 있는 이중 지수 형태이다.
\(t = 0\) 대입: \(e^{\lambda(e^0 - 1)} = e^{\lambda \cdot 0} = e^0 = 1\) — 정규화 자동 확인.
\(e^t - 1\) 의 역할: \(t > 0\) 이면 \(e^t > 1\) 이므로 \(e^t - 1 > 0\), 따라서 \(M_X(t) > 1\). 이는 오른쪽 꼬리를 탐색(큰 값 방향으로 분포를 기울임)하는 것에 해당한다.
합의 성질이 이 구조에서 자연스럽게 나온다: 독립인 두 포아송의 MGF를 곱하면 \[e^{\lambda_1(e^t-1)} \cdot e^{\lambda_2(e^t-1)} = e^{(\lambda_1+\lambda_2)(e^t-1)}\] 이는 \(\text{Poisson}(\lambda_1 + \lambda_2)\) 의 MGF이다. 강도가 더해지는 것이 이 수식 구조에서 직접 나온다.
모든 실수 \(t\) 에 대해 존재한다.
5.1 MGF에서 적률 복원
\[ M_X'(t) = \lambda e^t \cdot e^{\lambda(e^t - 1)} \]
\[ M_X'(0) = \lambda \cdot 1 = \lambda = E[X] \quad \checkmark \]
5.2 독립 포아송의 합
\(X_1 \sim \text{Poisson}(\lambda_1)\) , \(X_2 \sim \text{Poisson}(\lambda_2)\) 가 독립이면:
\[ M_{X_1+X_2}(t) = e^{\lambda_1(e^t-1)} \cdot e^{\lambda_2(e^t-1)} = e^{(\lambda_1+\lambda_2)(e^t-1)} \]
따라서 \(X_1 + X_2 \sim \text{Poisson}(\lambda_1 + \lambda_2)\) . 독립 포아송의 합은 다시 포아송이며, 강도가 더해진다. 이 성질은 포아송 과정의 독립 증분 공리의 직접적 결과이다.
6 재귀 관계
\[ P(X = x) = \frac{\lambda}{x} \cdot P(X = x-1), \quad x \geq 1 \]
\(P(X = 0) = e^{-\lambda}\) 에서 시작하여 순차 계산이 가능하다.
최빈값: \(P(X=x)/P(X=x-1) = \lambda/x\) 이므로, \(\lambda/x \geq 1\) 인 가장 큰 \(x\) , 즉 \(x = \lfloor\lambda\rfloor\) 가 최빈값이다. \(\lambda\) 가 정수이면 \(\lambda\) 와 \(\lambda - 1\) 두 개의 최빈값이 존재한다.
7 감마-포아송 관계
\(X \sim \text{Gamma}(\alpha, \beta)\) (단, \(\alpha\) 는 양의 정수)이면, 임의의 \(x > 0\) 에 대해:
\[ P(X \leq x) = P(Y \geq \alpha) \]
여기서 \(Y \sim \text{Poisson}(x/\beta)\) 이다.
이 관계는 적분 by parts를 반복하여 증명된다 (Casella & Berger, 2002, Example 3.3.1). 직관적으로, 포아송 과정에서 \(\alpha\) 번째 사건까지의 대기 시간이 감마 분포를 따르기 때문이다.
7.1 실무 활용
- 포아송 과정의 사건 간 간격: \(\text{Exp}(\lambda)\) (감마의 \(\alpha = 1\) 특수 경우)
- \(\alpha\) 번째 사건까지의 대기 시간: \(\text{Gamma}(\alpha, 1/\lambda)\)
- 이 이원성을 이용하면 포아송 확률을 감마 CDF로, 감마 확률을 포아송 합으로 계산할 수 있다
8 지수족 표현
포아송 분포는 지수족에 속한다:
\[ \frac{e^{-\lambda}\lambda^x}{x!} = \frac{1}{x!} \cdot e^{-\lambda} \cdot e^{x \log \lambda} \]
| 구성 요소 | 포아송 분포 |
|---|---|
| 자연 모수 \(\eta\) | \(\log \lambda\) |
| 충분통계량 \(T(x)\) | \(x\) |
| 기저 측도 \(h(x)\) | \(1/x!\) |
| 정규화 \(c(\lambda)\) | \(e^{-\lambda}\) |
자연 모수가 \(\log \lambda\) 라는 것은, 포아송 회귀(GLM)의 정준 연결함수가 로그 함수인 이유이다:
\[ \log \lambda = \mathbf{x}^\top \boldsymbol{\beta} \]
왜 로그인가? \(\lambda\) (카운트의 평균)는 반드시 양수여야 하지만, 선형 예측자 \(\mathbf{x}^\top \boldsymbol{\beta}\) 는 어떤 실수 값도 가질 수 있다. 로그 변환은 이 불일치를 자동으로 해결한다: \(\lambda = e^{\mathbf{x}^\top \boldsymbol{\beta}} > 0\) 이 항상 성립한다.
회귀계수의 해석: \(\beta_j\) 는 “설명변수 \(x_j\) 가 1 단위 증가할 때 \(\lambda\) 가 \(e^{\beta_j}\) 배 변화”를 의미한다. 예를 들어 \(\beta_j = 0.3\) 이면 \(e^{0.3} \approx 1.35\), 즉 약 35% 증가이다.
다른 연결함수와의 비교: 선형 회귀에서는 \(\lambda = \mathbf{x}^\top \boldsymbol{\beta}\) (항등 연결)를 쓰면 \(\lambda < 0\) 이 가능해져 카운트 데이터에 부적합하다. 로그 연결이 카운트 데이터의 자연스러운 선택인 이유이다.
이 연결에서 \(\lambda = e^{\mathbf{x}^\top \boldsymbol{\beta}} > 0\) 이 자동으로 보장되므로, 카운트 데이터의 비음수 제약이 자연스럽게 충족된다.
9 MLE
\(X_1, \ldots, X_n \overset{\text{iid}}{\sim} \text{Poisson}(\lambda)\) 에서:
\[ \ell(\lambda) = \sum_{i=1}^n \left[x_i \log \lambda - \lambda - \log(x_i!)\right] \]
\[ \frac{d\ell}{d\lambda} = \frac{\sum x_i}{\lambda} - n = 0 \implies \hat{\lambda}_{MLE} = \bar{X} \]
표본 평균이 MLE이다. 이는 충분통계량 \(T = \sum X_i\) 가 \(\lambda\) 에 관한 모든 정보를 담고 있으며, MLE가 이 충분통계량의 함수라는 지수족의 일반 성질과 일치한다.
피셔 정보량: \(I(\lambda) = 1/\lambda\) , 따라서 \(\text{Var}(\hat{\lambda}) \geq \lambda/n\) . MLE \(\bar{X}\) 의 분산 \(\lambda/n\) 이 이 하한에 도달한다.
10 응용 분야
| 분야 | 활용 | 구체적 예시 |
|---|---|---|
| 대기 행렬 | 도착 모형 | 시간당 콜센터 전화 건수, M/M/1 큐 |
| 역학 | 발생률 모형 | 지역별 질병 발생 건수 |
| 보험 | 보험금 청구 | 연간 보험사고 건수 |
| 자연어처리 | 단어 출현 | 문서에서 특정 단어의 출현 횟수 |
| 품질 관리 | 결함 수 | 칩 웨이퍼 면적당 결함 수 |
| 교통 공학 | 사고 발생 | 교차로별 연간 교통사고 건수 |
| 천문학 | 광자 카운트 | 검출기에 도달하는 광자 수 |
11 코드 예시
11.1 Step 1: 순수 Python 구현 (원리 이해)
import math
# ----- 포아송 PMF 직접 구현 -----
def poisson_pmf(x, lam):
return math.exp(-lam) * lam**x / math.factorial(x)
# ----- 재귀 방식 -----
def poisson_pmf_recursive(lam, max_x=20):
probs = [math.exp(-lam)] # P(X=0)
for x in range(1, max_x + 1):
probs.append(probs[-1] * lam / x)
return probs
# 기본 성질
lam = 4.0
print(f"Poisson(lambda={lam})")
print(f"E[X] = Var(X) = {lam}")
print(f"최빈값 = {int(lam) - 1} 또는 {int(lam)}" if lam == int(lam)
else f"최빈값 = {math.floor(lam)}")
# PMF 출력
probs = poisson_pmf_recursive(lam, 15)
print(f"\n{'x':>3} | {'P(X=x)':>10} | {'P(X<=x)':>10}")
print("-" * 35)
cum = 0.0
for x, p in enumerate(probs):
cum += p
print(f"{x:3d} | {p:10.6f} | {cum:10.6f}")
# ----- 등산포 검증 (시뮬레이션) -----
import random
random.seed(42)
# 순수 Python 포아송 난수 (역변환 방법)
def poisson_random(lam):
L = math.exp(-lam)
k, p = 0, 1.0
while True:
k += 1
p *= random.random()
if p < L:
return k - 1
samples = [poisson_random(lam) for _ in range(10000)]
sample_mean = sum(samples) / len(samples)
sample_var = sum((x - sample_mean)**2 for x in samples) / (len(samples) - 1)
print(f"\n시뮬레이션 (n=10000):")
print(f"표본 평균: {sample_mean:.4f} (이론: {lam})")
print(f"표본 분산: {sample_var:.4f} (이론: {lam})")
print(f"분산/평균 비: {sample_var/sample_mean:.4f} (등산포면 ~1)")11.2 Step 2: scipy/numpy 구현 (실무 활용)
import numpy as np
from scipy import stats
# ----- 기본 사용법 -----
lam = 4.0
dist = stats.poisson(lam)
print(f"E[X] = {dist.mean():.4f}")
print(f"Var(X) = {dist.var():.4f}")
print(f"P(X <= 3) = {dist.cdf(3):.4f}")
print(f"P(X > 6) = {1 - dist.cdf(6):.4f}")# ----- 과산포 진단 -----
import numpy as np
from scipy import stats
np.random.seed(42)
# 시나리오 1: 포아송 데이터 (등산포)
poisson_data = stats.poisson(lam=5).rvs(size=500)
mean_p, var_p = poisson_data.mean(), poisson_data.var()
print(f"포아송 데이터: 평균={mean_p:.3f}, 분산={var_p:.3f}, "
f"분산/평균={var_p/mean_p:.3f}")
# 시나리오 2: 음이항 데이터 (과산포)
nb_data = stats.nbinom(n=5, p=0.5).rvs(size=500) # E=5, Var=10
mean_nb, var_nb = nb_data.mean(), nb_data.var()
print(f"음이항 데이터: 평균={mean_nb:.3f}, 분산={var_nb:.3f}, "
f"분산/평균={var_nb/mean_nb:.3f}")
# 과산포 검정: Cameron-Trivedi (1990) 방법
# H0: Var(X) = E[X] (포아송) vs H1: Var(X) = E[X] + alpha*E[X]^2
def overdispersion_test(data):
n = len(data)
mean = data.mean()
aux = ((data - mean)**2 - data) / mean
t_stat = np.sqrt(n) * aux.mean() / aux.std()
p_value = 1 - stats.norm.cdf(t_stat)
return t_stat, p_value
t1, p1 = overdispersion_test(poisson_data)
t2, p2 = overdispersion_test(nb_data)
print(f"\n과산포 검정:")
print(f" 포아송 데이터: t={t1:.3f}, p={p1:.4f} (기각 안 됨)")
print(f" 음이항 데이터: t={t2:.3f}, p={p2:.4f} (과산포 검출)")# ----- 포아송 회귀 (GLM) -----
import numpy as np
import statsmodels.api as sm
np.random.seed(42)
n = 200
# 데이터 생성: log(lambda) = 0.5 + 0.3*x
x = np.random.normal(0, 1, n)
lam_true = np.exp(0.5 + 0.3 * x)
y = np.random.poisson(lam_true)
# 포아송 회귀 적합
X = sm.add_constant(x)
model = sm.GLM(y, X, family=sm.families.Poisson())
result = model.fit()
print(result.summary2())
# 과산포 확인: 피어슨 카이제곱 / 자유도
pearson_chi2 = result.pearson_chi2
df = result.df_resid
dispersion = pearson_chi2 / df
print(f"\n피어슨 분산: {dispersion:.3f} (1에 가까우면 등산포)")11.3 R 코드
# R에서의 포아송 분포
lam <- 4
# 기본 함수
cat("P(X=3):", dpois(3, lam), "\n")
cat("P(X<=3):", ppois(3, lam), "\n")
cat("0.95 분위수:", qpois(0.95, lam), "\n")
# 과산포 검정
set.seed(42)
data <- rpois(500, lambda=5)
cat("분산/평균:", var(data)/mean(data), "\n")
# 포아송 회귀
x <- rnorm(200)
y <- rpois(200, lambda=exp(0.5 + 0.3*x))
model <- glm(y ~ x, family=poisson(link="log"))
summary(model)
# 과산포 시 quasi-Poisson
model_quasi <- glm(y ~ x, family=quasipoisson(link="log"))
summary(model_quasi)12 관련 주제
선행 지식
후속 주제
관련 개념