[개발 공부] / TOST 등가성 검정과 허용 폭.md

TOST 등가성 검정과 허용 폭

조회

2026년 6월 25일 | 개발 공부


TOST(two one-sided tests) 등가성 검정은 “두 설정이 정말 다른가”가 아니라 “정해 둔 허용 폭 안에 들어왔다고 말해도 되는가”를 묻는 절차다. 나는 모델 평가표를 볼 때 p-value가 크면 무심코 “차이 없음”에 가까운 문장으로 접어 버릴 때가 있었는데, 이 검정은 그 습관을 꽤 불편하게 만든다. 차이가 없다는 말은 실패한 유의성 검정에서 자동으로 나오지 않고, 먼저 허용 가능한 차이의 폭을 사람이 정해야 나온다.

TOST 등가성 검정에서 허용 하한, 관측 차이, 허용 상한을 같은 축에 놓고 판단하는 도식
Figure 1. TOST는 관측 차이만 보는 검정이 아니라, 허용 폭과 신뢰구간을 같은 축에 놓고 판단하는 절차에 가깝다.

p-value가 크다는 말의 빈칸

일반적인 차이 검정은 보통 “두 평균이 같다”는 귀무가설을 세우고, 관측된 차이가 우연으로 보기 어려운지를 본다. 여기서 p-value가 작으면 차이가 있다는 쪽으로 말을 열 수 있다. 문제는 반대 방향이다. p-value가 크다고 해서 두 설정이 충분히 비슷하다는 뜻은 아니다. 샘플이 적거나 분산이 크거나 평가 metric이 둔하면, 꽤 큰 차이도 그냥 못 잡고 지나갈 수 있다.

그래서 등가성 검정은 질문을 뒤집는다. “차이가 0인가?”가 아니라 “차이가 -δ와 +δ 사이에 있다고 말할 만큼 근거가 있는가?”를 묻는다. 여기서 δ는 통계 패키지가 대신 정해 주는 숫자가 아니라 내가 업무 기준으로 정해야 하는 숫자다. 예를 들어 retrieval 평가에서 NDCG 0.002 차이는 무시해도 되지만 0.02 차이는 운영 판단을 바꾼다고 생각한다면, margin도 그 감각에서 출발해야 한다.

허용 폭을 정할 때는 “이번 실험에서 보고 싶은 차이”보다 “운영 의사결정이 바뀌는 차이”를 먼저 본다. metric이 accuracy라면 0.5%p가 의미 있을 수 있고, latency라면 20ms가 사용자 체감선일 수 있다. 반대로 embedding recall처럼 downstream reranker가 한 번 더 걸러 주는 지표라면 작은 흔들림을 그대로 제품 차이로 부풀리면 안 된다. 나는 그래서 margin을 표에 적을 때 단위를 꼭 붙인다. ±0.01, ±20ms, ±2%p처럼 단위를 남겨야 나중에 다른 사람이 같은 숫자를 보고도 “무엇을 같은 것으로 봤는지”를 다시 열 수 있다.

두 개의 단측 검정으로 보는 이유

TOST는 이름 그대로 두 개의 one-sided t test를 붙인다. 하나는 차이가 너무 낮은 쪽으로 밀리지 않았는지 보고, 다른 하나는 차이가 너무 높은 쪽으로 밀리지 않았는지 본다. 둘 다 통과해야 관측 차이가 허용 구간 안에 있다고 말할 수 있다. statsmodels 문서도 이 절차를 독립 표본에서는 ttost_ind, paired sample에서는 ttost_paired로 나눠 제공하고, 귀무가설을 “차이가 하한보다 작거나 상한보다 크다”로 둔다.

from statsmodels.stats.weightstats import ttost_paired

pvalue, lower_test, upper_test = ttost_paired(
    baseline_scores,
    candidate_scores,
    low=-0.01,
    upp=0.01,
)

이 코드에서 눈이 먼저 가야 하는 값은 함수 이름보다 lowupp다. 허용 폭을 나중에 결과에 맞춰 고르면 등가성 검정은 방어막이 아니라 결론 꾸미기가 된다. 실험을 시작하기 전에 metric 단위, 사용자 영향, 반복 측정 단위를 같이 보면서 “이 정도 차이는 같은 모델로 취급하겠다”는 선을 적어 두는 편이 안전하다.

margin을 정할 때 내가 제일 먼저 보는 것은 평균 점수표가 아니라 실패했을 때의 의사결정 비용이다. 후보 모델이 0.003 좋아졌지만 디버깅 시간이 두 배로 늘거나, 반대로 0.004 낮아졌지만 추론 비용이 절반으로 줄어드는 경우가 있다. 이런 상황에서는 통계적으로 보이는 차이보다 “바꿀 이유가 충분한가”가 더 실제적인 질문이 된다. TOST는 그 질문을 숫자로 닫게 해 주지만, 숫자 자체는 여전히 사람이 책임져야 한다. 그래서 나는 margin 옆에 “왜 이 폭인가”를 한 줄로 붙여 둔다. 나중에 모델이 바뀌거나 평가셋이 커졌을 때, 그 한 줄이 통계 결론보다 먼저 재검토 기준이 된다. 실험 노트에서는 이 사유가 나중의 재현성을 살린다. 작은 기준일수록 기록이 더 필요하다.

paired 평가에서는 더 조심스럽다

모델 A와 B를 같은 query set 위에서 비교했다면 독립 표본처럼 다루기보다 query별 차이를 먼저 만든다. 같은 입력에서 두 모델이 같이 어려워하거나 같이 쉬워하는 구조가 있기 때문이다. 이때 평균 차이 하나만 보면 편하지만, 실제로는 일부 query가 전체 평균을 끌고 갔는지, 특정 도메인에서만 후보 모델이 밀리는지까지 같이 봐야 한다.

내가 평가표에 붙이고 싶은 최소 묶음은 네 가지다. 첫째, paired difference의 평균과 중앙값. 둘째, TOST margin. 셋째, paired bootstrap confidence interval. 넷째, outlier query 몇 개의 원문 또는 식별자다. TOST가 통과하더라도 특정 입력군에서만 계속 실패한다면 “등가”라는 표현은 전체 평균 수준에서만 조심스럽게 써야 한다. 그래서 이 검정은 paired permutation test나 bootstrap confidence interval을 대체하기보다 옆에 붙는 판단 장치에 가깝다.

보고서에 남길 문장

등가성 검정을 쓴 날의 보고 문장은 짧아도 숫자 순서가 중요하다. “두 모델은 차이가 없었다”보다 “사전에 정한 ±0.01 margin 안에서 paired TOST를 통과했고, 평균 차이는 0.003이었다”가 낫다. 통과하지 못했다면 “차이가 있다”로 바로 바꾸지 말고 “등가라고 말할 근거가 부족했다”라고 적는 쪽이 더 정확하다. 이 차이를 놓치면 비유의성, 비열등성, 등가성이 한 문장 안에서 뒤섞인다.

TOST의 장점은 결론을 크게 만들어 주는 데 있지 않고, 작아 보이는 차이를 어디까지 작다고 부를지 미리 말하게 만드는 데 있다. 개인 프로젝트든 논문 재현이든 모델 후보를 갈아 끼우는 작업에서는 이 선을 자주 놓친다. 다음부터는 “p-value가 안 작다”는 문장을 쓰기 전에, 내가 정말 묻고 싶은 것이 차이 검정인지 등가성인지 먼저 한 번 멈춰 보려고 한다. 참고로 statsmodels의 paired TOST 문서independent sample TOST 문서는 귀무가설과 인자 이름을 확인할 때 가장 빨리 열기 좋았다.

댓글

홈으로 돌아가기

검색 결과

"" 검색 결과입니다.