히비스서커스의 블로그

[CellPin] Trouble Shooting (feat: Accuracy, Precision, Recall이 모두 똑같은 경우) 본문

ETC/개발 로그

[CellPin] Trouble Shooting (feat: Accuracy, Precision, Recall이 모두 똑같은 경우)

HibisCircus 2021. 6. 2. 23:52
728x90

6주간 진행되는 해커톤3에서 4주차 째 모델 선정까지 끝나고 Flask에서 웹페이지를 만들기 중반부에 접어들었을 무렵 매우 큰 오류를 발견하게 된다. 바로  Accuracy, Precision, Recall 값이 0.9192로 모두 동일했다. 확실하게 문제가 있다고 느꼈고 하나하나 파헤쳐가기 시작했다. 

 

 

Accuracy, Precision, Recall 값이 동일한 경우 ?

Accuracy, Precision, Recall의 의미를 알기 위해서는 confusion matrix를 알아야 한다.

 

  Predicted Class (예측)
Positive Negative
Actual Class (실제) Positive True Positive (TP)
정답을 정답으로 예측
False Negative (FN)
정답을 오답으로 예측
Negative False Positive (FP)
오답을 정답으로 예측
True Negative (TN)
오답을 오답으로 예측

이해하기 쉽게

  • 앞에 T가 붙으면 예측이 맞은 것, F가 붙으면 예측이 틀린 것
  • 뒤에 P가 붙으면 정답으로 예측, N이 붙으면 오답으로 예측

 

이제 Accuracy, Precision, Recall이 무엇인지 알아보자.

 

$ Accuracy = \frac{TP + TN}{TP + FN + FP + TN} $

 

$ Precision = \frac{TP}{TP + FP} $

 

$ Recall = \frac{TP}{TP + FN} $

 

 

여기서 Accuracy, Precision, Recall 이 0과 1이 아닌 이 사이의 값을 가진다?!

 

1. FP 와 FN이 같아야 한다.

  • Precision = Recall에서 양변에 $TP(TP + FP)(TP + FN)$을 곱해주면 $TP + FP = TP + FN$이 되어 $FP = FN$이 된다.

2. TN과 TF가 같아야 한다.

  • Accuracy에 FP = FN임을 이용하여 나타내주면$ Accuracy = \frac{TP + TN}{TP + 2FN + TN} $
  • Accuracy = Recall에서 양변에 $(TP + TN + 2FN)(TP + FN)$을 곱해주면

$ \frac{TP + TN}{TP + 2FN + TN} = \frac{TP}{TP + FN}$

$ TP^2 + TN*TP + TP*FN + TN*FN = TP^2 + TP*TN + 2TP*FN$

$TN = TF$

 

 

문제 해결을 위해 아래와 같은 두 개의 변환을 적용해보았다.

 

Loss Function의 변환 => 해결 X

먼저 loss function을 변환해보았다. 기존에 쓰던 loss function은 'binary_crossentropy'인데 이를 'categorical_crossentropy'로 바꾸어주었다. 그러나 결과는 똑같았다.

 

Labeling의 변환 => 해결 O

우리 팀이 이미지에 대해 labeling을 한 것은 리스트 형태로 Positive(CPE) :: [0, 1], Negative(Normal) :: [1, 0]과 같았다. 결론적으로 Model을 평가할 때 keras의 Precision(tf.keras.metrics.Precision)이나 Recall(tf.keras.metrics.Recall)을 쓰지 않고 코드로 직접 구해주는 것이 좋다고 한다. 우리 팀은 labeling을 Boolean 형태로 바꾸어주기로 하였다. Positive(CPE) :: True, Negative(Normal) :: False로 하여 주자 정상적으로 Precision과 Recall값이 나오게 되었다.

 

 

그렇다면 왜? 도대체 왜! 라벨링을 위와 같이 해줄경우 Precision과 Recall이 Accuracy와 동일한 형태가 나오는 것일까?

 

이를 알아보기 위해 실험을 해보았다.

 

1. 모델로  Positive data만 예측해보기

결과: 117개 중 107개를 Positive로 10개를 Negative로 예측하였다

 

2. 모델로 Negative data만 예측해보기

결과: 143개 중 11개를 Positive로 예측하고 132개를 Negative로 예측하였다.

 

3. 이때의  confusion matrix Accuracy, Precision, Recall 구하기

 

  Predicted Class (예측)
Positive Negative
Actual Class (실제) Positive True Positive (TP)
정답을 정답으로 예측
107
False Negative (FN)
정답을 오답으로 예측
10
Negative False Positive (FP)
오답을 정답으로 예측
11
True Negative (TN)
오답을 오답으로 예측
132

$ Accuracy = \frac{TP + TN}{TP + FN + FP + TN} = \frac{107 + 132}{107 + 10 + 11 + 132} = 0.9192$

 

$ Precision = \frac{TP}{TP + FP} = \frac{107}{107 + 11} = 0.9068$

 

$ Recall = \frac{TP}{TP + FN} = \frac{107}{107 + 10} = 0.9145$

 

즉, 모든 값이 다르게 나와야 하지만 Accuracy 값으로 Precision과 Recall값이 대체되었다. 

 

 

추가로 test data 전체의 TP, NF, TF, NP의 값을 모두 찍어보았다. (ex. tf.keras.metrics.TruePositive)

 

TP = TN = 239 (이는 위에서 TP + TN의 값이다.)

FN = FP = 21 (이는 위에서 FN+ FP의 값이다.)

 

위와 같은 결과가 나왔는데 TP와 TN을 더한 값으로 TP와 TN이 동일하게 나왔고, 마찬가지로 FN과 FP를 더한 값으로 FN과 FP이 동일하게 나왔다. 이는 위에서 보았듯이 Accuracy와 Precision, Recall이 동일하게 나오게 되는 조건을 만족하게 되는 것이다.

 

즉, 해석해보자면 라벨링을 리스트([1, 0], [0, 1])로 해준 경우 맞춘 것(TP, TN)과 틀린 것(FN, FP)으로만 구별할 수 있는 듯하다.

 

 

 

728x90