-
Notifications
You must be signed in to change notification settings - Fork 0
Metrics 0.2.0 classificationreport compute
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.
Builds the report: one row per class, the accuracy, and two or three averaged rows.
public static ClassificationReport Compute(ConfusionMatrix cm, IReadOnlyList<string> targetNames = null, ZeroDivision zeroDivision = ZeroDivision.Zero)
public static ClassificationReport Compute(ReadOnlySpan<int> yTrue, ReadOnlySpan<int> yPred, IReadOnlyList<string> targetNames = null, ZeroDivision zeroDivision = ZeroDivision.Zero, ReadOnlySpan<int> labels = default, ReadOnlySpan<double> sampleWeight = default)Parameters — cm is a matrix already counted, or pass yTrue and yPred instead.
targetNames
puts readable names on the rows, one per label and in label order; leave it null and the rows are
named by the label value. zeroDivision decides what an undefined per-class score becomes.
labels
fixes the label set and its order, and sampleWeight gives each sample its own weight.
Returns — a ClassificationReport, whose Classes list holds one ClassRow per label in the
matrix's label order, and whose MacroAverage, WeightedAverage and possibly MicroAverage hold
the averaged rows. Accuracy and TotalSupport are on the report itself.
Exceptions — ArgumentNullException when cm is null; ArgumentException when targetNames
has a different length from the label set, or the label spans disagree in length or are empty.
Example — a three-way triage, with names on the classes.
using Lodestar.Metrics;
int[] yTrue = [0, 0, 1, 1, 2, 2, 2];
int[] yPred = [0, 1, 1, 1, 2, 2, 0];
ClassificationReport report = ClassificationReport.Compute(yTrue, yPred, ["urgent", "normal", "spam"]);
double spamF1 = report.Classes[2].F1; // => 0.8
double accuracy = report.Accuracy; // => 0.7142…Remarks — this is the thing to reach for when you are looking rather than monitoring. One call
gives every per-class score at once, so it replaces four calls to Precision.PerClass and its
siblings and counts the matrix once instead of four times. ToText then renders it exactly as
Python prints it, which makes a C# result and a Python result comparable by eye rather than by
transcription.
MicroAverage is null almost always, and that is the interesting part. scikit-learn prints an
accuracy row normally and swaps in a micro avg row when an explicit label subset has left some
samples out — because then the diagonal over the total is no longer accuracy over the dataset.
This
reproduces that rule exactly: the property is non-null precisely when labels was given and
something fell outside it.
The trap is targetNames: it is positional, matched to the label set by index and not by value.
If
labels is omitted the order is the sorted union of both inputs, so names written in the order
the
classes occur in your data will be silently attached to the wrong rows. Pass labels explicitly
whenever you pass targetNames, or sort the names yourself.
Applies to — net10.0, netstandard2.0.
See also — ClassificationReport.ToText, ConfusionMatrix.Compute, Precision.PerClass,
the Python equivalence table.
- 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