정확도 98%의 함정 — 불량 121개 중 110개를 놓친 모델 이야기
보고서에는 정확도 97.98%가 올라갑니다. 현장에는 '불량 121개 중 110개를 놓쳤다'가 갑니다. 같은 모델의 이야기입니다.
소수점까지 똑같은 두 '모델'
CNC 정밀가공 라인의 최종검사 기록 30,000건이 있습니다. 불량은 606건, 불량률 2.02%입니다. 품질팀의 요청은 간단합니다 — "불량을 미리 잡아주는 모델을 만들어 주세요. 검사 인력이 부족합니다."
랜덤포레스트 300그루를 학습시킵니다. 결과는 정확도 97.98%. 꽤 훌륭해 보입니다.
그런데 옆자리 동료가 장난삼아 '모델'을 하나 만듭니다. 데이터를 보지도 않고 무조건 "정상"이라고만 답하는 한 줄짜리 프로그램입니다. 그 정확도는 97.98%. 소수점 네 자리까지 정확히 같습니다.
거짓말이 아닙니다. 불량률이 2%면 전부 정상이라고 답하는 것만으로 정말 98%를 맞힙니다. 다만 그 숫자는 우리가 궁금한 것 — 불량을 잡아내는 능력 — 을 하나도 알려주지 않을 뿐입니다. 현업 데이터는 거의 언제나 이렇게 한쪽으로 쏠려 있습니다. 불량률 2%, 이탈률 5%, 사기 거래 0.1%. 그리고 우리가 정말로 맞히고 싶은 것은 언제나 그 적은 쪽입니다.
혼동행렬의 네 칸부터
정확도라는 숫자 하나로는 이 상황을 구분할 수 없습니다. 그래서 모든 분류 평가는 혼동행렬(confusion matrix)에서 출발합니다. 예측 결과를 네 칸으로 분해하는 표입니다. 불량 검출을 예로 들면 이렇습니다.
- TP (True Positive, 진짜 양성) — 불량을 불량이라고 맞혔다 ✓
- FP (False Positive, 거짓 양성) — 정상을 불량이라고 했다 ✗ (헛경보)
- FN (False Negative, 거짓 음성) — 불량을 정상이라고 놓쳤다 ✗ (고객에게 흘러간다)
- TN (True Negative, 진짜 음성) — 정상을 정상이라 맞혔다 ✓
외우는 요령이 있습니다. 두 번째 단어(Positive/Negative)가 모델이 뭐라고 했는지, 첫 번째 단어(True/False)가 그 말이 맞았는지입니다. False Negative는 "Negative(정상)라고 했는데 그게 False(틀렸다)" — 즉 불량을 놓친 것입니다.
정확도는 이 네 칸 중 맞은 두 칸만 봅니다 — 정확도 = (TP + TN) / 전체. 문제는 불균형 데이터에서 TN이 압도적으로 많다는 것입니다. 불량이 2%뿐이라면 TN이 될 수 있는 표본이 98%입니다. 아무것도 하지 않아도 TN이 정확도를 다 채워줍니다. 이것이 정확도의 역설(accuracy paradox)입니다. 소수 클래스가 중요한 문제 — 불량 검출, 사기 탐지, 질병 진단, 이탈 예측 — 에서 정확도는 거의 언제나 쓸모없는 지표가 됩니다.
정확도 97.98% 뒤에 숨은 숫자
이제 앞의 랜덤포레스트를 혼동행렬로 다시 채점해 봅니다. 테스트 데이터 6,000행에는 불량이 121개 들어 있습니다. 임계값 0.5 기준 성적표는 이렇습니다.
- "전부 정상"이라고 답하기 — 정확도 0.9798 · 재현율 0.000 · 정밀도 0.000 · 놓침 121개 전부
- 랜덤포레스트 (임계값 0.5) — 정확도 0.9798 · 재현율 0.091 · 정밀도 0.500 · 적발 11 · 헛경보 11 · 놓침 110
재현율 0.091 — 불량 121개 중 11개를 잡았다는 뜻입니다. 나머지 110개는 그대로 고객에게 갑니다. 정확도 97.98%라는 숫자 뒤에 '121개 중 110개를 놓쳤다'가 숨어 있는 것입니다. 보고서에는 앞의 숫자가 올라가고, 현장에는 뒤의 숫자가 갑니다.
흥미로운 것은 정밀도 0.500입니다. 모델이 경보를 울린 22개 중 11개가 진짜 불량이었습니다. 모델이 확신을 갖고 말할 때는 절반이 맞는다는 뜻이고, 모델이 아무것도 배우지 못한 게 아니라는 첫 번째 힌트입니다. 실제로 이 모델이 매긴 불량 확률 상위 50개를 뽑아보면 23개가 진짜 불량입니다. 무작위로 50개를 골랐다면 1개였을 겁니다. 모델이 무능한 게 아니라, 정확도라는 저울이 그 능력을 보여주지 못했던 것입니다.
정밀도와 재현율 — 서로 다른 질문에 답한다
다른 도메인에서도 같은 일이 반복됩니다. 카드사의 이상거래 탐지를 봅니다. 거래 5,000건 중 사기는 152건(3.04%)입니다. "전부 정상"이라고 찍기만 해도 정확도 0.9696이 나오는 데이터입니다. 외주 업체 네 곳이 모델을 만들어 왔고, 그중 두 모델의 성적이 이렇습니다.
- 모델A — 정확도 0.9696, 잡은 사기 0건 / 152건. 단 한 건도 사기라고 예측하지 않았습니다. 정확도가 "전부 정상 찍기"와 소수점까지 같은, 아무 일도 하지 않는 모델입니다.
- 모델C — 정확도 0.8230으로 네 모델 중 꼴찌. 그런데 잡은 사기는 128건 / 152건으로 최다입니다. 대신 정상 거래 861건을 사기로 의심(FP)했습니다.
정확도만 보면 모델A가 모델C를 압도합니다. 사기를 잡는다는 목적으로 보면 정반대입니다. 그래서 혼동행렬의 네 칸을 조합한 지표들이 필요합니다. 각 지표는 서로 다른 질문에 답합니다.
- 정밀도(Precision) = TP / (TP + FP) — "사기라고 부른 것 중 진짜는 몇 %인가?" 헛수고를 줄이고 싶을 때 봅니다.
- 재현율(Recall) = TP / (TP + FN) — "진짜 사기 중 몇 %를 잡았나?" 놓치면 안 될 때 봅니다. 암 진단, 사기 탐지, 불량 검출이 여기에 해당합니다.
- F1 — 정밀도와 재현율의 조화평균. 정밀도 1.0에 재현율 0.0이면 산술평균은 0.5로 그럴듯해 보이지만, F1은 0.0입니다. 한쪽만 극단으로 올리는 꼼수를 허용하지 않습니다.
정밀도와 재현율은 거래 관계입니다. 공격적으로 예측하면 재현율이 오르고 정밀도가 떨어지며, 보수적으로 예측하면 반대가 됩니다. 어느 쪽에 무게를 둘지는 지표가 아니라 비용이 정합니다 — 불량 하나를 놓치는 손실이 큰가, 헛경보 하나의 비용이 큰가.
보고서를 받으면 가장 먼저 물어볼 것
누군가 "정확도 97%입니다"라고 말할 때, 그 숫자가 자랑스러워서가 아니라 다른 지표를 보여주고 싶지 않아서일 수 있습니다. 그래서 첫 질문은 언제나 이것이어야 합니다. "혼동행렬을 보여주세요." 네 칸을 보면 모델이 실제로 무엇을 하고 있는지 숨길 수 없습니다.
정리하면 이렇습니다. 정확도는 데이터가 균형 잡혀 있을 때만 믿을 수 있는 지표입니다. 불균형 데이터에서는 반드시 혼동행렬을 열고, 재현율("놓치면 안 되는 것을 몇 % 잡았나")과 정밀도("경보 중 진짜가 몇 %인가")를 나란히 봐야 합니다. 그 두 숫자 사이의 균형은 수식이 아니라 업무의 비용 구조가 정해줍니다.
이 글은 DataForge 교육 과정 원고에서 발췌·각색했습니다. 아래 시뮬레이터에서 임계값을 직접 움직여 보면 정확도·정밀도·재현율·F1이 어떻게 서로 밀고 당기는지 눈으로 확인할 수 있습니다.
📊 평가지표 시뮬레이터에서 직접 확인하기 →