use driftwatch::LabelDriftMonitor;
use model_selection_rs::scoring::Scorer;
use ndarray::Array1;
struct Accuracy;
impl Scorer for Accuracy {
fn score(&self, y_true: &Array1<f64>, y_pred: &Array1<f64>) -> f64 {
let n = y_true.len();
if n == 0 {
return 0.0;
}
let correct = y_true
.iter()
.zip(y_pred.iter())
.filter(|(a, b)| (**a - **b).abs() < 1e-9)
.count();
correct as f64 / n as f64
}
fn name(&self) -> &str {
"accuracy"
}
fn greater_is_better(&self) -> bool {
true
}
}
fn window(n: usize, error_rate: f64) -> Vec<(f64, f64)> {
let wrong = (n as f64 * error_rate).round() as usize;
(0..n)
.map(|i| {
let actual = 1.0;
let prediction = if i < wrong { 0.0 } else { 1.0 };
(prediction, actual)
})
.collect()
}
fn main() {
let reference = window(1000, 0.05);
let monitor = LabelDriftMonitor::from_reference(Accuracy, &reference, 0.10).unwrap();
println!("baseline accuracy: {:.3}", monitor.baseline_score());
println!();
for (day, error_rate) in [0.06, 0.09, 0.15, 0.28].into_iter().enumerate() {
let live = window(500, error_rate);
let report = monitor.check(&live).unwrap();
println!(
"day {}: accuracy {:.3} degradation {:+.3} {}",
day + 1,
report.rolling_score,
report.degradation,
if report.drifted { "DRIFT" } else { "ok" },
);
}
}