mgbam commited on
Commit
6811ecf
·
verified ·
1 Parent(s): e049c25

Upload 6 files

Browse files
Files changed (2) hide show
  1. app/ml/gating.py +4 -1
  2. app/ml/sundew_fallback.py +66 -0
app/ml/gating.py CHANGED
@@ -1,6 +1,9 @@
1
  from typing import Any, Dict, List, Tuple
2
 
3
- from sundew.gating import gate_probability_with_hysteresis, significance_score
 
 
 
4
 
5
 
6
  def _clamp(value: float, low: float = 0.0, high: float = 1.0) -> float:
 
1
  from typing import Any, Dict, List, Tuple
2
 
3
+ try:
4
+ from sundew.gating import gate_probability_with_hysteresis, significance_score
5
+ except ImportError:
6
+ from app.ml.sundew_fallback import gate_probability_with_hysteresis, significance_score
7
 
8
 
9
  def _clamp(value: float, low: float = 0.0, high: float = 1.0) -> float:
app/ml/sundew_fallback.py ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Fallback implementation of Sundew gating algorithms.
3
+ Replace with actual sundew-algorithms package for production.
4
+ """
5
+ import math
6
+
7
+
8
+ def significance_score(
9
+ features: dict,
10
+ w_mag: float = 0.35,
11
+ w_ano: float = 0.4,
12
+ w_ctx: float = 0.15,
13
+ w_urg: float = 0.1
14
+ ) -> float:
15
+ """
16
+ Compute significance score for a signal window.
17
+
18
+ Args:
19
+ features: Dict with keys: magnitude, anomaly_score, context_relevance, urgency
20
+ w_mag: Weight for magnitude
21
+ w_ano: Weight for anomaly score
22
+ w_ctx: Weight for context relevance
23
+ w_urg: Weight for urgency
24
+
25
+ Returns:
26
+ Significance score in [0, 1]
27
+ """
28
+ score = (
29
+ w_mag * min(features.get("magnitude", 0.0) / 100.0, 1.0) +
30
+ w_ano * features.get("anomaly_score", 0.0) +
31
+ w_ctx * features.get("context_relevance", 0.0) +
32
+ w_urg * features.get("urgency", 0.0)
33
+ )
34
+ return max(0.0, min(1.0, score))
35
+
36
+
37
+ def gate_probability_with_hysteresis(
38
+ significance: float,
39
+ threshold: float = 0.6,
40
+ temperature: float = 0.1,
41
+ last_activation: bool = False
42
+ ) -> float:
43
+ """
44
+ Convert significance to gate probability with hysteresis.
45
+
46
+ Args:
47
+ significance: Significance score in [0, 1]
48
+ threshold: Base threshold for gating
49
+ temperature: Softness of the gate (0 = hard threshold)
50
+ last_activation: Whether previous window was active (for hysteresis)
51
+
52
+ Returns:
53
+ Probability of keeping the window in [0, 1]
54
+ """
55
+ # Apply hysteresis: lower threshold if last was active
56
+ effective_threshold = threshold - (0.1 if last_activation else 0.0)
57
+
58
+ if temperature <= 0:
59
+ # Hard threshold
60
+ return 1.0 if significance >= effective_threshold else 0.0
61
+
62
+ # Soft threshold using sigmoid
63
+ logit = (significance - effective_threshold) / temperature
64
+ prob = 1.0 / (1.0 + math.exp(-logit))
65
+
66
+ return prob