spawn_access_control/
ml_metrics.rsuse serde::{Serialize, Deserialize};
use std::collections::HashMap;
use chrono::{DateTime, Utc};
use std::time::Duration;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ModelMetrics {
pub model_id: String,
pub timestamp: DateTime<Utc>,
pub accuracy: f64,
pub precision: f64,
pub recall: f64,
pub f1_score: f64,
pub confusion_matrix: ConfusionMatrix,
pub feature_importance: HashMap<String, f64>,
pub training_duration: Duration,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConfusionMatrix {
pub true_positives: u32,
pub true_negatives: u32,
pub false_positives: u32,
pub false_negatives: u32,
}
impl ConfusionMatrix {
pub fn new() -> Self {
Self {
true_positives: 0,
true_negatives: 0,
false_positives: 0,
false_negatives: 0,
}
}
pub fn update(&mut self, predicted: bool, actual: bool) {
match (predicted, actual) {
(true, true) => self.true_positives += 1,
(false, false) => self.true_negatives += 1,
(true, false) => self.false_positives += 1,
(false, true) => self.false_negatives += 1,
}
}
pub fn accuracy(&self) -> f64 {
let total = self.total() as f64;
if total == 0.0 {
return 0.0;
}
(self.true_positives + self.true_negatives) as f64 / total
}
pub fn precision(&self) -> f64 {
let predicted_positive = self.true_positives + self.false_positives;
if predicted_positive == 0 {
return 0.0;
}
self.true_positives as f64 / predicted_positive as f64
}
pub fn recall(&self) -> f64 {
let actual_positive = self.true_positives + self.false_negatives;
if actual_positive == 0 {
return 0.0;
}
self.true_positives as f64 / actual_positive as f64
}
pub fn f1_score(&self) -> f64 {
let precision = self.precision();
let recall = self.recall();
if precision + recall == 0.0 {
return 0.0;
}
2.0 * (precision * recall) / (precision + recall)
}
fn total(&self) -> u32 {
self.true_positives + self.true_negatives +
self.false_positives + self.false_negatives
}
}