KSvend commited on
Commit
cbe084f
·
1 Parent(s): aa09e0b

feat: add four-factor confidence scoring model

Browse files
app/analysis/confidence.py ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Four-factor confidence scoring for EO indicators."""
2
+ from __future__ import annotations
3
+
4
+ from typing import Any
5
+
6
+ from app.models import ConfidenceLevel
7
+
8
+
9
+ def score_temporal_coverage(valid_months: int) -> float:
10
+ if valid_months >= 10:
11
+ return 1.0
12
+ if valid_months >= 7:
13
+ return 0.75
14
+ if valid_months >= 4:
15
+ return 0.5
16
+ return 0.25
17
+
18
+
19
+ def score_observation_density(mean_obs: float) -> float:
20
+ if mean_obs > 10:
21
+ return 1.0
22
+ if mean_obs >= 6:
23
+ return 0.75
24
+ if mean_obs >= 3:
25
+ return 0.5
26
+ return 0.25
27
+
28
+
29
+ def score_baseline_depth(years_with_data: int) -> float:
30
+ if years_with_data >= 5:
31
+ return 1.0
32
+ if years_with_data >= 4:
33
+ return 0.75
34
+ if years_with_data >= 2:
35
+ return 0.5
36
+ return 0.25
37
+
38
+
39
+ def score_spatial_completeness(fraction: float) -> float:
40
+ if fraction > 0.9:
41
+ return 1.0
42
+ if fraction > 0.75:
43
+ return 0.75
44
+ if fraction >= 0.5:
45
+ return 0.5
46
+ return 0.25
47
+
48
+
49
+ def compute_confidence(
50
+ valid_months: int,
51
+ mean_obs_per_composite: float,
52
+ baseline_years_with_data: int,
53
+ spatial_completeness: float,
54
+ ) -> dict[str, Any]:
55
+ temporal = score_temporal_coverage(valid_months)
56
+ obs = score_observation_density(mean_obs_per_composite)
57
+ baseline = score_baseline_depth(baseline_years_with_data)
58
+ spatial = score_spatial_completeness(spatial_completeness)
59
+
60
+ score = temporal * 0.3 + obs * 0.2 + baseline * 0.3 + spatial * 0.2
61
+
62
+ if score > 0.7:
63
+ level = ConfidenceLevel.HIGH
64
+ elif score >= 0.4:
65
+ level = ConfidenceLevel.MODERATE
66
+ else:
67
+ level = ConfidenceLevel.LOW
68
+
69
+ return {
70
+ "level": level,
71
+ "score": round(score, 3),
72
+ "factors": {
73
+ "temporal": temporal,
74
+ "observation_density": obs,
75
+ "baseline_depth": baseline,
76
+ "spatial_completeness": spatial,
77
+ },
78
+ }
tests/test_confidence.py ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Tests for four-factor confidence scoring."""
2
+ import pytest
3
+
4
+
5
+ def test_score_temporal_coverage():
6
+ from app.analysis.confidence import score_temporal_coverage
7
+ assert score_temporal_coverage(0) == 0.25
8
+ assert score_temporal_coverage(3) == 0.25
9
+ assert score_temporal_coverage(5) == 0.5
10
+ assert score_temporal_coverage(8) == 0.75
11
+ assert score_temporal_coverage(12) == 1.0
12
+
13
+
14
+ def test_score_observation_density():
15
+ from app.analysis.confidence import score_observation_density
16
+ assert score_observation_density(1.0) == 0.25
17
+ assert score_observation_density(4.0) == 0.5
18
+ assert score_observation_density(8.0) == 0.75
19
+ assert score_observation_density(15.0) == 1.0
20
+
21
+
22
+ def test_score_baseline_depth():
23
+ from app.analysis.confidence import score_baseline_depth
24
+ assert score_baseline_depth(1) == 0.25
25
+ assert score_baseline_depth(3) == 0.5
26
+ assert score_baseline_depth(4) == 0.75
27
+ assert score_baseline_depth(5) == 1.0
28
+
29
+
30
+ def test_score_spatial_completeness():
31
+ from app.analysis.confidence import score_spatial_completeness
32
+ assert score_spatial_completeness(0.3) == 0.25
33
+ assert score_spatial_completeness(0.6) == 0.5
34
+ assert score_spatial_completeness(0.85) == 0.75
35
+ assert score_spatial_completeness(0.95) == 1.0
36
+
37
+
38
+ def test_compute_confidence_high():
39
+ from app.analysis.confidence import compute_confidence
40
+ from app.models import ConfidenceLevel
41
+ result = compute_confidence(
42
+ valid_months=12, mean_obs_per_composite=15.0,
43
+ baseline_years_with_data=5, spatial_completeness=0.95,
44
+ )
45
+ assert result["level"] == ConfidenceLevel.HIGH
46
+ assert result["score"] > 0.7
47
+
48
+
49
+ def test_compute_confidence_low():
50
+ from app.analysis.confidence import compute_confidence
51
+ from app.models import ConfidenceLevel
52
+ result = compute_confidence(
53
+ valid_months=2, mean_obs_per_composite=1.5,
54
+ baseline_years_with_data=1, spatial_completeness=0.3,
55
+ )
56
+ assert result["level"] == ConfidenceLevel.LOW
57
+ assert result["score"] < 0.4
58
+
59
+
60
+ def test_compute_confidence_returns_factors():
61
+ from app.analysis.confidence import compute_confidence
62
+ result = compute_confidence(
63
+ valid_months=6, mean_obs_per_composite=5.0,
64
+ baseline_years_with_data=3, spatial_completeness=0.8,
65
+ )
66
+ assert "factors" in result
67
+ factors = result["factors"]
68
+ assert "temporal" in factors
69
+ assert "observation_density" in factors
70
+ assert "baseline_depth" in factors
71
+ assert "spatial_completeness" in factors