포아송 분포로 희귀 사건의 발생 횟수 모델링하기

포아송 분포의 λ 매개변수, 평균과 분산의 관계, 노출량 보정, 과산포 진단과 포아송 회귀 활용 방식을 정리한다.

2026-08-14 · 최초 발행 2024-04-29

희귀한 카운트를 λ 하나로 표현하는 방식

대규모 시행에서 드문 사건이 몇 번 발생했는지 다룰 때 포아송 분포(Poisson distribution)를 사용할 수 있다. 운영 로그의 실패 건수, 트래픽 요청 수, 결함 발생 건처럼 값이 카운트 형태이고 사건이 희귀하며 독립적일 때 적합하다.

확률질량함수는 다음과 같다.

  • P(X = k) = e^(−λ) · λ^k / k! (k = 0, 1, 2, …), 파라미터 λ > 0
  • E[X] = Var[X] = λ

λ는 단위 시간뿐 아니라 면적·길이·용적 등 단위 구간당 사건율로 해석할 수 있다. 사건율이 λ인 동질(homogeneous) 포아송 과정에서는 임의 구간의 사건 수가 포아송 분포를 따르며, 사건 사이의 간격은 평균 1/λ인 지수 분포를 따른다.

이항분포와도 연결된다. 시행 횟수 n → ∞, 각 시행의 성공확률 p → 0, np → λ가 일정한 조건에서는 Binomial(n, p) → Poisson(λ)로 수렴한다.

관측 구간의 길이가 t라면 X ~ Poisson(λt)로 볼 수 있다. 독립 스트림을 합치거나 일부 사건만 선택하는 상황에도 합(superposition)과 분할(thinning) 성질을 적용할 수 있다.

노출량과 가정이 모델 선택을 가른다

서로 다른 시간이나 면적에서 수집한 카운트를 비교할 때는 노출량(exposure)을 함께 봐야 한다. 구간 길이 t에 따라 평균은 λt로 선형 스케일링되므로, 실무에서는 시간·면적 같은 노출량을 offset으로 반영해 정규화된 사건율을 추정한다.

포아송 모형은 겹치지 않는 구간의 사건 수가 독립이라는 가정과, 단위 시간당 사건율이 일정하다는 정상성 가정 위에 놓인다. 추세나 계절성이 있으면 비동질 포아송 λ(t) 또는 회귀 모형을 고려해야 한다.

특히 평균과 분산이 같다는 제약은 진단 대상이다. 관측 분산이 평균보다 크면 과산포(overdispersion)를 의심해 음이항 회귀를 검토하고, 평균보다 작으면 저산포(underdispersion)에 대응할 수 있는 Conway–Maxwell–Poisson 등을 대안으로 검토한다.

독립인 포아송 과정의 합은 λ가 합인 포아송 과정을 유지한다. 각 사건을 확률 p로 선택하는 경우도 결과는 λp인 포아송 과정이므로, 샘플링·필터링·라우팅을 설명하는 데 활용할 수 있다.

공변량을 반영하려면 포아송 회귀(GLM)를 사용한다.

  • 로그 링크: log(E[Y]) = β0 + βX + log(exposure).
  • 범주형·연속형 공변량을 반영할 수 있고, offset으로 노출량을 안정적으로 반영한다.

운영 데이터에서 만나는 카운트 문제

IT 운영과 신뢰성 영역에서는 장애 알람 건수, HTTP 5xx 오류수, 재시도 횟수를 모델링할 수 있다. 시간당 사건율을 바탕으로 SLA 위반 확률을 추정하고 알람 임계치를 동적으로 조정하는 데 연결된다.

네트워크와 콜센터에서는 분당 콜 수, 패킷 드롭 수, 접속 요청 수가 대상이다. 시간대별 λ(t)를 추정하면 인력 스케줄을 최적화하고 큐 길이를 예측할 수 있다.

제조·품질 관리에서는 라인당 불량 건수와 장비 고장 발생 건수를 다룬다. 생산 수량이나 시간을 노출량으로 정규화하면 공정 간 비교가 가능하다. 의료·보험·공공 영역에서는 감염 발생 건수, 보험 청구 발생 수, 사고 건수를 분석하고 지역·기간 노출량을 반영한 위험 지도(risk mapping)를 작성할 수 있다.

집계 후 분산을 확인하는 모델링 흐름

입력은 타임스탬프·구간·노출량(exposure)을 포함한 카운트 데이터다. 이를 집계한 뒤 λ를 추정하고 분산을 진단한다. 결과에 따라 포아송, 음이항, 제로인플레이트 모형을 선택해 적합·검증하며, 기간별 예측 분포·신뢰구간·임계치·리스크 지표를 산출한다.

분산지수(Dispersion Index, DI) = s² / x̄는 첫 진단 지표로 쓸 수 있다. DI ≈ 1이면 포아송 적합 가능성을 검토하고, DI >> 1이면 과산포, DI << 1이면 저산포를 의심한다. 피어슨·디비언스 잔차의 패턴과 χ² 적합도 검정(Σ (xi − μi)²/μi)도 함께 확인한다. 계절성이나 추세가 있으면 계절 더미·스플라인·Fourier 항으로 λ(t)를 모형화한다.

DI 1과산포제로 과다원천 로그/이벤트구간 집계 노출량 계산기초 통계: 평균=분산 점검포아송 추정 (λ̂)음이항 회귀제로 인플레이트 모형예측: 분기/일/시간대 사건지표 산출: SLA 리스크, 인력배치, 임계치경보/자동화: 동적 임계값 적용

카운트 데이터에 맞는 분포 고르기

모델 평균-분산 관계 장점 한계 활용 포인트
포아송 Var = Mean 단순·해석 용이, 계산 효율 과산포/저산포 데이터에 부적합 희귀 사건, 베이스라인 모델
음이항 Var > Mean (과산포 허용) 현실 데이터 적합성 우수 파라미터 1개 추가로 해석 복잡 이질성·군집 발생 데이터
제로-인플레이트 포아송 0 초과비 처리 0 과다 상황 대응 모형 복잡·추정 민감 결함·신고 등 0 편중 데이터
비동질 포아송 λ(t) 시간/공간 가변 계절·추세 반영 λ(t) 설계 필요 시간대별 수요/리스크 예측

포아송 기반 모델은 95% 예측구간을 제공해 예측 가능성을 높이고 의사결정 신뢰도를 뒷받침한다. λ를 이용한 인력·자원 배치는 과잉·과소 배치 비용을 10~30% 절감하는 사례로 이어질 수 있다. 기간 T 내 k회 이상 사건이 발생할 확률을 계산해 SLA 위반 확률을 산출할 수 있으며, 목표 오탐률 α에 대한 임계 k*를 정해 경보 품질을 높일 수 있다.

하루 평균 장애가 λ=4일 때 95% 예측구간은 약 [1, 8] 수준이다(정확 계산은 Poisson 분포 기준). λ 합성을 이용하면 주간·월간 리스크도 즉시 추정할 수 있다.

추정·진단·예측 코드

전제조건

  • Python 3.10+, numpy≥1.24, scipy≥1.10, statsmodels≥0.14(회귀 예시), pandas≥2.0

단순 포아송 추정과 예측구간은 다음처럼 계산한다.

import numpy as np
from scipy.stats import poisson

# 일별 장애 건수(동일 노출량 가정)
counts = np.array([2, 3, 4, 1, 5, 6, 2, 3, 4, 5])
lam_hat = counts.mean()

# 95% 예측구간(다음 하루 사건 수)
lo, hi = poisson.interval(0.95, mu=lam_hat)
print(f"λ̂={lam_hat:.3f}, 95% PI=[{int(lo)}, {int(hi)}]")

# 과산포 간단 진단
dispersion_index = counts.var(ddof=1) / counts.mean()
print(f"Dispersion Index={dispersion_index:.2f}")

시간대별 요청 건수처럼 노출량과 공변량이 함께 있는 경우에는 offset을 둔 포아송 GLM을 사용할 수 있다.

import numpy as np
import pandas as pd
import statsmodels.api as sm

# 시간대별 요청 건수와 노출량(분 단위), 요일/피크 더미
df = pd.DataFrame({
    "count": [5,7,3,9,12,4,6,8,10,11],
    "exposure": [30,30,30,60,60,30,30,60,60,60],  # 관측 시간(분)
    "is_peak":   [0,1,0,1,1,0,0,1,1,1],
    "is_weekend":[0,0,0,0,1,1,1,0,1,0],
})
df["log_exposure"] = np.log(df["exposure"])

X = sm.add_constant(df[["is_peak","is_weekend"]])
y = df["count"]

model = sm.GLM(y, X, family=sm.families.Poisson(), offset=df["log_exposure"])
res = model.fit()
print(res.summary())

# 다음 60분 예측(피크=1, 주말=0)
newX = sm.add_constant(pd.DataFrame({"is_peak":[1], "is_weekend":[0]}))
pred_mu = res.predict(newX, offset=np.log([60]))[0]
print(f"예측 사건 수(60분): {pred_mu:.2f}")

피어슨 χ² 통계량으로 간단한 적합도 점검도 수행할 수 있다.

import numpy as np
from scipy.stats import chi2

counts = np.array([2,3,4,1,5,6,2,3,4,5])
mu = counts.mean()
D = np.sum((counts - mu)**2 / mu)   # 피어슨 χ² 통계량
df = len(counts) - 1
pval = 1 - chi2.cdf(D, df)
print(f"Pearson χ²={D:.2f}, df={df}, p-value={pval:.3f}")

Dispersion Index가 ≈ 1이면 포아송 모형을 유지할 수 있고, 1.5 이상이면 과산포 가능성을 검토한다. GLM의 offset은 노출량을 보정하며 계수는 로그 스케일 비율로 해석한다. 잔차에서 체계적인 패턴이 발견되면 공변량을 추가하거나 대체 분포로 전환할 필요가 있다.

포아송 분포확률분포카운트 데이터포아송 회귀과산포