2026년 6월 15일 | 개발 공부
세 개 이상의 운영 로그를 한꺼번에 비교하면, 제일 먼저 헷갈리는 지점이 “전체 차이가 있다”와 “A와 B가 다르다” 사이의 간격이다. Kruskal-Wallis 검정은 이 간격의 앞부분만 답한다. 독립적인 여러 그룹의 값이 같은 분포에서 나온 것처럼 보이는지, 아니면 적어도 한 그룹이 rank 기준으로 밀려 보이는지를 먼저 묻는다. 그런데 실무에서 내가 더 자주 궁금한 것은 그다음이다. 어느 쌍이 실제로 멀어졌는지, 그 차이를 여러 번 비교했다는 사실까지 반영해도 믿을 만한지다.
Dunn 사후검정은 이 두 번째 질문으로 내려갈 때 쓰는 도구다. 이름은 조금 낯설지만 역할은 단순하다. Kruskal-Wallis로 전체 신호를 본 뒤, 그룹 쌍을 하나씩 열어 평균 rank 차이가 얼마나 큰지 계산하고, 그 쌍별 p-value를 만든다. 그리고 Holm-Bonferroni 같은 보정과 함께 읽는다. 나는 이 흐름을 전체검정과 쌍별검정을 분리하는 습관으로 기억하는 편이다.
전체 신호 뒤에 남는 질문
예를 들어 세 개의 검색 설정 A, B, C가 있다고 하자. 세 설정은 같은 query set을 통과한 paired 실험이 아니라, 서로 다른 기간에 쌓인 독립 로그다. A는 내부 테스트, B는 베타 사용자, C는 공개 데모에서 나온 값일 수 있다. 이 상황에서 평균 nDCG나 성공률만 보고 “B가 제일 좋다”라고 말하면 로그 구성 차이를 너무 쉽게 성능 차이로 읽게 된다. 그래서 먼저 Kruskal-Wallis로 전체 값을 한 줄에 세우고 rank가 그룹별로 치우쳤는지 본다.
문제는 전체 검정이 유의하게 나와도 결론이 아직 비어 있다는 점이다. 유의하다는 말은 세 그룹이 모두 서로 다르다는 뜻이 아니다. A와 B만 벌어졌을 수도 있고, B와 C만 다를 수도 있고, 한쪽 outlier가 전체 rank를 밀었을 수도 있다. 이때 Dunn 사후검정은 A-B, A-C, B-C처럼 쌍별 rank 차이를 다시 열어 준다. 그래서 “전체적으로 뭔가 있다”를 “어느 쌍을 더 봐야 한다”로 좁히는 데 도움이 된다.
이 흐름은 Friedman 검정 뒤에 Nemenyi 사후검정을 붙이는 그림과 닮았다. 다만 Friedman-Nemenyi 쪽은 같은 block 안에서 여러 설정을 반복 측정했다는 전제가 강하고, Kruskal-Wallis-Dunn 쪽은 독립 표본 구조를 더 자연스럽게 다룬다. 그래서 나는 사후검정 이름을 외우기보다 먼저 표의 모양을 본다. 같은 query가 모든 설정에 반복해서 들어갔는가. 아니면 그룹마다 샘플이 따로 모였는가. 이 질문이 먼저다.
Dunn은 무엇을 다시 쓰는가
Dunn test를 거칠게 말하면, 전체 데이터에 붙인 rank 정보를 바탕으로 두 그룹의 평균 rank 차이를 비교한다. A와 B만 떼어 새로운 세상을 만드는 것이 아니라, 전체 그룹을 함께 rank로 세운 맥락을 유지한다. 이 점 때문에 “Mann-Whitney U test를 여러 번 돌리는 것과 뭐가 다른가”라는 질문이 나온다. 실제로 둘은 가까운 친척처럼 보이지만, Dunn은 Kruskal-Wallis 뒤의 post-hoc 흐름에 맞춰 전체 rank와 tie correction, 비교 family를 함께 의식한다.
실무에서는 이 차이를 너무 신비하게 볼 필요는 없다. 중요한 것은 같은 전체 비교에서 파생된 쌍별 질문이라는 사실을 결과표에 남기는 것이다. A-B p-value 하나만 복사해 두면, 나중에 그 값이 어떤 전체 검정 뒤에 나온 것인지, 몇 개 쌍을 같이 비교했는지, tie가 얼마나 있었는지 금방 사라진다. 반대로 전체 p-value, 쌍 이름, 보정 전 p-value, 보정 후 판정, 평균 rank 차이를 한 줄에 묶으면 해석이 덜 흔들린다.
tie도 생각보다 자주 나온다. 평가 metric이 정수형 점수거나 성공/부분성공/실패처럼 단계가 적으면 같은 값이 많이 생긴다. rank 기반 검정은 tie를 보정할 수 있지만, tie가 많다는 사실 자체는 결과 해석의 배경이다. 예를 들어 세 그룹 모두 0점이 많고 일부 샘플만 높은 점수를 받는 구조라면, 유의한 쌍이 나와도 “전반적으로 좋아졌다”보다 “상위 꼬리에서 차이가 났다”에 가까울 수 있다.
보정 없이는 별표가 너무 쉽게 붙는다
Dunn 사후검정을 열면 비교 수가 바로 늘어난다. 그룹이 세 개면 쌍이 세 개지만, 다섯 개면 열 개가 된다. 각 쌍을 독립적으로 0.05 기준에 걸어 두면, 실제 차이가 없어도 어딘가 하나쯤은 별표가 붙을 확률이 올라간다. 그래서 Dunn 결과는 보통 Holm-Bonferroni, Bonferroni, Benjamini-Hochberg 같은 multiple-comparison 보정과 같이 읽는다.
내 기준에서는 Holm-Bonferroni가 제일 손에 잘 잡힌다. p-value를 작은 순서로 세우고, 앞쪽 값일수록 더 엄격하게 본다. 어느 지점에서 멈추면 그 뒤는 더 이상 유의하다고 말하지 않는다. 이 방식이 완벽해서라기보다, 비교 family를 결과 해석 전에 고정하게 만드는 장점이 있다. “이번 표에서 비교한 쌍이 정확히 무엇인가”를 먼저 적게 만든다.
다만 보정 후 reject 여부가 결론을 대신하지는 않는다. 작은 p-value는 차이가 없다는 가설과 맞지 않는다는 신호이지, 차이가 업무적으로 크다는 뜻은 아니다. 그래서 Dunn 표 옆에는 효과 크기와 샘플 구성을 함께 둔다. 두 그룹씩 내려가면 Cliff's delta처럼 승패 비율을 보는 값이 도움이 되고, median과 IQR, 그룹별 샘플 수, 수집 기간도 같이 적어 둔다.
내가 남기는 결과표 모양
평가 노트에 Dunn 사후검정을 붙일 때 나는 보통 표를 넓게 만들지 않는다. 열은 여섯 개 정도면 충분하다. 비교 쌍, 평균 rank 차이, 보정 전 p-value, 보정 후 p-value 또는 reject 여부, 효과 크기, 짧은 해석 메모다. 해석 메모에는 “B가 항상 우세” 같은 결론보다 “B-C만 보정 후 유지, A-B는 불명확, C의 낮은 점수 꼬리 확인”처럼 다음 확인 지점을 적는다.
이 작은 메모가 생각보다 중요하다. 사후검정 결과는 사람을 자꾸 순위표로 끌고 간다. 그런데 운영 로그에서는 승자 하나보다 어떤 조건에서 차이가 생겼는지가 더 중요할 때가 많다. 베타 사용자 로그에서만 B가 높다면 모델 차이보다 사용자군 차이일 수 있고, 특정 시간대에 C가 낮다면 인프라 이슈일 수 있다. Dunn 결과는 이런 가지를 줄이는 필터이지, 마지막 판정문이 아니다.
또 하나 남기는 항목은 “왜 paired 분석을 못 했는가”다. 같은 query set이 있다면 Kruskal-Wallis-Dunn으로 가기 전에 Friedman, paired permutation, Wilcoxon 같은 길을 먼저 본다. paired 정보는 query 난이도라는 큰 잡음을 줄여 주기 때문이다. 독립 표본 검정은 필요한 도구지만, 짝 구조를 만들 수 있는데도 버리면 정보 손실이 된다.
쓰지 않는 쪽이 나은 경우
Dunn 사후검정을 쓰지 않는 상황도 꽤 선명하다. 첫째, 그룹별 수집 조건이 너무 다르면 통계 검정보다 데이터 정의를 먼저 고쳐야 한다. A는 쉬운 query, B는 어려운 query, C는 실패 사례만 모은 표라면 rank 차이는 모델 성능보다 샘플링 편향을 크게 반영한다. 둘째, 비교하려는 값이 거의 이산 라벨 몇 개로만 되어 있어 tie가 과도하면, rank 검정 결과를 더 조심해서 읽어야 한다.
셋째, 이미 특정 두 설정의 차이가 중심 질문이라면 굳이 전체 검정부터 열 필요가 없을 수 있다. A와 B의 같은 query별 delta를 보고 싶은데 C, D까지 끌어와 전체 family를 만들면 질문이 흐려진다. 이때는 paired permutation이나 bootstrap confidence interval이 더 직접적이다. 검정법은 많이 붙일수록 좋아지는 것이 아니라, 질문과 표 모양이 맞을수록 좋아진다.
그래서 나는 Dunn 사후검정을 “Kruskal-Wallis가 유의하면 자동으로 누르는 다음 버튼”으로 보지 않는다. 먼저 독립 그룹 구조가 맞는지 보고, 전체 차이 신호가 있는지 보고, 그다음 쌍별 rank 차이를 보정과 함께 좁혀 본다. 마지막에는 p-value보다 어떤 쌍을 다시 조사할지가 남아야 한다. 그래야 통계표가 결론을 빨리 닫는 장치가 아니라, 다음 디버깅 범위를 줄이는 장치가 된다.
짧게 정리하면 Dunn 사후검정은 Kruskal-Wallis 뒤에서 “어느 두 그룹이 멀어졌는가”를 묻는 쌍별 rank 비교다. 전체 신호, 보정, 효과 크기, 샘플 구성 메모를 함께 두면 운영 로그에서도 꽤 실용적이다. 반대로 이 네 가지가 빠진 별표 하나만 남으면, 나중에 다시 열었을 때 거의 아무것도 설명하지 못한다.
'[개발 공부]' 카테고리의 다른 글
| Welch ANOVA: 분산이 다른 세 그룹 비교 (0) | 2026.06.17 |
|---|---|
| Hodges-Lehmann 추정량: p-value 옆 중앙 차이 (0) | 2026.06.16 |
| Kruskal-Wallis 검정: 독립 세 묶음 rank 비교 (0) | 2026.06.12 |
| Nemenyi 사후검정: Friedman 다음 쌍별 rank 비교 (0) | 2026.06.11 |
| Kendall's W: Friedman 검정 옆 효과 크기 (0) | 2026.06.04 |