1#![allow(clippy::too_many_arguments)]
7#![allow(dead_code)]
8
9use crate::error::{MetricsError, Result};
10use scirs2_core::ndarray::{Array1, Array2};
11use scirs2_core::numeric::Float;
12use serde::{Deserialize, Serialize};
13use std::collections::{HashMap, VecDeque};
14use std::time::{Duration, Instant, SystemTime};
15
16#[derive(Debug, Clone, Serialize, Deserialize)]
18pub struct StreamingConfig {
19 pub base_window_size: usize,
21 pub max_window_size: usize,
23 pub min_window_size: usize,
25 pub drift_sensitivity: f64,
27 pub warning_threshold: f64,
29 pub drift_threshold: f64,
31 pub adaptive_windowing: bool,
33 pub adaptation_strategy: WindowAdaptationStrategy,
35 pub enable_drift_detection: bool,
37 pub drift_detection_methods: Vec<DriftDetectionMethod>,
39 pub enable_anomaly_detection: bool,
41 pub anomaly_algorithm: AnomalyDetectionAlgorithm,
43 pub monitoring_interval: Duration,
45 pub enable_alerts: bool,
47 pub alert_config: AlertConfig,
49}
50
51#[derive(Debug, Clone, Serialize, Deserialize)]
53pub enum WindowAdaptationStrategy {
54 Fixed,
56 ExponentialDecay { decay_rate: f64 },
58 PerformanceBased { target_accuracy: f64 },
60 DriftBased,
62 Hybrid {
64 strategies: Vec<WindowAdaptationStrategy>,
65 weights: Vec<f64>,
66 },
67 MLBased { model_type: String },
69}
70
71#[derive(Debug, Clone, Serialize, Deserialize)]
73pub enum DriftDetectionMethod {
74 Adwin { confidence: f64 },
76 Ddm {
78 warning_level: f64,
79 drift_level: f64,
80 },
81 Eddm { alpha: f64, beta: f64 },
83 PageHinkley { threshold: f64, alpha: f64 },
85 Cusum {
87 threshold: f64,
88 drift_threshold: f64,
89 },
90 KolmogorovSmirnov { p_value_threshold: f64 },
92 Ensemble { methods: Vec<DriftDetectionMethod> },
94 Custom {
96 name: String,
97 parameters: HashMap<String, f64>,
98 },
99}
100
101#[derive(Debug, Clone, Serialize, Deserialize)]
103pub enum AnomalyDetectionAlgorithm {
104 ZScore { threshold: f64 },
106 IsolationForest { contamination: f64 },
108 OneClassSvm { nu: f64 },
110 LocalOutlierFactor { n_neighbors: usize },
112 Dbscan { eps: f64, min_samples: usize },
114 Autoencoder { threshold: f64 },
116 Ensemble {
118 algorithms: Vec<AnomalyDetectionAlgorithm>,
119 },
120}
121
122#[derive(Debug, Clone, Serialize, Deserialize)]
124pub struct AlertConfig {
125 pub email_enabled: bool,
127 pub email_addresses: Vec<String>,
129 pub webhook_enabled: bool,
131 pub webhook_urls: Vec<String>,
133 pub log_enabled: bool,
135 pub log_file: Option<String>,
137 pub severity_levels: HashMap<String, AlertSeverity>,
139 pub rate_limit: Duration,
141}
142
143#[derive(Debug, Clone, Serialize, Deserialize)]
145pub enum AlertSeverity {
146 Critical,
147 High,
148 Medium,
149 Low,
150 Info,
151}
152
153pub trait ConceptDriftDetector<F: Float + std::fmt::Debug + Send + Sync + std::iter::Sum>:
155 std::fmt::Debug
156{
157 fn update(&mut self, prediction_correct: bool, error: F) -> Result<DriftDetectionResult>;
159
160 fn get_status(&self) -> DriftStatus;
162
163 fn reset(&mut self);
165
166 fn get_config(&self) -> HashMap<String, f64>;
168
169 fn get_statistics(&self) -> DriftStatistics<F>;
171}
172
173#[derive(Debug, Clone)]
175pub struct DriftDetectionResult {
176 pub status: DriftStatus,
177 pub confidence: f64,
178 pub change_point: Option<usize>,
179 pub statistics: HashMap<String, f64>,
180}
181
182#[derive(Debug, Clone, PartialEq)]
184pub enum DriftStatus {
185 Stable,
186 Warning,
187 Drift,
188 Unknown,
189}
190
191#[derive(Debug, Clone)]
193pub struct DriftStatistics<F: Float + std::fmt::Debug> {
194 pub samples_since_reset: usize,
195 pub warnings_count: usize,
196 pub drifts_count: usize,
197 pub current_error_rate: F,
198 pub baseline_error_rate: F,
199 pub drift_score: F,
200 pub last_detection_time: Option<SystemTime>,
201}
202
203pub trait StreamingMetric<F: Float> {
205 fn update(&mut self, true_value: F, predicted_value: F) -> Result<()>;
206 fn get_value(&self) -> F;
207 fn reset(&mut self);
208 fn get_name(&self) -> &str;
209 fn get_confidence(&self) -> F;
210}
211
212#[derive(Debug, Clone)]
214pub enum EnsembleAggregation {
215 WeightedAverage,
216 Majority,
217 Maximum,
218 Minimum,
219 Median,
220 Stacking { meta_learner: String },
221}
222
223#[derive(Debug, Clone)]
225pub struct DataPoint<F: Float + std::fmt::Debug> {
226 pub true_value: F,
227 pub predicted_value: F,
228 pub error: F,
229 pub confidence: F,
230 pub features: Option<Vec<F>>,
231}
232
233#[derive(Debug, Clone)]
235pub struct Alert {
236 pub id: String,
237 pub timestamp: Instant,
238 pub severity: AlertSeverity,
239 pub title: String,
240 pub message: String,
241 pub data: HashMap<String, String>,
242 pub tags: Vec<String>,
243}
244
245#[derive(Debug, Clone)]
247pub struct SentAlert {
248 pub alert: Alert,
249 pub sent_at: Instant,
250 pub channels: Vec<String>,
251 pub success: bool,
252 pub error_message: Option<String>,
253}
254
255impl Default for StreamingConfig {
256 fn default() -> Self {
257 Self {
258 base_window_size: 1000,
259 max_window_size: 10000,
260 min_window_size: 100,
261 drift_sensitivity: 0.05,
262 warning_threshold: 0.5,
263 drift_threshold: 0.8,
264 adaptive_windowing: true,
265 adaptation_strategy: WindowAdaptationStrategy::DriftBased,
266 enable_drift_detection: true,
267 drift_detection_methods: vec![
268 DriftDetectionMethod::Adwin { confidence: 0.95 },
269 DriftDetectionMethod::Ddm {
270 warning_level: 2.0,
271 drift_level: 3.0,
272 },
273 ],
274 enable_anomaly_detection: true,
275 anomaly_algorithm: AnomalyDetectionAlgorithm::ZScore { threshold: 3.0 },
276 monitoring_interval: Duration::from_secs(60),
277 enable_alerts: false,
278 alert_config: AlertConfig::default(),
279 }
280 }
281}
282
283impl Default for AlertConfig {
284 fn default() -> Self {
285 Self {
286 email_enabled: false,
287 email_addresses: Vec::new(),
288 webhook_enabled: false,
289 webhook_urls: Vec::new(),
290 log_enabled: true,
291 log_file: None,
292 severity_levels: HashMap::new(),
293 rate_limit: Duration::from_secs(300),
294 }
295 }
296}