Skip to main content

Crate model_selection_rs

Crate model_selection_rs 

Source
Expand description

§model-selection-rs

Cross-validation and model-selection utilities for Rust, filling the specific gaps in smartcore::model_selection: stratified, group-aware, and time-aware splitting, nested cross-validation, and learning / validation curve utilities — as a standalone, dependency-light crate rather than hand-rolled notebook code.

The crate is deliberately about splitting strategies and evaluation-loop utilities, not hyperparameter search itself. Grid/random search and Bayesian optimizers (e.g. the tpe crate) remain their own job; this crate composes with them — most directly through nested_cross_validate, whose tuning step is a closure you fill with whatever search you like.

§Layout

§Feature flags

  • parallel — fan fold execution out over rayon in the evaluate utilities. Public signatures are unchanged; only wall-clock time differs, and results are numerically identical to the serial path.
  • smartcore-metrics — enable scoring::smartcore_adapter, wrapping smartcore::metrics (F1, ROC-AUC) as Scorers.

§Quick start

use ndarray::{Array1, Array2};
use model_selection_rs::evaluate::{cross_validate, BoxedScorer};
use model_selection_rs::scoring::R2Score;
use model_selection_rs::splitters::KFold;

// Toy: perfectly linear data, a least-squares "model".
let x = Array2::from_shape_fn((20, 1), |(i, _)| i as f64);
let y = x.column(0).mapv(|v| 2.0 * v + 1.0);

let kf = KFold::new(5).unwrap();
let scorers: Vec<BoxedScorer> = vec![Box::new(R2Score)];
let res = cross_validate(&kf, &x, &y, |xt, yt| {
    // fit y = a*x + b by ordinary least squares on one feature
    let n = xt.nrows() as f64;
    let (xs, ys) = (xt.column(0).to_owned(), yt.to_owned());
    let mx = xs.sum() / n; let my = ys.sum() / n;
    let cov = xs.iter().zip(ys.iter()).map(|(a,b)| (a-mx)*(b-my)).sum::<f64>();
    let var = xs.iter().map(|a| (a-mx).powi(2)).sum::<f64>();
    let slope = cov / var; let intercept = my - slope*mx;
    move |xq: &Array2<f64>| xq.column(0).mapv(|v| slope*v + intercept)
}, &scorers, false).unwrap();

assert!((res.mean_test_score(0) - 1.0).abs() < 1e-9); // R2 ~ 1

Re-exports§

pub use error::ModelSelectionError;
pub use error::Result;

Modules§

error
Error type shared across every splitter and evaluation utility.
evaluate
Evaluation-loop utilities that compose a splitter, a model-fitting closure, and one or more scorers.
scoring
Scoring: a lightweight metric abstraction usable standalone or, optionally, backed by smartcore::metrics.
splitters
Cross-validation splitters.