Skip to content

v0.6.9 Release - #439

Merged
Mec-iS merged 3 commits into
mainfrom
development
Aug 21, 2026
Merged

v0.6.9 Release#439
Mec-iS merged 3 commits into
mainfrom
development

Conversation

@Mec-iS

@Mec-iS Mec-iS commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

No description provided.

Mec-iS added 2 commits August 21, 2026 16:09
Relax Precision, Recall and F1 (structs and free functions) from
Number + RealNumber + FloatNumber to Number. Classification metrics
need only equality and a canonical class key, so ordered integer
labels (u16, i32, ...) now work. This lets the same y feed
RandomForestClassifier::fit (Number + Ord) and cross_validate with
&precision / &recall / &f1.

Class keys are derived through a shared label_bits helper (to_f64
widening) instead of RealNumber::to_f64_bits raw transmutation;
float-input scores are unchanged.

- add integer-label unit tests to precision/recall/f1
- add regression test: cross_validate(RandomForestClassifier, ...,
  &precision) with Vec<u16> labels (#322)
- bump patch 0.6.8 -> 0.6.9
- label_bits: replace unwrap with expect for a clear panic message
  when a custom Number impl fails to_f64 conversion
- regression test: use DenseMatrix<f32> features, mirroring the
  exact report in #322
@Mec-iS

Mec-iS commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator Author

Review

Verified locally on the development branch (this PR's head):

Code correctness looks solid:

  • label_bits correctly widens any Number to f64 via ToPrimitive::to_f64(). I checked to_f64() returns Some for every current Number impl (f32/f64/all integer primitives), so .expect("class label must convert to f64") can't panic today.
  • Bonus fix: the old RealNumber::to_f64_bits for f32 did self.to_bits() as u64 (widening the raw 32-bit pattern into a u64, not actually converting the value to f64). label_bits now does a real value conversion. Never mattered in practice (y_true/y_pred are always the same T), but it's a latent correctness improvement.
  • Per-class precision/recall/F1 math and binary vs. multiclass macro-averaging are unchanged — only the label-keying mechanism and generic bounds changed.

One inconsistency worth fixing before/after merge (not caught by tests/clippy since it's an unused path):

ClassificationMetrics::<T>::precision()/recall()/f1() (src/metrics/mod.rs:122) was not updated and still requires T: Number + RealNumber + FloatNumber, while the standalone precision()/recall()/f1() functions (mod.rs:189-214) now bypass ClassificationMetrics and construct Precision::/Recall::/F1::new() directly with only T: Number. This fails to compile:

ClassificationMetrics::<u16>::precision();
// error[E0599]: trait bounds not satisfied: `u16: RealNumber`, `u16: FloatNumber`

So the struct-based entry point still can't be used with integer labels even though Precision<T> itself and the free precision() function now can. Not a regression, but it leaves the fix for #322 half-applied on the ClassificationMetrics surface, which the module docs point to as the primary entry point. Suggest relaxing the impl<T: Number + RealNumber + FloatNumber> ClassificationMetrics<T> bound the same way (or documenting that integer labels should go through the free functions / Precision::new() directly).

Minor nit: the CHANGELOG entry says labels "no longer need to implement RealNumber" but doesn't mention FloatNumber was also dropped from the bound — harmless, just slightly incomplete.

Otherwise LGTM — approve after the ClassificationMetrics bound is addressed (or explicitly deferred with a note/issue).

precision/recall/f1 on ClassificationMetrics<T> still required
Number + RealNumber + FloatNumber, so the struct-based entry point
could not be used with integer labels even though Precision/Recall/F1
and the free functions accept any Number (#322). Split roc_auc_score
into its own impl block with the bounds AUC itself needs.

Also complete the CHANGELOG wording: FloatNumber was dropped from the
bounds too.
@Mec-iS
Mec-iS merged commit c80a7de into main Aug 21, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant