pub fn train_test_split_seeded(
x: &Tensor,
train_ratio: f64,
seed: u64,
) -> Result<(Tensor, Tensor), MattenMlprepError>Expand description
Splits the rows of a 2D tensor into (train, test) by a seeded, shuffled
partition.
n_train = floor(n_rows * train_ratio) // identical to train_test_splitRow order is determined by a Fisher-Yates shuffle of the row indices
(never the data itself), driven by a [SplitMix64] stream seeded from
seed. The first n_train shuffled indices become train; the rest
become test. Only row selection and order differ from
train_test_split; the output sizes match exactly for the same
(x, train_ratio).
§Reproducibility
The same (x, train_ratio, seed) always produces byte-identical output,
on every platform and every future release of this crate. The PRNG
constants, the shuffle direction, and the seed-to-state mapping are part
of this function’s observable, contract-bearing behavior (RFC-077 §6) and
will not change without a documented breaking change.
§Errors
MattenMlprepError::ExpectedMatrixifxis not rank-2.MattenMlprepError::InvalidRatioiftrain_ratiois not finite or not in(0.0, 1.0).MattenMlprepError::EmptySplitiffloor(rows * train_ratio) == 0.MattenMlprepError::DynamicTensor(with thedynamicfeature) ifxis dynamic.
use matten::Tensor;
use matten_mlprep::train_test_split_seeded;
let x = Tensor::new(vec![10.0, 20.0, 30.0, 40.0, 50.0], &[5, 1]);
let (train, test) = train_test_split_seeded(&x, 0.6, 42).unwrap();
assert_eq!(train.shape(), &[3, 1]);
assert_eq!(test.shape(), &[2, 1]);
// Same seed -> byte-identical output.
let (train2, test2) = train_test_split_seeded(&x, 0.6, 42).unwrap();
assert_eq!(train.as_slice(), train2.as_slice());
assert_eq!(test.as_slice(), test2.as_slice());Examples found in repository?
17fn main() {
18 let x = Tensor::new(vec![10.0, 20.0, 30.0, 40.0, 50.0], &[5, 1]);
19 let (train, test) = train_test_split_seeded(&x, 0.6, 7).expect("valid split"); // 3 / 2
20 println!("train {:?}: {:?}", train.shape(), train.as_slice());
21 println!("test {:?}: {:?}", test.shape(), test.as_slice());
22
23 assert_eq!(train.shape(), &[3, 1]);
24 assert_eq!(test.shape(), &[2, 1]);
25
26 // Re-running with the same seed reproduces the exact same split.
27 let (train2, test2) = train_test_split_seeded(&x, 0.6, 7).expect("valid split");
28 assert_eq!(train.as_slice(), train2.as_slice());
29 assert_eq!(test.as_slice(), test2.as_slice());
30 println!("same seed -> reproduced split: OK");
31
32 // A different seed shuffles differently.
33 let (train3, _) = train_test_split_seeded(&x, 0.6, 8).expect("valid split");
34 println!(
35 "different seed -> train {:?}: {:?}",
36 train3.shape(),
37 train3.as_slice()
38 );
39
40 println!("train_test_split_seeded: OK");
41}