Sequential A/B Testing을 언제든 멈춰도 안전하게 — e-value와 Optional Stopping의 수학적 원리
A/B 테스트를 운영하다 보면 누구나 한 번쯤 이런 유혹에 빠진다. "어, 중간 결과가 이미 유의미한데, 지금 멈춰도 되지 않을까?" 고전 통계학의 답은 냉혹하다. 안 된다. 미리 정한 샘플 수를 채우기 전에 중간 결과를 들여다보고 멈추면 1종 오류율(잘못 유의미하다고 판정하는 오류의 허용 확률, α)이 급격히 부풀어 오른다. 예를 들어 α=0.05로 설계한 실험을 중간에 5번 들여다보고 그때마다 멈출지 결정하면, 실제 오류율은 0.19까지 치솟는다. 이른바 "Peeking Problem"이다.
그러나 최신 통계 이론은 이 질문에 전혀 다른 답을 내놓는다. e-value와 SAVI(Safe Anytime-Valid Inference) 프레임워크를 사용하면, 어떤 시점에 분석을 멈추든 1종 오류 보장이 수학적으로 유지된다. Spotify는 mSPRT(mixture Sequential Probability Ratio Test, 뒤에서 설명) 기반의 sequential testing 프레임워크를 자사 A/B 실험 플랫폼에 도입했고(Spotify Engineering, 2023), Amplitude, Netflix, Uber도 유사한 방법론을 수천 건의 상업적 실험에 적용하고 있다. ICML 2025에서는 전용 튜토리얼 세션이 편성될 만큼 학계와 산업계 모두에서 주류로 자리 잡고 있다.
이 글에서는 e-value의 수학적 본질부터 mSPRT를 넘어서는 복합 귀무가설·다중 검정·회귀 조정까지 SAVI의 전체 지형을 정리하고, R과 Python으로 바로 써먹을 수 있는 코드와 함께 소개한다. mSPRT를 처음 접하는 독자라면 "두 가설 하에서 데이터가 얼마나 잘 설명되는지의 비율(likelihood ratio)을 이용한 순차 검정"으로 이해하면 충분하다.
핵심 개념
E-value란 무엇인가
e-value는 귀무가설 H₀에 대한 증거를 수량화하는 확률 변수다. 정의는 단순하다.
E-value: 귀무가설 H₀ 하에서 기댓값이 1 이하인 비음수 통계량. 즉, E[E] ≤ 1 (H₀ 하에서).
이 단순한 제약 하나가 놀라운 특성을 만들어 낸다.
| 특성 | 내용 |
|---|---|
| 기각 기준 | e ≥ 1/α (예: α=0.05이면 e ≥ 20) |
| 해석 | e-value가 크다 = H₀에 반하는 강한 증거 |
| 결합 | 독립 e-value의 곱이 여전히 e-value |
| 병합 | 임의 의존 구조 하에서도 가중 평균이 e-value |
p-value와 비교하면 차이가 선명해진다.
| 비교 항목 | p-value | e-value |
|---|---|---|
| 기각 기준 | p < α | e ≥ 1/α |
| Optional Stopping | 불가 (1종 오류 팽창) | 가능 (보장 유지) |
| 유의수준 사후 변경 | 불가 | 가능 |
| 복합 귀무가설 | 어려움 | Universal Inference로 해결 |
| 다중 검정 결합 | 의존 구조 제약 | 임의 의존 허용 |
비통계 직군을 위한 한 줄 설명: PM이나 데이터 분석가에게 e-value를 설명할 때는 이렇게 말하면 된다. "우리는 지금 '대조군이 더 낫다'는 가설에 베팅을 걸고 있고, 데이터가 쌓일수록 베팅 잔고가 변한다. e-value가 잔고이고, 20배가 넘으면 우리 쪽이 맞다고 판정한다. 언제 확인해도, 중간에 멈춰도 이 판정 기준은 흔들리지 않는다."
SAVI 프레임워크의 전체 구조
SAVI는 e-value를 중심으로 순차 추론을 체계화한 프레임워크다. 핵심 구성 요소는 세 가지다.
| 구성 요소 | 역할 | p-value 세계의 대응 개념 |
|---|---|---|
| E-value | 단일 시점의 증거 측정 | p-value |
| E-process | 순차 축적되는 증거 (Test Martingale) | 순차적 p-value |
| Confidence Sequence | 어느 시점에나 유효한 신뢰 구간 | 고정 표본 신뢰 구간 |
E-process와 Martingale 이해하기: "Martingale"이라는 단어가 생소해도 직관은 간단하다. 일반적인 누적 합산(+)과 달리, e-process는 새 데이터가 들어올 때마다 곱(×)으로 갱신된다. "지금까지 베팅 잔고가 100배 불었는데, 새 데이터가 들어왔다. 이 데이터가 H₀에 반하는 증거라면 잔고가 더 불어나고, 아니라면 줄어든다." 이 곱셈 갱신 구조 덕분에 어떤 시점에 멈춰도 전체 오류율이 보장된다.
게임 이론적 해석: SAVI는 통계 검정을 도박 게임으로 재해석한다. H₀가 참이라면 어떤 전략으로도 장기적으로 돈을 벌 수 없다. H₀가 거짓이라면 올바른 베팅 전략이 기하급수적으로 수익을 키운다. e-value는 "현재 베팅 잔고"이고, e-process는 "잔고의 시간적 궤적"이다.
수학적 보장의 근거는 Ville의 부등식이다.
e-process E_t가 H₀ 하에서 Test Martingale이면:
P(어떤 시점 t에서 E_t ≥ 1/α) ≤ α이것이 "언제 멈춰도 안전하다"는 주장의 수학적 뼈대다.
mSPRT를 넘어서: SAVI가 다루는 네 가지 확장
mSPRT(mixture Sequential Probability Ratio Test)는 e-value의 특수 케이스다. mSPRT의 likelihood ratio(두 가설 하에서 데이터 확률의 비)는 H₀ 하에서 기댓값 1 이하임을 만족하기 때문에 e-value 정의를 충족한다. SAVI는 이보다 훨씬 넓은 문제를 해결한다.
1. 복합 귀무가설 (Composite Null) — 단일 분포가 아닌 분포 집합을 검정할 때
H₀가 "평균이 0 이하인 모든 분포"처럼 분포의 집합일 때, 고전적 방법은 종종 막힌다. Wasserman, Ramdas, Balakrishnan(2020)의 Universal Inference는 데이터 분할(split)만으로 이 문제를 해결한다. 정칙 조건(regularity conditions, 분포가 미분 가능하고 경계가 없다는 등의 수학적 전제)이 전혀 필요 없다.
# Universal Inference: split LRT 기반 e-value — 개념 예시 (pseudocode)
# 알고리즘 흐름 설명용입니다. 실제 실행을 위해서는 각 함수를 구현해야 합니다.
def universal_e_value_concept(data, fit_mle_fn, compute_lrt_fn, null_set):
"""
Universal Inference 3단계:
1. 데이터를 훈련/검증으로 분할
2. 훈련 세트로 MLE(최대우도추정) 추정
3. 검증 세트에서 split LRT e-value 계산
E = L(theta_hat | test) / sup_{theta in H0} L(theta | test)
"""
n = len(data)
train, test = data[:n // 2], data[n // 2:]
theta_hat = fit_mle_fn(train) # fit_mle_fn은 문제에 맞게 구현
e_value = compute_lrt_fn(theta_hat, test, null_set) # 마찬가지
return e_value # e_value >= 1/alpha 이면 H0 기각
# 정규 분포 평균 검정 — 바로 실행 가능한 구체 예시
import numpy as np
from scipy import stats
def demo_normal_mean_test(n=100, true_mean=0.5, null_mean=0.0):
"""H0: μ = null_mean 에 대한 Universal Inference 데모"""
np.random.seed(42)
data = np.random.normal(true_mean, 1, n)
train, test = data[:n // 2], data[n // 2:]
# MLE: 정규 분포 평균의 MLE는 표본 평균
theta_hat = np.mean(train)
# Split LRT e-value 계산
log_like_alt = np.sum(stats.norm.logpdf(test, loc=theta_hat, scale=1))
log_like_null = np.sum(stats.norm.logpdf(test, loc=null_mean, scale=1))
e_value = np.exp(log_like_alt - log_like_null)
print(f"e-value: {e_value:.2f}")
# 예상 출력: e-value: 수십~수백 (효과 크기 0.5, n=50 검증 세트)
print(f"기각 여부 (α=0.05): {e_value >= 20}")
# 예상 출력: 기각 여부 (α=0.05): True
return e_value
demo_normal_mean_test()2. 회귀 조정 (Regression Adjustment) — 분산 감소와 anytime-validity를 동시에
CUPED(Controlled-experiment Using Pre-Experiment Data)는 실험 전 데이터(예: 이전 주 구매 이력)를 공변량으로 활용해 측정 분산을 줄이는 기법이다. 분산이 줄면 같은 효과를 더 작은 샘플로 탐지할 수 있다. e-value 프레임워크 안에서 CUPED 스타일 조정을 적용할 때 핵심은 조정 후에도 E[E] ≤ 1 (under H₀) 조건이 유지되어야 한다는 점이다. 이 조건이 깨지면 anytime-valid 보장이 사라진다. Statsig의 CURE(Covariate-adjusted Unadjusted Regression Estimator)는 이 조건을 보존하면서 공변량 조정을 구현한 대표적 사례다.
3. 다중 검정 — FDR(False Discovery Rate)과 FWER(Family-Wise Error Rate) 제어
FDR(기각된 가설 중 실제로는 귀무가설이 참인 비율)과 FWER(적어도 하나라도 잘못 기각할 확률)을 e-value 기반으로 제어하면 의존 구조에 관계없이 보장이 유지된다.
| 절차 | 제어 대상 | 의존 구조 가정 |
|---|---|---|
| e-BH | FDR (잘못 기각 비율) | 임의 의존 허용 |
| e-Bonferroni | FWER (하나라도 잘못 기각) | 임의 의존 허용 |
| e-GAI | 온라인 FDR (스트리밍) | 임의 의존 허용 |
고전적 BH 절차는 PRDS(Positive Regression Dependency on Subsets, 가설들 간 특정 양의 의존 구조)를 가정한다. e-BH는 이 가정 없이도 FDR ≤ α를 보장한다.
4. 비모수·고차원 설정 — 모형 가정 없이도 작동
전환율, 클릭률처럼 이항 분포를 따르는 지표에도, 수백 개의 광고 소재를 동시에 검정하는 고차원 설정에도 e-value는 적용 가능하다. 정규 분포 가정이 맞는지 걱정할 필요 없이 보편적으로 사용할 수 있다는 것이 큰 강점이다.
실전 적용
아래 세 예시는 각각 e-value 기본 적용(예시 1), e-process 시간적 모니터링(예시 2), 다중 검정에서의 FDR 제어(예시 3)를 다룬다. 모두 동일한 맥락—웹 서비스 A/B 테스트—을 전제한다.
예시 1: R로 구현하는 Sequential A/B 테스트
safestats 패키지는 SAVI의 공식 참조 구현체다. Safe t-test를 이용해 전환율 실험을 순차적으로 모니터링할 수 있다.
library(safestats)
# 1단계: 설계 — 목표 효과 크기와 파워 기반 설계
# delta1: 탐지하고 싶은 효과 크기 (Cohen's d)
# alpha: 1종 오류율, beta: 2종 오류율 (1 - power)
design <- designSafeT(delta1 = 0.5, alpha = 0.05, beta = 0.2)
cat("최소 권장 샘플 수:", design$n_plan, "\n")
# 예상 출력: 최소 권장 샘플 수: 62 (처리군·대조군 각각)
# 2단계: 순차 검정 — 데이터가 쌓일 때마다 e-value 갱신
set.seed(42)
control <- rnorm(100, mean = 0, sd = 1)
treatment <- rnorm(100, mean = 0.5, sd = 1)
result <- safeTTest(
x = treatment,
y = control,
design = design
)
cat("e-value:", result$eValue, "\n")
# 예상 출력: e-value: 수십~수백 (효과 크기 0.5, n=100이면 20 초과 가능성 높음)
cat("기각 여부 (α=0.05):", result$eValue >= 1 / 0.05, "\n")
# 기각 기준: e-value >= 20이면 H₀ 기각
# 예상 출력: 기각 여부 (α=0.05): TRUE
# 핵심: 이 결과를 n=100에서 확인해도, n=50에서 확인해도
# 1종 오류율은 α=0.05로 수학적으로 보장됨| 코드 단계 | 역할 |
|---|---|
designSafeT() |
검정력 분석 + 설계 파라미터 계산 |
safeTTest() |
e-value 계산 (순차 적용 가능) |
result$eValue >= 1/α |
기각 판단 (e ≥ 20이면 H₀ 기각) |
예시 2: Python으로 구현하는 e-process 시각화
e-process가 시간에 따라 어떻게 곱셈으로 축적되는지 직접 구현해 확인한다.
expectation라이브러리 사용 시 주의: 패키지는 활발히 개발 중이며 API가 변경될 수 있다.TwoSampleMeanEProcess클래스명과 인터페이스를 사용하기 전에 GitHub 저장소에서 최신 API를 확인하라. 아래 코드는 동일한 수학적 원리를 직접 구현한 버전으로 바로 실행 가능하다.
# 라이브러리를 사용할 경우 (API 변경 가능성 있음)
pip install expectationimport numpy as np
import matplotlib.pyplot as plt
from scipy import stats
np.random.seed(42)
# 실험 데이터: 처리군이 실제 효과 있는 시나리오
control = np.random.normal(0, 1, 200)
treatment = np.random.normal(0.4, 1, 200)
alt_mean_diff = 0.4 # 사전 기대 효과 크기
# e-process: 각 관측에서 likelihood ratio를 곱셈으로 갱신
# 이 곱셈 구조가 Optional Stopping을 안전하게 만드는 핵심
e_values = []
e_current = 1.0 # e-process 초기값 (베팅 잔고)
for i in range(10, len(control)):
diff = treatment[i] - control[i]
# 단일 관측에서의 likelihood ratio
# null(차이=0) vs alternative(차이=alt_mean_diff)
lr = (stats.norm.pdf(diff, loc=alt_mean_diff, scale=np.sqrt(2)) /
stats.norm.pdf(diff, loc=0, scale=np.sqrt(2)))
e_current *= lr # 곱셈 갱신
e_values.append(e_current)
timesteps = range(10, len(control))
plt.figure(figsize=(10, 5))
plt.plot(timesteps, e_values, label="e-process 궤적", color="steelblue")
plt.axhline(y=1 / 0.05, color="red", linestyle="--", label="기각 임계값 (1/α = 20)")
plt.axhline(y=1.0, color="gray", linestyle=":", label="귀무가설 기준 (e=1)")
plt.yscale("log")
plt.xlabel("누적 관측 수")
plt.ylabel("e-value (log scale)")
plt.title("E-process 시간적 궤적 — Optional Stopping 데모")
plt.legend()
plt.tight_layout()
plt.show()
rejection_point = next(
(i + 10 for i, e in enumerate(e_values) if e >= 20),
None
)
print(f"최초 기각 시점: 관측 {rejection_point}번째")
# 예상 출력: 최초 기각 시점: 관측 40~100번째 (효과 크기·랜덤 시드에 따라 다름)
print(f"최종 e-value: {e_values[-1]:.2f}")
# 예상 출력: 최종 e-value: 수십~수천 (H₀가 거짓인 시나리오)로그 스케일 궤적에서 H₀가 거짓이라면 직선에 가깝게 우상향(기하급수적 상승)하고, H₀가 참이라면 1 근방을 무작위로 맴도는 것을 확인할 수 있다.
예시 3: e-BH를 이용한 다중 광고 소재 검정 — FDR(False Discovery Rate) 제어
동일 서비스에서 수백 개의 광고 소재를 동시에 A/B 테스트할 때, e-BH로 FDR을 제어하는 예시다.
savvi라이브러리 사용 시 주의:savvi.multiple_testing.eBH경로는 버전에 따라 변경될 수 있다. 실행 전 PyPI 페이지에서 최신 API를 확인하라. 아래는 e-BH 알고리즘을 직접 구현한 버전으로 바로 실행 가능하다.
# 라이브러리를 사용할 경우 (API 변경 가능성 있음)
pip install savviimport numpy as np
def eBH(e_values, alpha):
"""
e-BH 절차: e-value 기반 FDR(False Discovery Rate) 제어
임의의 의존 구조 하에서도 FDR ≤ alpha 보장.
알고리즘: e-value를 내림차순 정렬 후
e_(k) >= n / (k * alpha) 를 만족하는 가장 큰 k를 찾아 상위 k개 기각
"""
n = len(e_values)
sorted_idx = np.argsort(e_values)[::-1] # 내림차순 정렬
sorted_e = e_values[sorted_idx]
k_star = 0
for k in range(1, n + 1):
if sorted_e[k - 1] >= n / (k * alpha):
k_star = k
# 단조 조건이 보장되지 않으므로 break 없이 가장 큰 k를 탐색
return sorted_idx[:k_star]
np.random.seed(0)
# 시뮬레이션: 500개 광고 소재 중 50개는 실제 효과 있음
n_hypotheses = 500
n_true_effects = 50
e_null = np.random.exponential(1.0, n_hypotheses - n_true_effects)
e_alt = np.random.exponential(5.0, n_true_effects) # 실제 효과 있는 소재
e_all = np.concatenate([e_null, e_alt])
labels = np.array([0] * (n_hypotheses - n_true_effects) + [1] * n_true_effects)
alpha = 0.05
rejected = eBH(e_all, alpha=alpha)
fdr = np.sum(labels[rejected] == 0) / max(len(rejected), 1)
power = np.sum(labels[rejected] == 1) / n_true_effects
print(f"기각된 소재 수: {len(rejected)}")
# 예상 출력: 기각된 소재 수: 20~40 (효과 강도에 따라 다름)
print(f"실제 FDR: {fdr:.3f} (목표: ≤ {alpha})")
# 예상 출력: 실제 FDR: 0.000~0.050 (보통 목표치 이하)
print(f"검정력(Power): {power:.3f}")
# 예상 출력: 검정력(Power): 0.5~0.8 (효과 크기에 따라 다름)e-BH vs 고전 BH 절차: 고전적 Benjamini-Hochberg(BH) 절차는 p-value의 독립성이나 PRDS(Positive Regression Dependency on Subsets, 가설들 간 특정 양의 의존 구조)를 가정한다. e-BH는 임의의 의존 구조에서도 FDR ≤ α를 보장한다. 단, 이 강력한 보장의 대가로 검정력이 다소 낮아질 수 있다. 기각 소재 수가 BH보다 적다고 "방법이 틀렸다"고 판단하면 안 된다.
장단점 분석
장점
| 항목 | 내용 |
|---|---|
| Optional Stopping | 어떤 이유로든 실험을 조기 중단·재개해도 1종 오류 보장 유지 |
| 곱셈 조합성 | 독립 e-value의 곱이 여전히 e-value → 실험 간 증거 합산이 자연스러움 |
| 임의 의존성 허용 | 가중 평균도 e-value → 다중 검정에서 의존 구조와 무관하게 적용 가능 |
| 유의수준 사후 변경 | 실험 후 α를 조정해도 유효 (p-value로는 원천 불가) |
| 보편성 | 복합·비모수·고차원 설정 모두 적용 가능 |
| 직관적 해석 | 베팅 잔고 비유로 PM·데이터 분석가에게 설명하기 쉬움 |
| Confidence Sequence | 신뢰 구간도 언제든 유효하게 계산 가능 |
단점 및 주의사항
| 항목 | 내용 | 대응 방안 |
|---|---|---|
| 검정력(Power) 손실 | 동일 샘플에서 p-value 기반 검정보다 보수적 | 효과 크기 사전 추정 강화, CUPED 스타일 회귀 조정 결합 |
| 최적 e-value 선택 어려움 | 비음수 함수면 모두 e-value → 어떤 e-value를 쓸지 비자명 | mSPRT(정규 분포), safestats 등 표준 구현체 활용 |
| 기존 도구 호환성 | 대부분의 통계 소프트웨어가 p-value 중심 설계 | R safestats, Python expectation·savvi 사용 |
| 학습 곡선 | 게임 이론적 사고방식이 기존 통계 교육과 다름 | Ramdas & Wang CMU 교재부터 시작 |
| 비정규 분포 지표 | mSPRT는 정규 분포 가정(또는 CLT(중심극한정리) 근사) 필요 | 비정규 지표는 별도 e-value 설계 또는 비모수 방법 사용 |
Bayes Factor와의 혼동 주의: 일부 e-value는 Bayes factor이지만, 대부분의 Bayes factor는 e-value가 아니다. Bayes factor는 H₀ 하에서 기댓값이 1 이하임을 보장하지 않을 수 있다. 혼용하면 anytime-valid 보장이 즉시 깨진다.
실무에서 가장 흔한 실수
- e-value를 설계 없이 사용: Optional Stopping이 가능하다고 해서 검정력 분석을 생략하면 실험이 수렴하지 않을 수 있다. "언제 멈춰도 된다"는 "목표 없이 영원히 돌려도 된다"와 다르다.
designSafeT()처럼 사전 설계 단계를 반드시 거쳐야 한다. - 회귀 조정 후 e-value 조건 미검증: CUPED 등으로 공변량을 조정한 뒤 조정된 추정량이 여전히 E[E] ≤ 1 (under H₀) 조건을 만족하는지 확인하지 않는 것. 이 조건이 깨지면 anytime-valid 보장이 사라진다.
- e-BH 결과를 BH와 동일하게 해석: e-BH는 임의 의존 구조와 온라인(스트리밍) 설정에서 진가가 드러난다. 기각 가설 수가 BH보다 적다는 이유만으로 "방법이 잘못됐다"고 판단하면 안 된다.
마치며
e-value와 SAVI는 단순한 mSPRT의 일반화가 아니라, p-value 중심 패러다임을 게임 이론적 기반 위에서 전면 재구성한 통계 추론의 새로운 언어다.
지금 당장 실천할 수 있는 3단계 — 순서대로 따라가면 이론과 실무를 함께 쌓을 수 있다.
- 먼저, R 사용자라면:
install.packages("safestats")실행 후designSafeT(delta1=0.5, alpha=0.05, beta=0.2)로 현재 진행 중인 실험을 safe t-test로 재설계하고, e-value가 1/α(=20)를 넘는 시점을 직접 확인해 보라. - 다음으로, Python 사용자라면: 예시 2의 e-process 시각화 코드를 과거 A/B 테스트 데이터에 적용해 보라. 사후 분석으로 e-process 궤적을 그려보면 "실험을 언제 멈췄다면 올바른 결론을 낼 수 있었는가"를 시각적으로 확인할 수 있어 향후 실험 설계에 직접적인 참고가 된다.
- 이론 기반을 다지고 싶다면: Ramdas & Wang의 CMU 공개 교재로 Ville의 부등식에서 e-BH 절차까지 전체 흐름을 따라간다. 교재를 읽고 난 뒤 Alexander Ly의 SAVI 튜토리얼을 보면 실무 적용까지 자연스럽게 연결된다.
다음 글: Confidence Sequence 심층 분석 — 이 글에서 소개한 e-process와 짝을 이루는 "언제든 유효한 신뢰 구간"을 직접 구현하고, 고전적 신뢰 구간과 폭(width)을 실험적으로 비교한다. e-value를 이해했다면 Confidence Sequence는 그 자연스러운 다음 단계다.
참고 자료
핵심 5개 — 여기서 시작하라
- Game-Theoretic Statistics and Safe Anytime-Valid Inference | Statistical Science — e-value·SAVI 이론 전체의 수학적 기반을 담은 핵심 논문
- Hypothesis Testing with E-values | Ramdas & Wang, CMU — e-value 입문부터 고급까지 다루는 공개 교과서
- Universal Inference | PNAS, Wasserman et al. 2020 — 복합 귀무가설 e-value 구성법 원논문
- Choosing a Sequential Testing Framework | Spotify Engineering — 실무 관점의 sequential testing 프레임워크 비교
- safestats R 패키지 | CRAN — 예시 1에서 사용한 공식 구현체
더 깊이 보려면
- E-values | Wikipedia — 개념 정리용 빠른 참조
- Beyond Neyman–Pearson: E-values enable hypothesis testing with a data-driven alpha | PNAS — 사후 유의수준 변경 가능성 이론
- False Discovery Rate Control with E-values | JRSS-B — e-BH 절차 원논문, 수식 중심
- Family-wise Error Rate Control with E-values | arXiv 2501.09015 — e-Bonferroni 완전 증명
- ICML 2025 Tutorial: Game-theoretic Statistics and Sequential Anytime-Valid Inference — 최신 연구 동향 한눈에 파악
- Sequential Testing on Statsig | Statsig Blog — CURE 포함 실무 구현 중심 케이스
- A tiny review on e-values and e-processes | Ruodu Wang, 2023 — 짧고 명확한 개념 정리 리뷰
- Regularized e-processes | arXiv 2410.01427 — 사전 지식 활용 효율 개선 최신 이론
- expectation Python 라이브러리 | GitHub — 예시 2 라이브러리 최신 API 확인용
- savvi Python 패키지 | PyPI — 예시 3 라이브러리 최신 API 확인용