spawn_access_control/
ml_metrics.rs

1use serde::{Serialize, Deserialize};
2use std::collections::HashMap;
3use chrono::{DateTime, Utc};
4use std::time::Duration;
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
7pub struct ModelMetrics {
8    pub model_id: String,
9    pub timestamp: DateTime<Utc>,
10    pub accuracy: f64,
11    pub precision: f64,
12    pub recall: f64,
13    pub f1_score: f64,
14    pub confusion_matrix: ConfusionMatrix,
15    pub feature_importance: HashMap<String, f64>,
16    pub training_duration: Duration,
17}
18
19#[derive(Debug, Clone, Serialize, Deserialize)]
20pub struct ConfusionMatrix {
21    pub true_positives: u32,
22    pub true_negatives: u32,
23    pub false_positives: u32,
24    pub false_negatives: u32,
25}
26
27impl ConfusionMatrix {
28    pub fn new() -> Self {
29        Self {
30            true_positives: 0,
31            true_negatives: 0,
32            false_positives: 0,
33            false_negatives: 0,
34        }
35    }
36
37    pub fn update(&mut self, predicted: bool, actual: bool) {
38        match (predicted, actual) {
39            (true, true) => self.true_positives += 1,
40            (false, false) => self.true_negatives += 1,
41            (true, false) => self.false_positives += 1,
42            (false, true) => self.false_negatives += 1,
43        }
44    }
45
46    pub fn accuracy(&self) -> f64 {
47        let total = self.total() as f64;
48        if total == 0.0 {
49            return 0.0;
50        }
51        (self.true_positives + self.true_negatives) as f64 / total
52    }
53
54    pub fn precision(&self) -> f64 {
55        let predicted_positive = self.true_positives + self.false_positives;
56        if predicted_positive == 0 {
57            return 0.0;
58        }
59        self.true_positives as f64 / predicted_positive as f64
60    }
61
62    pub fn recall(&self) -> f64 {
63        let actual_positive = self.true_positives + self.false_negatives;
64        if actual_positive == 0 {
65            return 0.0;
66        }
67        self.true_positives as f64 / actual_positive as f64
68    }
69
70    pub fn f1_score(&self) -> f64 {
71        let precision = self.precision();
72        let recall = self.recall();
73        if precision + recall == 0.0 {
74            return 0.0;
75        }
76        2.0 * (precision * recall) / (precision + recall)
77    }
78
79    fn total(&self) -> u32 {
80        self.true_positives + self.true_negatives + 
81        self.false_positives + self.false_negatives
82    }
83}