use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion};
use fdars_core::explain_generic::{
generic_pdp, generic_permutation_importance, generic_shap_values,
};
use fdars_core::matrix::FdMatrix;
use fdars_core::scalar_on_function::fregre_lm;
use std::f64::consts::PI;
fn generate_regression_data(n: usize, m: usize) -> (FdMatrix, Vec<f64>) {
let mut data = vec![0.0; n * m];
for i in 0..n {
let c1 = ((i as f64 * 3.7).sin()) * 2.0;
let c2 = ((i as f64 * 5.1 + 0.3).sin()) * 1.5;
let c3 = ((i as f64 * 7.9 + 0.7).sin()) * 1.0;
for j in 0..m {
let t = j as f64 / (m - 1) as f64;
data[i + j * n] =
c1 * (2.0 * PI * t).sin() + c2 * (4.0 * PI * t).sin() + c3 * (6.0 * PI * t).sin();
}
}
let y: Vec<f64> = (0..n)
.map(|i| {
let c1 = ((i as f64 * 3.7).sin()) * 2.0;
let c2 = ((i as f64 * 5.1 + 0.3).sin()) * 1.5;
let noise = ((i as f64 * 13.7).sin()) * 0.1;
2.0 * c1 + 1.0 * c2 + noise
})
.collect();
let mat = FdMatrix::from_column_major(data, n, m).unwrap();
(mat, y)
}
fn bench_shap_values(c: &mut Criterion) {
let mut group = c.benchmark_group("generic_shap_values");
let m = 50;
let ncomp = 5;
let seed = 42;
let n = 50;
let (data, y) = generate_regression_data(n, m);
let model = fregre_lm(&data, &y, None, ncomp).unwrap();
for &n_samples in &[50, 100, 200] {
let label = format!("n{}_ns{}", n, n_samples);
group.bench_with_input(BenchmarkId::new("params", &label), &label, |b, _| {
b.iter(|| {
generic_shap_values(
black_box(&model),
black_box(&data),
None,
black_box(n_samples),
black_box(seed),
)
});
});
}
let n_samples = 100;
for &n in &[30, 50, 100] {
let (data_n, y_n) = generate_regression_data(n, m);
let model_n = fregre_lm(&data_n, &y_n, None, ncomp).unwrap();
let label = format!("n{}_ns{}", n, n_samples);
group.bench_with_input(BenchmarkId::new("scale", &label), &label, |b, _| {
b.iter(|| {
generic_shap_values(
black_box(&model_n),
black_box(&data_n),
None,
black_box(n_samples),
black_box(seed),
)
});
});
}
group.finish();
}
fn bench_permutation_importance(c: &mut Criterion) {
let mut group = c.benchmark_group("generic_permutation_importance");
let m = 50;
let ncomp = 5;
let n_perm = 50;
let seed = 42;
for &n in &[50, 100, 200] {
let (data, y) = generate_regression_data(n, m);
let model = fregre_lm(&data, &y, None, ncomp).unwrap();
group.bench_with_input(BenchmarkId::new("n", n), &n, |b, _| {
b.iter(|| {
generic_permutation_importance(
black_box(&model),
black_box(&data),
black_box(&y),
black_box(n_perm),
black_box(seed),
)
});
});
}
group.finish();
}
fn bench_pdp(c: &mut Criterion) {
let mut group = c.benchmark_group("generic_pdp");
let m = 50;
let ncomp = 5;
let n_grid = 20;
for &n in &[50, 100, 200] {
let (data, y) = generate_regression_data(n, m);
let model = fregre_lm(&data, &y, None, ncomp).unwrap();
group.bench_with_input(BenchmarkId::new("n", n), &n, |b, _| {
b.iter(|| {
generic_pdp(
black_box(&model),
black_box(&data),
None,
black_box(0), black_box(n_grid),
)
});
});
}
let n = 50;
let (data, y) = generate_regression_data(n, m);
let model = fregre_lm(&data, &y, None, ncomp).unwrap();
for component in 0..ncomp.min(3) {
group.bench_with_input(
BenchmarkId::new("component", component),
&component,
|b, &comp| {
b.iter(|| {
generic_pdp(
black_box(&model),
black_box(&data),
None,
black_box(comp),
black_box(n_grid),
)
});
},
);
}
group.finish();
}
criterion_group!(
benches,
bench_shap_values,
bench_permutation_importance,
bench_pdp,
);
criterion_main!(benches);