'신뢰도가 높다'가 '정확하다'를 의미하지 않았다 — 2위와의 차이로 측정할 경우, 근거가 1건일 때 가장 크게 나타난다
요약
본 기사는 문서 분류 시스템의 신뢰도 측정 방식에 대한 문제점을 지적합니다. 초기 공식은 1위와 2위 간의 '마진(Margin)'만을 계산하여, 근거가 희박할 때도 과도하게 높은 신뢰도를 산출하는 오류를 범했습니다. 정확한 측정을 위해서는 단순히 차이가 아닌 '총 투표 점유율'로 측정 방식을 변경해야 합니다.
핵심 포인트
- 신뢰도는 1위와 2위의 차이(마진)만으로는 측정할 수 없습니다.
- 근거가 단 1건일 때, 공식은 가장 높은 신뢰도를 내는 오류를 범합니다.
- 측정 방식은 '차이'가 아닌 '총 투표 점유율'로 변경되어야 합니다.
직원이 임시 보관 폴더에 던져놓은 서류들을 매일 밤 모아서 올바른 선반으로 옮긴다.
이러한 시스템을 구축할 수 있는지 여부를, 실제 서류를 1바이트도 수정하지 않고 측정했습니다.
측정 방식은 이렇습니다. 1년 동안 배치된 파일들은 직원이 놓았던 장소가 그대로 정답입니다.
따라서 파일을 읽기만 해도 분류의 정확도를 산출할 수 있습니다.
전체적인 적중률(的中率)이 높지는 않습니다. 목적지가 약 2,700개의 폴더가 있고,
이 1년 동안 실제로 무언가가 들어간 선반으로만 한정해도 841가지 선택지입니다. 그 841가지 선택지에 대해,
파일 이름만으로 판별했을 때 **똑같은 선반에 들어가는 비율은 30.3%**였습니다
(바로 아래 카테고리만으로는 79.7%). 큰 틀은 맞추지만, 마지막 한 가지를 고르지 못합니다.
여기까지는 예상대로입니다. 전체가 낮더라도, 신뢰도가 높은 것들만 자동으로 움직이고,
나머지는 사람에게 맡기면 실용적이다라는 전제하에 신뢰도 구간별 적중률을 산출해 보니,
측정 방식 자체가 잘못되어 있었습니다.
증상: 신뢰도 '높음' 구간이 적중률을 반영하지 못한다
구간별 적중률은 다음과 같았습니다.
신뢰도 '높음' 구간 … 전체의 31.1%를 차지하며, 그 안에서의 적중률 54.6%
3건 중 1건이 '높음'에 속하는데, 맞는 경우는 절반을 조금 넘습니다.
이 상태로는 '여기부터는 자동화한다'라는 선을 그을 수 없습니다.
어디서 잘라도 비슷한 적중률이 나오고, 임계값(Threshold)이 분류에 도움이 되지 않습니다.
여기서 '정확도가 부족하다'라고 판단하는 것은 성급하다고 생각했습니다.
구간들이 적중률을 나누지 못하고 있다면, 그것은 정확도의 문제가 아니라 신뢰도를 만드는 방식의 문제일 수 있습니다.
분리 테스트: 단서를 늘려 오직 공식만 잘못되었음을 확인했다
판단 재료에 본문의 시작 부분을 추가했습니다. 결과는 다음과 같습니다.
전체 적중률 30.3% → 43.4% ( +13.1pt)
신뢰도 '높음' 구간 54.6% → 56.9% ( +2.3pt)
전체가 13포인트 상승했지만, 구간은 거의 움직이지 않았습니다.
단서가 부족하다면, 구간의 적중률도 함께 올라야 합니다. 오르지 않습니다.
이로써 범인은 단서가 아니라, 신뢰도를 산출하는 공식 쪽이라고 확정했습니다.
원인: 측정했던 것은 '2위를 얼마나 벌렸는가'였다
판단은 비슷한 서류 몇 건을 모아서 그 배치 장소에 투표시키는 형태입니다.
신뢰도는 처음에 다음과 같이 산출되었습니다.
# 초기 버전 (이것이 잘못되었다)
scores = sorted(bucket.values(), reverse=True) # 선반별 득표수
top = scores[0]
...
1위와 2위의 차이를 1위로 나눈 값, 이른바 마진(Margin)입니다.
이것은 1위가 2위를 얼마나 벌렸는지를 측정할 뿐, 1위가 올바른지 여부는 측정하지 않습니다.
그리고 더 심각한 성질이 있습니다. 위 코드를 다시 읽어보세요.
비슷한 서류가 단 1건만 발견되어 투표지가 하나밖에 없을 때, second는 0이므로 confidence는 1.0이 됩니다.
# 근거가 1건밖에 없을 때 (=가장 신뢰할 수 없을 때)
scores = [0.08] # 약한 유사도가 단 1건만
confidence = (0.08 - 0.0) / 0.08
...
즉, 근거가 가장 희박할 때, 가장 높은 신뢰도를 내는 방향의 공식이었습니다.
'높음' 구간에 믿을 수 없는 것들이 모여 들어갔던 것입니다.
구간을 올린다고 해도 적중률이 오르지 않는 것은 당연했습니다.
수정 방법: 차이가 아닌 '투표 점유율'로 변경한다
측정해야 할 것은 벌린 폭이 아니라, 근거가 분산되었는지 여부입니다.
분모를 '2위'가 아닌 '총 투표량'으로 바꿨습니다.
# 교체 후: 가중치 점유율
total = sum(bucket.values()) # 투표에 참여한 근처의 가중치 합계
top_key = max(bucket, key=bucket.get)
...
이 형태로 바꾸자,
- 여러 근처가 같은 선반을 추천했을 때만 올라가고 - 근거가 분산되어 있으면, 표가 분산되는 만큼 내려갑니다.
단 1건밖에 맞지 않았더라도, 분자에 들어가는 것은 그 1건만큼의 표뿐이므로,
총량이 적은 상태로 높은 점수를 받을 수 없습니다.
마진 공식이 가지고 있던 '후보가 하나면 만점'이라는 구멍이 구조적으로 사라집니다.
임계값과 적중률이 연동되게 되었다
교체 후, 임계값별로 '얻을 수 있는 양'과 '그 안에서의 정확도'는 다음과 같았습니다.
| 임계값 | 포착 비율 | 그 안에서의 정확도 |
|---|---|---|
| 0.5 | 47.0% | 70.1% |
| ... | ||
| 높일수록 정확도가 올라간다. 이로써 마침내, 선을 그을 재료로 사용할 수 있게 되었다. |
추가: 투표에 참여시키는 근처가 많다고 좋은 것은 아니었다
같은 장소에서 하나 더 시도해 보았습니다. 비슷한 서류를 많이 모을수록 판정은 좋아져야 하는데,
20건을 모아 투표하게 했을 때, 5건일 때보다 정확도가 떨어졌습니다.
원인은 목적지 선반의 세밀함 때문이었습니다. 20건이나 모으면, 정답 선반 옆에 있는 선반의 서류까지 들어와서,
표가 옆으로 흘러갑니다. 유사한 순위 상위 20건은 '정답과 비슷한 20건'이 아니라,
**'정답과 그 근처에서 비슷한 20건'**이었습니다.
투표에 참여시키는 근처 20건 → 5건 에서 38.7% → 43.4%
상위 5건은 선반을 넘기 전에 끊어지므로, 옆에서 유입되는 혼입이 줄어듭니다.
신뢰도를 점유율로 바꾼 경우와도 궁합이 좋아서, 분모가 작기 때문에,
근거가 분산되었는지 여부가 명확하게 나옵니다.
측정 방식 자체를 먼저 의심했다
여담이지만, 이 측정에서는 미래를 엿보지 않도록 공을 들였습니다.
과거 데이터로 측정하면, 방치해 두면 엿보게 됩니다. 어떤 파일을 판정할 때,
그 후에 놓인 파일을 참고하게 되면, 실제 본문에는 존재하지 않는 단서로 맞추게 되는 것입니다.
- 판정은 시간 순서대로 진행하고,
색인에 추가하는 것은 판정 이후에만 - 어휘의 희귀도(IDF) 통계 역시,
측정 기간보다 이전 파일들로부터만 만들었습니다.
숫자를 좋게 만들기 위한 노력이 아니라, 숫자를 믿을 수 있게 만들기 위한 노력이었습니다.
이번처럼 '식이 망가졌다'고 단언하기 위해서는, 그 전제가 먼저 필요했습니다.
그럼에도 불구하고, 아직 조용히 움직이지 않는다
신뢰도를 0.9 이상으로 좁히면 91.9%의 정확도로 포착할 수 있습니다. 관문이었던 90%는 넘었습니다.
하지만 포착하는 건 6건에 1건이고, 그중에서도 10%가 채 안 되는 비율은 제외합니다.
제외하면 서류가 아무도 보지 않는 곳으로 가게 됩니다.
그래서 당분간은 이동하지 않고, 매일 밤의 제안 목록을 내는 것에만 했습니다.
숫자가 선을 넘었다는 것과, 조용히 움직여도 좋다는 것은 별개였습니다.
신뢰도를 스스로 만들 때는, 그 식이 무엇을 측정하고 있는지를 한 번 소리 내어 말하는 편이 좋다는 이야기였습니다. '2위와의 차이'는 자신감의 지표로 자연스럽게 보이지만,
측정하는 것은 정확도가 아니라 떨어진 폭이며, 게다가 후보가 1개일 때 최대화됩니다.
제작 기록에는 매년 같은 이름으로 만들어지는 보고서가 반드시 전년도 폴더로 가버리는 건과,
정답 선반이 그 시점에서 아직 비어있었던 것을 정확도의 이야기에서 분리한 것도 적혀 있습니다.
논의 (Discussion)

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn ML의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기