use driftwatch::{
DatasetMonitor, EqualFrequencyBinning, LiveFeature, LogAlerter, ReferenceDistribution,
};
struct Lcg(u64);
impl Lcg {
fn next_unit(&mut self) -> f64 {
self.0 = self
.0
.wrapping_mul(6364136223846793005)
.wrapping_add(1442695040888963407);
(self.0 >> 11) as f64 / (1u64 << 53) as f64
}
fn sample(&mut self, mean: f64, spread: f64) -> f64 {
let u = self.next_unit() + self.next_unit() + self.next_unit();
mean + (u - 1.5) * spread
}
}
fn main() {
tracing_subscriber::fmt::init();
let mut rng = Lcg(0x1234_5678);
let ref_latency: Vec<f64> = (0..1000).map(|_| rng.sample(100.0, 20.0)).collect();
let ref_amount: Vec<f64> = (0..1000).map(|_| rng.sample(50.0, 10.0)).collect();
let mut monitor = DatasetMonitor::new();
monitor.add_feature(
ReferenceDistribution::fit_continuous(
"latency_ms",
&ref_latency,
EqualFrequencyBinning::default(),
)
.unwrap(),
);
monitor.add_feature(
ReferenceDistribution::fit_continuous(
"amount",
&ref_amount,
EqualFrequencyBinning::default(),
)
.unwrap(),
);
let monitor = monitor
.with_dataset_fraction_threshold(0.4)
.with_alerter(Box::new(LogAlerter::new()));
let live_latency: Vec<f64> = (0..500).map(|_| rng.sample(160.0, 25.0)).collect();
let live_amount: Vec<f64> = (0..500).map(|_| rng.sample(50.0, 10.0)).collect();
let report = monitor
.check(&[
("latency_ms", LiveFeature::Continuous(&live_latency)),
("amount", LiveFeature::Continuous(&live_amount)),
])
.unwrap();
println!("{report}");
println!(
"dataset drift detected: {}",
report.dataset_drift_detected()
);
}