Open10
機械学習の評価指標
Definitions for classification
for class
Accuracy
def accuracy(y_true: np.ndarray, y_pred: np.ndarray):
'''
y_true: (n,)
y_pred: (n,)
'''
return np.mean(y_true == y_pred)
Precision
def macro_precision(y_true: np.ndarray, y_pred: np.ndarray):
'''
y_true: (n,)
y_pred: (n,)
'''
return np.mean([
np.sum((y_true == y_pred) & (y_pred == c)) / (np.sum(y_pred == c) + 1e-10)
for c in np.unique(y_true)
])
def micro_precision(y_true: np.ndarray, y_pred: np.ndarray):
'''
y_true: (n,)
y_pred: (n,)
'''
unique_classes = np.unique(y_true)
tp = np.array([np.sum((y_true == y_pred) & (y_true == c)) for c in unique_classes])
fp = np.array([np.sum((y_true != y_pred) & (y_pred == c)) for c in unique_classes])
return np.sum(tp) / (np.sum(tp) + np.sum(fp) + 1e-10)
Recall
def macro_recall(y_true: np.ndarray, y_pred: np.ndarray):
'''
y_true: (n,)
y_pred: (n,)
'''
return np.mean([
np.sum((y_true == y_pred) & (y_true == c)) / (np.sum(y_true == c) + 1e-10)
for c in np.unique(y_true)
])
def micro_recall(y_true: np.ndarray, y_pred: np.ndarray):
'''
y_true: (n,)
y_pred: (n,)
'''
unique_classes = np.unique(y_true)
tp = np.array([np.sum((y_true == y_pred) & (y_true == c)) for c in unique_classes])
fn = np.array([np.sum((y_true != y_pred) & (y_true == c)) for c in unique_classes])
return np.sum(tp) / (np.sum(tp) + np.sum(fn) + 1e-10)
F1
def macro_f1(y_true: np.ndarray, y_pred: np.ndarray):
'''
y_true: (n,)
y_pred: (n,)
'''
return np.mean([
2*np.sum((y_true==y_pred)&(y_true==c)) / (2*np.sum((y_true==y_pred)&(y_true==c)) + np.sum((y_true!=y_pred)&(y_pred==c)) + np.sum((y_true!=y_pred)&(y_true==c)) + 1e-10)
for c in np.unique(y_true)
])
# or
return np.mean([
2 * macro_precision(y_true, y_pred) * macro_recall(y_true, y_pred) / (macro_precision(y_true, y_pred) + macro_recall(y_true, y_pred) + 1e-10)
for c in np.unique(y_true)
])
def micro_f1(y_true: np.ndarray, y_pred: np.ndarray):
'''
y_true: (n,)
y_pred: (n,)
'''
unique_classes = np.unique(y_true)
tp = np.array([np.sum((y_true == y_pred) & (y_true == c)) for c in unique_classes])
fp = np.array([np.sum((y_true != y_pred) & (y_pred == c)) for c in unique_classes])
fn = np.array([np.sum((y_true != y_pred) & (y_true == c)) for c in unique_classes])
return np.sum(2 * tp) / (np.sum(2 * tp) + np.sum(fp) + np.sum(fn) + 1e-10)
# or
precision = micro_precision(y_true, y_pred)
recall = micro_recall(y_true, y_pred)
return 2 * precision * recall / (precision + recall + 1e-10)
Definitions for action segmentation
for segment
IoU
def iou(y_true: Tuple[int, int], y_pred: Tuple[int, int]):
'''
y_true: (2,)
y_pred: (2,)
'''
intersection = max(0, min(y_true[1], y_pred[1]) - max(y_true[0], y_pred[0]))
union = max(y_true[1], y_pred[1]) - min(y_true[0], y_pred[0])
return intersection / union
\tau
Precision@def labels_segments(labels: np.ndarray):
'''
labels: (n,)
'''
change_indices = np.where(np.diff(labels, prepend=0) != 0)[0]
segments = []
for i in range(len(change_indices)):
start = change_indices[i]
end = change_indices[i + 1] if i + 1 < len(change_indices) else len(labels)
segment = [labels[start], (start, end)]
segments.append(segment)
return segments
def precision_tau(y_true: np.ndarray, y_pred: np.ndarray, tau: float = 0):
'''
y_true: (n,)
y_pred: (n,)
'''
segments_true = labels_segments(y_true)
segments_pred = labels_segments(y_pred)
tp = 0
fp = 0
for segment_pred in segments_pred:
match_segments = [segment_true for segment_true in segments_true if segment_pred[0] == segment_true[0]]
ious = [iou(segment_pred[1], segment_true[1]) for segment_true in match_segments]
if len(ious) > 0 and max(ious) > tau:
tp += 1
else:
fp += 1
return tp / (tp + fp + 1e-10)
\tau
Recall@def recall_tau(y_true: np.ndarray, y_pred: np.ndarray, tau: float = 0):
'''
y_true: (n,)
y_pred: (n,)
'''
segments_true = labels_segments(y_true)
segments_pred = labels_segments(y_pred)
tp = 0
fn = 0
for segment_true in segments_true:
match_segments = [segment_pred for segment_pred in segments_pred if segment_true[0] == segment_pred[0]]
ious = [iou(segment_pred[1], segment_true[1]) for segment_pred in match_segments]
if len(ious) > 0 and max(ious) > tau:
tp += 1
else:
fn += 1
return tp / (tp + fn + 1e-10)
\tau
F1@def f1_tau(y_true: np.ndarray, y_pred: np.ndarray, tau: float = 0):
'''
y_true: (n,)
y_pred: (n,)
'''
precision = precision_tau(y_true, y_pred, tau)
recall = recall_tau(y_true, y_pred, tau)
return 2 * precision * recall / (precision + recall + 1e-10)