-
Notifications
You must be signed in to change notification settings - Fork 5
/
metrics.py
128 lines (96 loc) · 4.43 KB
/
metrics.py
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import numpy as np
def compute_mae(predictions, labels, data):
preds_unscaled, y_unscaled = _unscale(predictions, labels, data)
mae = mae_metric(preds_unscaled, y_unscaled)
return mae
def compute_mape(predictions, labels, data):
preds_unscaled, y_unscaled = _unscale(predictions, labels, data)
mape = mape_metric(preds_unscaled, y_unscaled)
return mape
def compute_ssi(predictions, labels, data):
preds_unscaled, y_unscaled = _unscale(predictions, labels, data)
return ssi_metric(preds_unscaled, y_unscaled)
def compute_geh(predictions, labels, data):
preds_unscaled, y_unscaled = _unscale(predictions, labels, data)
return geh_metric(preds_unscaled, y_unscaled)
def compute_cpl(predictions, labels, data):
preds_unscaled, y_unscaled = _unscale(predictions, labels, data)
return cpl_metric(preds_unscaled, y_unscaled)
def compute_cpc(predictions, labels, data):
preds_unscaled, y_unscaled = _unscale(predictions, labels, data)
return cpc_metric(preds_unscaled, y_unscaled)
def compute_binned_metric(metric_f, predictions, labels, bins, data, num_bins):
bins = np.concatenate(bins, axis=0).reshape(-1)
preds_unscaled, y_unscaled = _unscale(predictions, labels, data)
binned_metric = _compute_binned_metric(preds_unscaled, y_unscaled,
bins, num_bins, metric_f)
return binned_metric
def compute_macro_metric(metric_f, predictions, labels, bins, data, num_bins):
binned_metric = compute_binned_metric(metric_f, predictions, labels, bins,
data, num_bins)
macro_metric = (np.nanmean(binned_metric)
if not np.all(np.isnan(binned_metric))
else np.nan)
return macro_metric
def _unscale(preds, y, data):
preds_unscaled = np.concatenate(preds, axis=0).reshape(-1, 1)
preds_unscaled = data.label_scaler.inverse_transform(preds_unscaled)
preds_unscaled = preds_unscaled.reshape(-1)
y_unscaled = np.concatenate(y, axis=0).reshape(-1, 1)
y_unscaled = data.label_scaler.inverse_transform(y_unscaled)
y_unscaled = y_unscaled.reshape(-1)
return preds_unscaled, y_unscaled
def mae_metric(preds_unscaled, y_unscaled):
mae = np.absolute(preds_unscaled.reshape(-1) - y_unscaled.reshape(-1))
mae = np.mean(mae)
return mae
def mape_metric(preds_unscaled, y_unscaled):
non_zero_target_idcs = y_unscaled > 1e-5
if np.sum(non_zero_target_idcs) == 0:
return np.nan
non_zero_targets = y_unscaled[non_zero_target_idcs]
predicted = preds_unscaled[non_zero_target_idcs]
mape = np.absolute(predicted - non_zero_targets) / non_zero_targets
mape = np.mean(mape, axis=0)
return mape
def ssi_metric(preds_unscaled, y_unscaled):
preds_unscaled = preds_unscaled[y_unscaled > 0]
y_unscaled = y_unscaled[y_unscaled > 0]
ssi = (np.sum(2 * np.minimum(preds_unscaled, y_unscaled)
/ (preds_unscaled + y_unscaled))
/ len(y_unscaled))
return ssi
def geh_metric(preds_unscaled, y_unscaled):
geh = np.sqrt(2 * (preds_unscaled - y_unscaled)**2
/ (preds_unscaled + y_unscaled))
geh_percentage = len(geh[geh < 5]) / len(geh)
return geh_percentage
def cpl_metric(preds_unscaled, y_unscaled):
cpl = (2 * np.sum(preds_unscaled * y_unscaled > 1e-8)
/ (np.sum(preds_unscaled > 1e-8) + np.sum(y_unscaled > 1e-8)))
return cpl
def cpc_metric(preds_unscaled, y_unscaled):
cpc = (np.sum(2 * np.minimum(preds_unscaled, y_unscaled))
/ (np.sum(preds_unscaled) + np.sum(y_unscaled)))
return cpc
def _compute_binned_metric(out, y, bins, num_bins, metric_f):
"""
Computes the given metric for each bin individually.
:param out: NumPy array containing model predictions.
:param y: NumPy array containing labels.
:param bins: NumPy array containing the bins that each label belongs to.
:param num_bins: Total number of bins.
:param metric_f: Function which receives the model predictions and labels
as arguments (in that order) and returns a scalar metric value.
:return: NumPy array of shape [num_bins] containing the metric value for
each bin.
"""
metric_vals = []
for bin_idx in range(num_bins):
mask = bins == bin_idx
if np.sum(mask) > 0:
vals = metric_f(out[mask], y[mask])
metric_vals.append(vals)
else:
metric_vals.append(np.nan)
return np.array(metric_vals)