-
Notifications
You must be signed in to change notification settings - Fork 0
Metrics 0.2.0 classification
Lodestar.Metrics 0.2.0. This page is frozen at that release. Read the current documentation for what
mainsays now. A link to a decision or a migration page followsmain, and leaves the archive.
Your model looked at some things and put a label on each one. How well did it do? Every type on this page answers that, and they disagree — not about the arithmetic, but about what "well" is worth measuring. One number can hide a model that never predicts the rare class; another can be near zero for a model that is right nine times in ten. Reporting the wrong one is the usual reason a model looks fine on a slide and useless in production.
Almost everything here is built on one object, so it is worth reading first.
A confusion matrix is a table with one row per true class and one column per predicted class, and each cell holds how many samples fell there. The diagonal is what the model got right; every other cell is a specific mistake — "this class, mistaken for that one". For two classes the table has four cells, and they have names: true positives (said yes, was yes), false positives (said yes, was no), false negatives (said no, was yes) and true negatives (said no, was no). Precision, recall and F1 are three different divisions of those four numbers.
flowchart LR
subgraph M["The four cells, for one class"]
direction TB
TP["<b>TP</b><br/>said yes, was yes"]
FP["<b>FP</b><br/>said yes, was no"]
FN["<b>FN</b><br/>said no, was yes"]
TN["<b>TN</b><br/>said no, was no"]
end
TP --> P["<b>Precision</b> = TP / (TP + FP)<br/><i>of what I flagged, how much belonged</i>"]
FP --> P
TP --> R["<b>Recall</b> = TP / (TP + FN)<br/><i>of what belonged, how much I found</i>"]
FN --> R
P --> F["<b>F1</b><br/>harmonic mean of the two"]
R --> F
TP -.-> A["<b>Accuracy</b> = (TP + TN) / everything"]
TN -.-> A
TN -.-x|"never read"| P
TN -.-x|"never read"| R
The dotted lines are the point: TN is invisible to precision, recall and F1. A model that says
"no" to everything scores perfectly on the true-negative cell and zero on all three of them, which
is why a rare-disease detector can be 99% accurate and worthless.
Three conventions run through the whole namespace.
-
Every metric has two ways in. One overload takes
yTrueandyPredand counts the matrix on the way; the other takes aConfusionMatrixyou already have. They give the same number, and the second is what you want when you are reporting five metrics over one dataset — the counting happens once. The one place they can differ is an explicitlabelssubset, and each entry says so. -
Labels are
int. Astringclass name is the caller's mapping to make, andClassificationReport'stargetNamesis where readable names go back on. -
Undefined is a real answer, not a crash. A class nothing was predicted into has no precision;
a class with no true samples has no recall.
ZeroDivisionsays what comes back, and the default reproduces scikit-learn's0.0.
Regression metrics — how far a number is from another number — are on the regression page, not here.
flowchart TD
A["What are you reporting?"] --> B{"Are you scoring a decision,<br/>or a ranking?"}
B -->|a ranking, or a probability| C["RocAuc"]
B -->|a decision| D{"Are the classes<br/>roughly balanced?"}
D -->|yes, and every mistake costs the same| E["Accuracy"]
D -->|no| F{"Is one class the one<br/>you actually care about?"}
F -->|yes| G{"Which mistake hurts more?"}
G -->|a false alarm| H["Precision"]
G -->|a miss| I["Recall"]
G -->|both, and equally| J["F1"]
G -->|both, unequally| K["FBeta"]
F -->|no, every class matters| L{"Should a rare class count<br/>as much as a common one?"}
L -->|yes| M["BalancedAccuracy,<br/>or Averaging.Macro"]
L -->|no| N["Averaging.Weighted"]
A --> O{"Do you want one number<br/>that already discounts luck?"}
O -->|against chance agreement| P["CohenKappa"]
O -->|as a correlation| Q["MatthewsCorrelation"]
A --> R["Looking rather than reporting:<br/>ConfusionMatrix, then ClassificationReport"]
| Type | What it is |
|---|---|
Accuracy |
The share of samples the model got right. |
AverageRow |
One averaged line of a ClassificationReport. |
Averaging |
How per-class scores are reduced to one number. |
BalancedAccuracy |
Accuracy that counts every class equally, however rare. |
ClassificationReport |
The per-class table, structured and as printable text. |
ClassRow |
One class's line of a ClassificationReport. |
CohenKappa |
Agreement between two raters, with chance agreement subtracted. |
ConfusionMatrix |
Predictions counted against truth — the table everything else reads. |
F1 |
The harmonic mean of precision and recall. |
FBeta |
The same, with the balance between the two turned by hand. |
KappaWeighting |
How far apart two classes count as being, for CohenKappa. |
MatthewsCorrelation |
The correlation between prediction and truth, in [-1, 1]. |
MultiClassRocOptions |
The optional settings of multiclass ROC-AUC. |
MultiClassStrategy |
One class against the rest, or every pair. |
Normalization |
Which sum a confusion matrix's cells are divided by. |
Precision |
Of everything flagged as a class, how much belonged there. |
Recall |
Of everything that belonged to a class, how much was found. |
RocAuc |
How well the scores rank a positive above a negative. |
UndefinedMetricException |
Thrown when a metric is undefined and you asked to be told. |
ZeroDivision |
What an undefined metric returns instead of throwing. |
- 0001-target-framework
- 0002-unicode-comparison-unit
- 0003-provenance-and-licensing
- 0004-levenshtein-myers-backlog
- 0005-hamming-jellyfish-divergence
- 0006-ratcliff-autojunk
- 0007-metaphone-scope
- 0008-italian-enza-nltk-divergence
- 0009-sample-consumes-a-local-feed
- 0010-stop-word-list-provenance
- 0011-persistence-format
- 0012-per-package-versioning
- 0013-sentencepiece-parity-scope
- 0014-precompiled-normalizer
- 0015-sonar-rules-in-the-build
- 0016-metrics-package-placement
- 0017-bpe-parity-scope
- 0018-multiclass-roc-auc-parallelism-is-opt-in
- 0019-the-net-analysers-run-in-the-build-too
- 0020-normalize-is-a-projection-not-a-parameter
- 0021-multioutput-is-a-method-not-an-enum
- 0022-added-token-matching-flags
- 0023-byte-level-decode-substitutes
- 0024-weighted-median-averages-within-scikit-learns-epsilon
- 0025-quickselect-replaces-a-full-sort-for-the-median
- 0026-r2-and-explainedvariance-split-their-undefined-cases-differently
- 0027-r2-and-explainedvariance-vectorize-only-a-single-output
- 0028-log1p-is-kahans-identity-not-math-log-1-plus-x
- 0029-balanced-accuracy-adjusted-is-left-to-ieee-754-at-the-edge
- 0030-cohen-kappa-keeps-scikit-learns-expected-matrix-orientation
- 0031-nosamplecorrect-mirrors-numpys-float64-upcast
- 0032-fbeta-substitutes-tp-predicted-and-support-algebraically
- 0033-compensated-sum-is-neumaiers-variant
- 0034-dropout-is-refused-for-want-of-a-user
- 0035-a-null-pre-split-is-removed-with-invert-not-isolated
- 0036-a-member-may-ship-without-an-oracle-if-it-says-so
- 0037-the-guards-run-before-the-commit
- 0038-the-gate-confronts-an-exception-tag-with-the-page-that-documents-it
- 0039-mutual-information-returns-zero-on-an-empty-input
- 0040-a-curve-is-a-sealed-class-per-curve
- 0041-one-sample-file-per-public-class
- 0042-phonetic-encoders-refuse-a-null-word
- 0043-the-equality-table-is-sized-to-the-pattern
- 0044-compression-belongs-to-the-caller
- 0045-a-console-call-carries-its-reason-on-the-line
- 0046-check-adr-immutable-runs-in-ci-only
- 0047-one-gate-per-kernel-not-one-per-alphabet
- 0048-the-gate-depends-on-the-kernel-and-the-alphabet
- 0049-two-gates-per-kernel-tested-where-the-width-is-known
- 0050-the-sentencepiece-bpe-lineage-stays-a-bpe-model
- benchmark_latest
- decisions
- equivalence
- matplotlib
- migration
- nightly_run
- numpy
- pandas
- performance
- pytorch
- seaborn
- sklearn
- statsmodels