일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- CentOS
- python
- deep learning
- Redux
- fastapi
- NCP
- mariadb
- docker
- nginx
- Go
- AWS
- laravel
- nodejs
- 블레이드 템플릿
- Node
- For
- webpack
- linux
- Machine Learning
- Redis
- php
- rabbitmq
- Backbone.js
- 기초 수학
- Switch
- javascript
- SQL
- phpredis
- React
- Babel
- Today
- Total
개발일기
딥러닝/머신러닝 - 모델 평가지표 본문
이진 분류 평가 지표
Confusion Matrix
모델 학습을 평가하는 지표로 Confusion Matrix라 불리는 오차 행렬을 기반으로 각 평가 지표를 4가지의 경우로 나눌 수 있다.
Prediction | |||
A | B | ||
Actual | A | TP | FN |
B | FP | TN |
- True, False: 예측의 정답 여부를 나타낸다.
- Positive, Negative: 예측한 값의 True, False 여부를 나타낸다.
- TP: Prositive로 예측하고 실제로 Postitive 경우(정답)
- FP: Prositive로 예측했으나 실제는 Negative인 경우(오답)
- FN: Negative로 예측했으나 실제는 Positive인 경우(오답)
- TN: Negative로 예측하고 실제로 Negative인 경우(정답)
정확도(Accuracy)
예측한 값이 정답 레이블과 일치하는 비율을 의미한다. 정확도는 직관적으로 모델의 성능을 평가할 수 있는 지표지만 데이터의 구성 방식에 따라 정확도가 과도하게 부풀려지는 왜곡이 발생할 수 있다. 여기서 왜곡이란 데이터가 불균형할 때 발생한다. 예를 들어 True와 False 정답의 비율이 9:1 이라면 해당 모델이 True라고 예측만 해도 90%의 정확도를 달성할 수 있다. 하지만 이러한 경우 False 예측도 잘한다고 단정 지을 수 없기에 잘 학습된 모델이라 판단하기 어렵다.
데이터의 편향으로 인해 잘못된 정확도가 책정될 수 있기 때문에 균형 잡힌 데이터 셋에서 정확도 지표를 사용하는게 권장된다.
import tensorflow as tf
tf.keras.metrics.Accuracy(
name='accuracy', dtype=None
)
a1 = tf.keras.metrics.Accuracy() # accuracy
a1.update_state([[0], [0], [0], [0]], [[0], [0], [0], [0]])
a1_accuracy = a1.result().numpy()
a2 = tf.keras.metrics.Accuracy() # accuracy
a2.update_state([[0], [0], [0], [0]], [[0], [1], [1], [1]])
a2_accuracy = a2.result().numpy()
print(a1_accuracy, a2_accuracy) # 1.0 0.25
# a1은 모든게 일치하므로 정확도가 100%
# a2는 인덱스 2만 일치하므로 정확도가 25%
정밀도(Precision)
Positive로 예측하고 정답인 비율. 0과 1사이의 값을 가지며 1에 가까울 수록 좋은 모델이다.
a1 = tf.keras.metrics.Precision()
a1.update_state([[0], [0], [1], [1]], [[1], [0], [1], [1]])
a1_precision = a1.result().numpy()
print(a1_precision) # 0.6666667
Recall(재현율)
정답이 True고 예측을 성공한 비율. precision과 마찬가지로 0과 1사이의 값을 가지며 1에 가까울수록 좋은 모델이다.
a1 = tf.keras.metrics.Recall()
a1.update_state([0, 1, 1, 1], [1, 0, 0, 1])
a1_recall = a1.result().numpy()
print(a1_recall) # 0.33333334
F1Score
precision과 recall 수치의 조화 평균을 나타낸다. precision과 recall은 서로 균형을 이루는 관계이다. recall의 수치가 올라가면 precision의 수치가 낮아지는 관계를 이룬다. precision 수치가 증가하려면 FP수치가 감소해야 하는데, FP값이 감소하면 FN가 올라가 recall의 수치가 낮아지게 된다.
TP | FN |
FP | TN |
Confusion Matrix 대각의 값은 각각 비례 관계를 가진다. Positive 정답 비율이 줄어들면 Negative 정답 비율이 증가한다. 이와 반대로 Negative 예측이 실패하면 Positive 예측 실패의 비율이 떨어지게 된다.
이런 불균형을 해결하기 위해 두 지표의 평균을 통해 모델을 평가하는 F1Score가 사용된다.
a1 = tf.keras.metrics.Recall()
a1.update_state([0, 1, 1, 1], [1, 0, 0, 1])
a1_precision = a1.result().numpy()
a1_recall = a1.result().numpy()
print(a1_precision) # 0.33333334
print(a1_recall) # 0.33333334
a1_f1_score = 2 * (a1_precision * a1_recall) / (a1_precision + a1_recall)
print(a1_f1_score) # 0.33333334823449406
회귀 평가 지표
MSE
출력값과 정답값의 차이를 제곱한 후한균을 한 한것이 평균 제곱 오차이다. 이 값이 작은 모델일수록 더 정확한 값을 산출해냄을 의미한다.
오차값을 제곱하기에 오차값이 1미만인 경우 값이 더 작아지고 1이상인 경우는 값이 더 커지게 된다.
y: 신경망이 추정한 값(i는 차원)
t: 정답 레이블(i는 차원)
sum: 인덱스 0부터 시작하여 마지막 인덱스까지 예측값과 정답값의 오차를 제곱하여 더한다.
# 첫 번째 모델
import numpy as np
t = np.array([5.0, 4.0, 3.0, 2.0, 1.0]) # 정답 레이블
y = np.array([4.9, 3.7, 3.0, 2.0, 1.3]) # 예측값
mse = 1/(y.size) * np.sum((y - t)**2)
print(mse) # 0.03799999999999997
# 두 번째 모델
import numpy as np
t = np.array([5.0, 4.0, 3.0, 2.0, 1.0])
y = np.array([4.5, 3.5, 2.5, 1.5, 0.5])
mse = 1/(y.size) * np.sum((y-t)**2)
print(mse) # 0.25
첫번째 모델과 다르게 예측값과 정답의 오차를 많이 발생시키면 mse값이 증가한다. mse값이 더 작은 모델이 정확한 모델이기에 이 두개의 모델을 비교해보았을 때 mse값이 적은 첫번째 모델이 더 정확한 모델이란 것을 확인할 수 있다. 하지만 MSE는 제곱이기에 값이 1미만이면 0에 더 가까워지고 1이상이면 값이 더욱 커지게 된다.
제곱을 통한 오차 계산이기에 이상치(outliner)에 민감하여 잘못된 오차를 산출해 낼 수 있다.
MAE
MSE와는 다르게 오차의 절대값의 평균을 구한다. 절대값의 평균이기에 예측과 정답 사이의 오차를 가장 직관적으로 확인할 수 있다. 절대값이기에 예측값이 정답값에 비교했을 때 음수쪽 방향인지 양수쪽 방향인지 알 수가 없다는 단점이 있다.
MSE와는 다르게 이상치로 인한 영향을 적게 받는다.
import numpy as np
t = np.array([5.0, 4.0, 3.0, 2.0, 1.0]) # 정답 레이블
y = np.array([4.9, 3.7, 3.0, 2.0, 1.3]) # 예측값
mae = 1/(y.size) * np.sum(abs(y-t))
print(mae) # 0.1399999999999999
RMSE
평균 제곱 오차에 root를 씌운다. 이상치로 인한 과도한 증감을 줄일 수 있다.
import numpy as np
import math
t = np.array([5.0, 4.0, 3.0, 2.0, 1.0]) # 정답 레이블
y = np.array([4.9, 3.7, 3.0, 2.0, 1.3]) # 예측값
rmse = math.sqrt(np.sum(((y-t)**2) / y.size))
print(rmse) # 0.19493588689617922
이상치(outliner)
다른 데이터셋과 비교했을 때 현저하게 다른 데이터를 가지고 있는것을 이상치라 한다. 과일 목록을 나타내는 데이터셋에 갑자기 핸드폰 모델명이 나오는 경우, 이 핸드폰 모델은 해당 데이터셋의 이상치이다.
np.array(['mango', 'orange', 'melon']) # 정상
np.array(['mango', 'cherry', 'Galaxy S22+']) # 이상치 포함
참고 사이트:
https://www.analyticsvidhya.com/blog/2020/09/precision-recall-machine-learning/
https://www.tensorflow.org/api_docs/python/tf/keras/metrics/Recall
https://www.tensorflow.org/api_docs/python/tf/keras/metrics/Precision
https://www.tensorflow.org/api_docs/python/tf
'AI' 카테고리의 다른 글
딥러닝, 머신러닝 - 미분이란 무엇일까? (0) | 2024.01.06 |
---|---|
딥러닝, 머신 러닝 - 손실 함수(Loss Function) (0) | 2023.12.30 |
딥러닝/머신러닝 - 활성화(Activation) 함수 (0) | 2023.12.30 |