ClassificationResult.java
package org.hammer.audio.experimental.acoustic.wingbeat;
import java.util.Objects;
/**
* Result of a wingbeat classification.
*
* <p>Every result carries a label string (one of the constants defined in {@link WingbeatLabel})
* and a confidence value in {@code [0,1]}. An optional reference to the feature vector used for
* classification is included for traceability and debugging.
*
* <p>Callers should not treat the {@link #confidence()} as a calibrated probability without
* empirical validation against a labelled dataset. It is a heuristic score.
*
* @param label classification label; must not be blank
* @param confidence classification confidence in {@code [0,1]}
* @param featureVector the feature vector that produced this result, or {@code null} if not
* retained
*/
public record ClassificationResult(
String label, double confidence, WingbeatFeatureVector featureVector) {
/* Validate fields. */
public ClassificationResult {
Objects.requireNonNull(label, "label");
if (label.isBlank()) {
throw new IllegalArgumentException("label must not be blank");
}
if (!Double.isFinite(confidence) || confidence < 0.0 || confidence > 1.0) {
throw new IllegalArgumentException("confidence must be finite and in [0,1]");
}
}
/**
* Create a result without retaining the feature vector.
*
* @param label classification label; must not be blank
* @param confidence classification confidence in {@code [0,1]}
*/
public ClassificationResult(String label, double confidence) {
this(label, confidence, null);
}
/**
* Create an unknown result with zero confidence and no feature vector.
*
* @return unknown classification result
*/
public static ClassificationResult unknown() {
return new ClassificationResult(WingbeatLabel.UNKNOWN, 0.0, null);
}
}