-
Notifications
You must be signed in to change notification settings - Fork 67
WIP per-class metrics #1538
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
WIP per-class metrics #1538
Changes from 6 commits
d30dd7a
6ea83fb
0874bae
4a79ccd
416906d
0431ffb
f63fe03
d581625
873a9d1
8153642
e34f632
07a3878
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,6 +10,7 @@ | |
| from sklearn.metrics import silhouette_samples | ||
|
|
||
| from armory.metrics.perturbation import MetricNameSpace, set_namespace | ||
| from armory.metrics.task import populationwise | ||
|
|
||
| registered = MetricNameSpace() | ||
|
|
||
|
|
@@ -21,6 +22,54 @@ def register(metric): | |
| return set_namespace(registered, metric) | ||
|
|
||
|
|
||
| @populationwise | ||
| def precision_and_recall(y, y_pred): | ||
swsuggs marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| """ | ||
| Produce a dictionary whose keys are class labels, and values are (precision, recall) for that class | ||
| """ | ||
| # Assumes that every class is represented in y | ||
|
|
||
| C = confusion_matrix(y, y_pred, normalize=False) | ||
| # breakpoint() | ||
| N = C.shape[0] | ||
| D = {} | ||
| for class_ in range(N): | ||
| # precision: true positives / number of items identified as class_ | ||
| tp = C[class_, class_] | ||
| total_selected = C[:, class_].sum() | ||
| precision = tp / total_selected | ||
|
|
||
| # recall: true positives / number of actual items in class_ | ||
|
||
| total_class_ = C[class_, :].sum() | ||
| recall = tp / total_class_ | ||
|
|
||
| D[class_] = (precision, recall) | ||
|
|
||
| return D | ||
|
|
||
|
|
||
| @populationwise | ||
| def confusion_matrix(y, y_pred, normalize=True): | ||
| """ | ||
| Produce a matrix C such that C[i,j] is the percentage of class i that was classified as j | ||
| If normalize is False, C[i,j] is the actual number of such elements, rather than the percentage | ||
swsuggs marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| """ | ||
| # Assumes that every class is represented in y | ||
| y = np.array(y) | ||
| y_pred = np.array(y_pred) | ||
| if y_pred.ndim == 2: | ||
| y_pred = np.argmax(y_pred, axis=1) | ||
| N = len(np.unique(y)) | ||
|
||
| C = np.zeros((N, N)) | ||
swsuggs marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| for i in range(N): | ||
| for j in range(N): | ||
| C[i, j] = np.sum(y_pred[y == i] == j) | ||
| if normalize: | ||
| sums = np.sum(C, axis=1) | ||
| C = C / sums[:, np.newaxis] | ||
| return C | ||
|
|
||
|
|
||
| @register | ||
| def chi2_p_value(contingency_table: np.ndarray) -> List[float]: | ||
| """ | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.