2026년 7월 10일 | 개발 공부
양성 샘플이 드문 분류 결과에서 다수 클래스 recall 0.98, 소수 클래스 recall 0.36을 봤다. 전체 accuracy는 높았고 산술평균으로 접은 값도 아주 나빠 보이지 않았다. 그런데 운영에서 놓치면 안 되는 쪽은 0.36이었다. G-mean은 Geometric Mean, 즉 기하평균의 줄임말이다. 이진 분류에서는 양성 recall과 음성 recall을 곱한 뒤 제곱근을 취해, 두 클래스가 함께 살아 있는지를 한 값으로 본다.
나는 처음에 G-mean을 Balanced Accuracy의 다른 표기쯤으로 생각했다. 둘 다 클래스별 recall을 보고 불균형 데이터의 착시를 줄이기 때문이다. 계산을 작은 숫자로 직접 해 보니 차이가 분명했다. Balanced Accuracy는 두 recall을 더해 평균내지만, G-mean은 둘을 곱한다. 그래서 한쪽이 크게 무너지면 높은 쪽 점수가 그 실패를 덜 가려 준다.
산술평균이 남기는 여유
Balanced Accuracy는 이진 분류에서 sensitivity와 specificity의 산술평균이다. sensitivity는 양성 recall, specificity는 음성 recall이라고 보면 된다. 0.98과 0.36을 더해 둘로 나누면 0.67이다. 이 값은 전체 accuracy보다 훨씬 솔직하지만, 0.98이 낮은 0.36을 어느 정도 끌어올릴 여지는 남는다.
G-mean은 같은 두 값을 sqrt(0.98 × 0.36)으로 계산해 약 0.594가 된다. 둘 중 하나가 낮으면 곱 자체가 작아진다. 특히 한쪽 recall이 0이면 다른 쪽이 0.99여도 결과는 0이다. 한 클래스를 완전히 포기한 모델은 균형 잡힌 분류기로 볼 수 없다는 판단이 계산식 안에 들어 있는 셈이다.
두 모델의 순서가 왜 더 선명해지나
모델 A의 두 recall이 0.98과 0.36이고, 모델 B는 0.82와 0.62라고 해 보자. Balanced Accuracy는 각각 0.670과 0.720이다. G-mean은 약 0.594와 0.713이다. 두 지표 모두 B를 고르지만, G-mean에서는 격차가 더 크게 보인다. A가 다수 클래스를 거의 다 맞힌 대가로 소수 클래스를 크게 놓쳤다는 사실을 곱셈이 더 강하게 반영하기 때문이다.
| 모델 | 다수 recall | 소수 recall | Balanced Accuracy | G-mean |
|---|---|---|---|---|
| A | 0.98 | 0.36 | 0.670 | 0.594 |
| B | 0.82 | 0.62 | 0.720 | 0.713 |
이 차이는 “G-mean이 언제나 더 좋은 지표”라는 뜻은 아니다. 두 클래스의 recall을 비슷하게 유지하는 일이 제품 목표와 맞을 때 유용하다는 뜻에 가깝다. 사기 탐지, 장애 감지, 희귀 이벤트 선별처럼 한쪽을 통째로 놓치는 모델이 위험하다면 G-mean의 강한 벌점이 판단과 잘 맞는다. 반대로 실제 트래픽 비용이 클래스 support에 비례한다면 weighted 지표를 함께 봐야 한다.
F1과 같은 기하평균은 아니다
이름 때문에 또 하나 헷갈리기 쉬운 부분이 있다. F1은 precision과 recall의 조화평균이고, G-mean은 클래스별 recall의 기하평균이다. F1은 모델이 양성이라고 꺼낸 결과의 품질과 실제 양성을 건진 비율을 함께 묻는다. G-mean은 양성과 음성을 각각 자기 클래스라고 놓았을 때 두 recall이 동시에 유지되는지를 묻는다.
따라서 false positive 비용이 특별히 큰 문제에서는 G-mean 하나로 충분하지 않다. specificity가 false positive를 반영하긴 하지만, 업무 비용의 비대칭을 직접 표현하지는 않는다. precision, PR curve, class별 비용표를 같이 봐야 한다. 나는 지표 이름이 비슷하다는 이유로 한 줄에 나란히 놓기보다, 각 지표가 어떤 실패를 벌주는지를 먼저 적는 편이 덜 헷갈렸다.
0점이 알려 주는 것과 알려 주지 않는 것
G-mean이 0이면 보통 한 클래스의 recall이 0이라는 강한 신호다. 이때 작은 상수를 더해 점수를 보기 좋게 만드는 방식은 보고용 평가에서는 피하는 편이 낫다. 수치가 0인 이유가 모델의 완전한 실패라면 그대로 드러내야 한다. threshold를 조정하거나 class weight, sampling, feature, label 정의를 다시 보는 것이 먼저다.
다만 평가 split에 양성 샘플이 아예 없다면 recall 0과는 다른 문제다. 이 경우 recall 자체가 정의되지 않는다. 라이브러리가 경고와 함께 0을 넣었다고 해서 모델이 모두 놓쳤다고 단정하면 안 된다. stratified split을 다시 확인하고, 해당 클래스 support가 0이어서 계산할 수 없었다고 따로 기록해야 한다. 모델 실패와 평가 데이터 부재를 같은 0으로 합치지 않는 것이 중요하다.
내가 평가표에 남기는 기준
불균형 이진 분류 리포트에는 G-mean만 단독으로 올리지 않는다. 먼저 양성·음성 support와 class별 recall을 적고, 전체 accuracy와 Balanced Accuracy, G-mean을 나란히 둔다. 양성 후보를 사람이 검토하는 작업이면 precision과 PR curve도 붙인다. threshold는 validation set에서 정한 값인지, test 결과를 본 뒤 고른 값인지 함께 적는다.
모델 비교에서는 평균 점수의 소수점 셋째 자리보다 두 recall의 모양을 먼저 본다. G-mean이 올랐더라도 다수 클래스 recall을 과하게 희생해 업무량이 폭증했다면 그대로 채택하지 않는다. 반대로 accuracy가 조금 내려가도 소수 클래스 recall이 크게 회복되고 G-mean이 안정적으로 오르면 후보로 남긴다. 여러 seed나 bootstrap 구간에서도 같은 방향인지 확인하면 우연한 몇 건에 끌릴 가능성을 줄일 수 있다.
G-mean이 유용했던 지점은 계산식보다 질문을 바꿔 준 데 있었다. “전체적으로 얼마나 맞혔나”에서 멈추지 않고, “두 클래스 중 하나를 사실상 버린 것은 아닌가”를 먼저 묻게 한다. Balanced Accuracy와 답이 비슷하게 나오는 날도 많지만, 한쪽 recall이 급락한 실험에서는 곱의 제곱근이 실패를 더 선명하게 남긴다. 나는 그 차이를 모델 선택의 결론보다 추가 확인을 시작하는 경고등으로 쓰고 있다.
'[개발 공부]' 카테고리의 다른 글
| Youden's J: Sensitivity와 Specificity가 만나는 임계값 (1) | 2026.07.14 |
|---|---|
| F-beta score: Precision과 Recall의 무게를 바꾸는 지표 (0) | 2026.07.13 |
| Micro F1와 Accuracy가 겹치는 지점 (0) | 2026.07.06 |
| Macro F1: 클래스별 성능을 따로 평균낸 값 (0) | 2026.07.05 |
| Cohen's Kappa: 우연 일치가 만든 정확도 착시 (0) | 2026.07.03 |