classification performance evaluation

분류 성능 평가

분류 문제는 회귀분석과 달리 다양한 성능 평가기준이 필요하다.

Scikit-Learn에서 제공하는 분류 성능평가 메서드들은 다음과 같다.

sklearn.metrics 서브 패키지

  • confusion_matrix()
  • classfication_report()
  • accuracy_score(y_true, y_pred)
  • precision_score(y_true, y_pred)
  • recall_score(y_true, y_pred)
  • fbeta_score(y_true, y_pred, beta)
  • f1_score(y_true, y_pred)

분류 결과표 Confusion Matrix

분류 결과표는 타겟의 실제 클래스와 모형이 예측한 클래스가 일치하는 개수를 표로 나타낸 것이다. 원래 클래스는 행으로, 예측한 클래스는 열로 나타낸다.

예측 클래스 0 예측 클래스 1 예측 클래스 2
원래 클래스 0 2 0 0
원래 클래스 1 0 0 1
원래 클래스 2 1 0 2

이를 코드로 구현하면 다음과 같다.

1
2
3
4
from sklearn.metrics import confusion_matrix
y_true = [2, 0, 2, 2, 0, 1]
y_pred = [0, 0, 2, 2, 0, 2]
confusion_matrix(y_true, y_pred)
1
2
3
4
#분류결과표
array([[2, 0, 0],
[0, 0, 1],
[1, 0, 2]])

이진 분류 결과표 Binary Confusion Matrix

클래스가 두 개인 경우에는 일반적으로 클래스 이름을 “Positive”와 “Negative”로 표시한다.

  • positive : 특이한 케이스에 해당하는 경우
  • negative : 그렇지 않은 일반적인 경우

이진 분류 결과표는 다음과 같은 모양이다.

Positive라고 예측 Negative라고 예측
실제 Positive True Positive False Negative
실제 Negative False Positive True Negative

FDS (Fraud Detection System)

잘못된 거래 및 사기 거래 등을 예측하는 시스템으로, 예측 결과가 실제와 일치하는지에 따라 다음과 같이 구분한다.

  • TP(True Positive): 사기를 사기라고 정확하게 예측
  • TN(True Negative): 정상을 정상이라고 정확하게 예측
  • FP(False Positive): 정상을 사기라고 잘못 예측
  • FN(False Negative): 사기를 정상이라고 잘못 예측

FDS는 병의 진단에도 쓰일 수 있다. (positive: 병에 걸린 것, negative: 병에 걸리지 않은 것)

이진분류결과표에 따르면 분류모델의 성능평가척도가 4개로 추려지지만 그래도 여전히 많다.

그래서 그 4개의 수를 조합해 하나의 점수로 만든 것이 아래 설명할 평가점수다.

평가 점수

FDS 의 결과로 나온 TP, TN, FP, FN 네 가지를 조합해 다음의 평가점수들을 계산한다.

  • accuracy (정확도)
  • precision (정밀도)
  • recall (재현율)
  • fallout (위양성율)
  • F (beta) score

1) Accuracy

​ : 전체 샘플 중 맞게 예측한 샘플 수의 비율

2) Precision

​ : Positive 클래스라고 예측한 데이터 중 실제로 Positive에 해당하는 데이터의 비율

  • 사기거래 추정에서 일단 positive라고 추정이 됐으면 그게 실제 사기문제일 수 있기 때문에 중요하게 여겨지고, 사기거래 특정 시스템이 실제로 잘 작동하고 있는지 파악할 수 있어야 되기 때문에 precision점수가 중요하게 된다.

3) Recall

​ : 실제 Positive인 데이터 중 Positive라고 예측된 데이터의 비율

4) Fall-Out

​ : 실제 Negative인 데이터 중 Positive로 잘못 에측된 표본의 비율

5) F (beta) score

​ :반비례관계에 있는 precision과 recall은 둘 다 중요한 점수이기 때문에 같이 봐야 하는데, 그 때 그 두 점수를 가중조화 평균낸 점수가 F-score다. 베타 값에 따라 달라진다.

image-20181201093234513

  • F1 score (beta = 1)

Scikit-Learn의 metrics 패키지에서는 정밀도, 재현율, F1-score를 구하는 classification_report 명령을 제공한다.

이 명령은 각각의 클래스를 positive로 보았을 때의 precision, recall, F1-score를 구하고 그 평균값으로 전체 모형의 성능을 평가한다.

1
2
3
4
5
6
from sklearn.metrics import classification_report

y_true = [0, 0, 0, 1, 1, 0, 0]
y_pred = [0, 0, 0, 0, 1, 1, 1]

print(classification_report(y_true, y_pred, target_names=['class 0', 'class 1']))
1
2
3
4
5
6
7
#결과
precision recall f1-score support

class 0 0.75 0.60 0.67 5
class 1 0.33 0.50 0.40 2

avg / total 0.63 0.57 0.59 7

위의 평가 점수들은 서로 밀접한 관계를 맺고 있다.

  • 재현율(recall)과 위양성률(fall-out)은 양의 상관 관계가 있다.
  • 정밀도(precision)와 재현율(recall)은 대략적으로 음의 상관 관계가 있다.

Precision vs. Recall

분류모델 예측결과 precision과 recall이 모두 높으면 좋지만, 사실 두 점수는 반비례하는 경향이 있다.

precision은, 예를들어 의사가 진단을 하는 경우 의사의 권위 및 능력과 직결되는 점수이다. precision이 낮으면 신뢰도가 떨어지기때문에 의사는 precision을 높이기 위해 판별함수 f(x)의 기준점을 0보다 높게 설정하게 된다. f(x)가 10 이상인 경우에만 positive라고 진단해버림으로써 0이상 10 미만일 때 오진이었던 경우를 배제해버리는 것이다. 그러면 precision점수가 높아진다.

이와 반대로 recall을 높이려면 존재하는 모든 positive를 잡아내야만 하는 것이 목표가 된다. 그러기 위해서는 반대로 f(x)의 임계점을 0보다 낮게 만든다. 일단 negative인 것들도 막 잡아내고 보면 positive가 다 잡히게 되어있기 때문이다.

따라서 precision과 recall을 동시에 높이기는 쉽지 않다.

ROC 커브

ROC(Receiver Operator Characteristic) 커브란, fall-out과 recall 값이 판별함수 기준값의 변화에 따라 어떻게 달라지는지를 시각화한 것이다.

아래 표는, 16개의 데이터에 대해 판별함수 기준값을 0으로 설정하고 이진분류를 진행한 결과이다.

​ 표를 보면 6번, 7번, 10번 데이터의 예측에 실패했음을 알 수 있다. 이 때 만약 판별함수 기준값을 6번데이터의 판별함수값인 0.244729보다 높이게 되면 6번데이터는 0클래스로 예측되게 되므로 정확한 예측이 된다. 이런 식으로 기준값을 높이거나 낮춰가면서 recall과 fall-out 점수를 확인하는 과정을 자동으로 진행하고 시각화해주는 것이 scikit-learn의 roc_curve 명령이다.

image-20181202204820835

​ 아래 그래프는 위 16개의 데이터에 대한 ROC 곡선이다.

데이터가 더 많으면 더 곡선에 가까운 형태의 그래프가 그려진다.

AUC

분류모델은 Fall-Out 점수가 낮으면서 Recall이 높으면 좋기 때문에 ROC커브 그래프에서는 좌측 상단의 점이 높게 그려질수록 좋은 모델에 해당한다. 따라서 곡선 아래 면적이 클수록 좋은데, 그 면적을 측정한 것이 AUC(Area Under the Curve)이다. AUC가 1에 가까울수록 좋은 모델이라고 볼 수 있다.

1
2
from sklearn.metrics import auc
auc(fpr, tpr)
1
2
#AUC 결과값
0.9112016520622872
Share