(
build_classifier: &F,
params: &ParamSet,
splits: &[(Vec<usize>, Vec<usize>)],
x: &[Vec<f64>],
y: &[f64],
sample_weight: Option<&[f64]>,
scoring: SearchScoring,
)
| 385 | } |
| 386 | |
| 387 | fn evaluate_params<C, F>( |
| 388 | build_classifier: &F, |
| 389 | params: &ParamSet, |
| 390 | splits: &[(Vec<usize>, Vec<usize>)], |
| 391 | x: &[Vec<f64>], |
| 392 | y: &[f64], |
| 393 | sample_weight: Option<&[f64]>, |
| 394 | scoring: SearchScoring, |
| 395 | ) -> Result<Vec<f64>, String> |
| 396 | where |
| 397 | C: SimpleClassifier, |
| 398 | F: Fn(&ParamSet) -> C, |
| 399 | { |
| 400 | let mut fold_scores = Vec::with_capacity(splits.len()); |
| 401 | |
| 402 | for (train_idx, test_idx) in splits { |
| 403 | if train_idx.is_empty() || test_idx.is_empty() { |
| 404 | return Err("PurgedKFold generated an empty train/test fold".to_string()); |
| 405 | } |
| 406 | |
| 407 | let x_train: Vec<Vec<f64>> = train_idx.iter().map(|i| x[*i].clone()).collect(); |
| 408 | let y_train: Vec<f64> = train_idx.iter().map(|i| y[*i]).collect(); |
| 409 | let x_test: Vec<Vec<f64>> = test_idx.iter().map(|i| x[*i].clone()).collect(); |
| 410 | let y_test: Vec<f64> = test_idx.iter().map(|i| y[*i]).collect(); |
| 411 | |
| 412 | let sw_train: Option<Vec<f64>> = |
| 413 | sample_weight.map(|sw| train_idx.iter().map(|i| sw[*i]).collect()); |
| 414 | let sw_test: Option<Vec<f64>> = |
| 415 | sample_weight.map(|sw| test_idx.iter().map(|i| sw[*i]).collect()); |
| 416 | |
| 417 | let mut clf = build_classifier(params); |
| 418 | clf.fit(&x_train, &y_train, sw_train.as_deref()); |
| 419 | let probs = clf.predict_proba(&x_test); |
| 420 | let fold_score = classification_score(&y_test, &probs, sw_test.as_deref(), scoring)?; |
| 421 | fold_scores.push(fold_score); |
| 422 | } |
| 423 | |
| 424 | Ok(fold_scores) |
| 425 | } |
no test coverage detected