from sklearn.metrics import accuracy_score
y_pred = [0, 2, 1, 3]
y_true = [0, 1, 2, 3]
accuracy_score(y_true, y_pred) <- 0.5임
accuracy_score(y_true, y_pred, normalize=False) <- 2임
import numpy as np
def accuracy_score(y_pred, y_true):
yhat = np.array(y_pred)
y = np.array(y_true)
accuracy = np.mean(y == yhat)
return accuracy
이 식을 보면서도 알 수 있는 것은 k개의 샘플을 일일이 대조하며 맞는 값을 찾으며 예측 정확도를 높이는 것이다.
import numpy as np
from sklearn.metrics import top_k_accuracy_score
y_true = np.array([0, 1, 2, 2])
y_score = np.array([[0.5, 0.2, 0.2],
[0.3, 0.4, 0.2],
[0.2, 0.4, 0.3],
[0.7, 0.2, 0.1]])
top_k_accuracy_score(y_true, y_score, k=2) <- 0.75임
top_k_accuracy_score(y_true, y_score, k=2, normalize=False) <- 3임
def top_k_accuracy(X, y, k, classifier):
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
# 자연어처리 시 문자를 넣어 단어 출현 횟수를 세는 함수이다.
vectorizer = TfidVectorizer(min_df=2)
X_train_sparse = vectorizer.fit_transform(X_train)
feature_names = vectorizer.get_feature_names()
test = vectorizer.transform(X_test)
clf = classifier
clf.fit(X_train_sparse, y_train)
predictions = clf.predict(test)
probs = clf.predict_proba(test)
# probs를 기준으로 정렬함
topk = np.argsort(probs, axis = 1)[:, -n:]
y_true = np.array(y_test)
return np.mean(np.array([1 if y_true[k] in topk[k] else 0 for k in range(len(topk))]))
Balanced_Accuracy_Score = (98.7%+96%)/2 = 97.35%
adjusted=True
의 경우 위에서 나타내는 1/nsamples이 1/(1- nsamples)로 불균형 데이터를 조정하려고 하는 것이 존재한다.
from sklearn.metrics import balanced_accuracy_score
y_true = [0, 1, 0, 0, 1, 0]
y_pred = [0, 1, 0, 0, 0, 1]
balanced_accuracy_score(y_true, y_pred)
class BalancedSparseCategoricalAccuracy(keras.metrics.SparseCategoricalAccuracy):
def __init__(self, name='balanced_sparse_categorical_accuracy', dtype=None):
super().__init__(name, dtype=dtype)
def update_state(self, y_true, y_pred, sample_weight=None):
y_flat = y_true
if y_true.shape.ndims == y_pred.shape.ndims:
y_flat = tf.squeeze(y_flat, axis=[-1])
y_true_int = tf.cast(y_flat, tf.int32)
cls_counts = tf.math.bincount(y_true_int)
cls_counts = tf.math.reciprocal_no_nan(tf.cast(cls_counts, self.dtype))
weight = tf.gather(cls_counts, y_true_int)
return super().update_state(y_true, y_pred, sample_weight=weight)
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)
출력
array([[2, 0, 0],
[0, 0, 1],
[1, 0, 2]])
import numpy as np
def compute_confusion_matrix(true, pred):
# 고유값을 검색해 정렬함
K = len(np.unique(true))
# 고유값을 기준으로 KxK 행렬 생성
result = np.zeros((K, K))
for i in range(len(true)):
result[true[i]][pred[i]] += 1
return result
classification_report는 분류 성능 평가에 필요한 지표를 text 형식의 Report로 지원해준다.
from sklearn.metrics import classification_report
y_true = [0, 1, 2, 2, 0]
y_pred = [0, 0, 2, 1, 0]
target_names = ['class 0', 'class 1', 'class 2']
print(classification_report(y_true, y_pred, target_names=target_names))
출력
precision recall f1-score support
class 0 0.67 1.00 0.80 2
class 1 0.00 0.00 0.00 1
class 2 1.00 0.50 0.67 2
accuracy 0.60 5
macro avg 0.56 0.50 0.49 5
weighted avg 0.67 0.60 0.59 5
이진 분류 기업을 사용하는 곳에서 정밀도는 전체 예측 중에서 정확하게 예측한 비율이고, 재현율은 관련 있는 것들 중에서 실제 값들의 비율이다.
from sklearn.metrics import precision_score, recall_score
y_true = [0, 1, 2, 0, 1, 2]
y_pred = [0, 2, 1, 0, 0, 1]
precision_score(y_true, y_pred, average='macro')
recall_score(y_true, y_pred, average='weighted')
# average_precision_score 함수
import numpy as np
from sklearn.metrics import average_precision_score
y_true = np.array([0, 0, 1, 1])
y_scores = np.array([0.1, 0.4, 0.35, 0.8])
average_precision_score(y_true, y_scores)
Case1
def compute_average_precision_recall(precision_recall_dict):
precision = 0
recall = 0
for _, value in precision_recall_dict.items():
precision += value['precision']
recall += value['recall']
average_precision = safe_divide(precision, len(precision_recall_dict))
average_recall = safe_divide(recall, len(precision_recall_dict))
return average_precision, average_recall
Case2 : Average_Precision
def compute_average_precision(precision, recall):
precision = np.concatenate([[0.0], precision, [0.0]])
for i in range(len(precision)-1, 0, -1):
precision[i-1] = np.maximum(precision[i-1], precision[i])
recall = np.concatenate([[0.0], recall, [1.0]])
changing_points = np.where(recall[1:] != recall[:1][0])
areas = (recall[changing_points + 1] - recall[changing_points]) * precision[changing_points + 1]
return areas.sum()
F1-Score는 정밀도와 재현율의 조화평균으로 주로 분류 클래스 간 데이터가 심각한 불균형을 이루는 경우에 사용한다.
F1-Score는 여기서 베타 = 1인 경우로 보고 집어넣으면 된다.
from sklearn.metrics import f1_score
y_true = [0, 1, 2, 0, 1, 2]
y_pred = [0, 2, 1, 0, 0, 1]
f1_score(y_true, y_pred, average='macro')
def f1(actual, predicted, label):
tp = np.sum((actual==label) & (predicted==label))
fp = np.sum((actual!=label) & (predicted==label))
fn = np.sum((predicted!=label) & (actual==label))
precision = tp/(tp+fp)
recall = tp/(tp+fn)
f1 = 2 * (precision * recall) / (precision + recall)
return f1
def f1_macro(actual, predicted):
return np.mean([f1(actual, predicted, label)
for label in np.unique(actual)])
Roc_Curve를 보게 되면 X축은 FP, Y축은 TP로 얼마나 모델이 잘 분류를 하였는지 구분하며 Y축에 더 가까운 그래프를 형성할 수록 좋은 성능을 보인다고 말할 수 있다.
import numpy as np
from sklearn.metrics import roc_curve
y = np.array([1, 1, 2, 2])
scores = np.array([0.1, 0.4, 0.35, 0.8])
fpr, tpr, thresholds = roc_curve(y, scores, pos_label=2)