Skip to content

[Lane 2 · kotlin-core] Precision metric #1227

Open

Description

@michalharakal

Sub-issue of #1222 (Precision, Recall and F1Score metrics).

Lane: 2 · Kotlin core
Skill needed: Kotlin. Read Accuracy.kt and ConfusionMatrixAccumulator first — this task is mostly wiring.
Size: s (~2–3 h)
Blocked by: #1226 (accumulator + Averaging)

What to do

  1. Add public class Precision(averaging: Averaging = Averaging.MACRO, dim: Int = -1, threshold: Float? = null) : Metric
    in skainet-lang/skainet-lang-core/src/commonMain/kotlin/sk/ainet/lang/nn/metrics/Precision.kt:
    • override val name = "precision";
    • update(...) delegates to a private ConfusionMatrixAccumulator(dim, threshold);
    • compute() = reduce(acc.counts(), averaging) { tp, fp, fn -> if (tp + fp == 0L) 0.0 else tp.toDouble() / (tp + fp) };
    • reset() delegates.
      Mirror Accuracy.kt's KDoc style (what the metric means, the dim / threshold semantics, what averaging does).
  2. Add factory functions at the bottom of the file mirroring accuracy() / binaryAccuracy():
    public fun precision(averaging: Averaging = Averaging.MACRO, dim: Int = -1): Metric and
    public fun binaryPrecision(threshold: Float = 0.5f): Metric.
  3. Tests in skainet-backends/skainet-backend-cpu/src/commonTest/kotlin/sk/ainet/exec/metrics/PrecisionTest.kt,
    copying AccuracyTest.kt's tensor helpers. Cover, with hand-computed expected values
    (see the parent issue and [Lane 1 · numerics] Precision/Recall/F1 — averaging-mode and zero-division conventions #1224 for the reference fixture pred [2,0,1,2], target [2,1,1,0]):
    • macro multi-class with Int32 index targets → 0.5;
    • micro multi-class → 0.5 (and assert it equals Accuracy on the same batch);
    • the same batch with soft (FP32 one-hot) targets gives the same result;
    • binary with threshold, 2-class logits;
    • accumulation across two update() calls equals one call on the concatenated batch;
    • zero-division: a class with TP+FP+FN = 0 contributes 0.0 (per [Lane 1 · numerics] Precision/Recall/F1 — averaging-mode and zero-division conventions #1224), and
      compute() on a fresh metric returns 0.0.
  4. ./gradlew :skainet-lang:skainet-lang-core:apiDump and
    ./gradlew :skainet-backends:skainet-backend-cpu:jvmTest --tests "sk.ainet.exec.metrics.*".

Acceptance

Notes

Precision answers "of what I predicted positive, how much was right". The twin task #1228 (Recall) is the same shape with tp / (tp + fn) — if you take both, fine, but they are filed separately so two people can each ship one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    codingImplementation task (DARC: C)good first issueGood for newcomers; no prior SKaiNET codebase knowledge assumedsize:sA few hoursskill:kotlin-coreKotlin implementation in commonMainsub-issueSub-issue of a tracking issuetrainingTraining pipeline, optimizers, loss

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions