klydekushy commited on
Commit
409f286
·
verified ·
1 Parent(s): 2d5ea43

Create validation_engine.py

Browse files
Files changed (1) hide show
  1. src/core/validation_engine.py +60 -0
src/core/validation_engine.py ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ MODULE: VALIDATION ENGINE
3
+ =========================
4
+ Responsabilité : Vérifier la qualité des données post-ingestion.
5
+ """
6
+ import pandas as pd
7
+
8
+ class ValidationEngine:
9
+ def __init__(self, rdf_store, ontology_manager):
10
+ self.rdf = rdf_store
11
+ self.onto = ontology_manager
12
+ self.report = {}
13
+
14
+ def run_validation(self):
15
+ """Exécute une batterie de tests sur le graphe"""
16
+ print("🔍 [VALIDATION] Démarrage de l'audit des données...")
17
+
18
+ real_schema = self.rdf.get_full_schema()
19
+ theoretical_classes = self.onto.structure["classes"]
20
+
21
+ # 1. Validation des Volumes
22
+ self.report["volumes"] = real_schema.get("classes", {})
23
+
24
+ # 2. Validation de la Couverture (Propriétés Critiques)
25
+ # On vérifie si les propriétés définies dans l'Ontology existent vraiment
26
+ self.report["missing_props"] = {}
27
+
28
+ # Pour faire simple et rapide : on check un échantillon
29
+ for cls in list(theoretical_classes)[:5]: # Check les 5 premières classes majeures
30
+ expected_props = self.onto.structure["properties"].get(cls, [])
31
+ if not expected_props: continue
32
+
33
+ # Requête SPARQL pour vérifier si ces props sont utilisées
34
+ for prop in expected_props:
35
+ # Est-ce que au moins 1 entité de cette classe a cette prop ?
36
+ q = f"""
37
+ ASK {{
38
+ ?s a vortex:{cls} .
39
+ ?s vortex:{prop} ?o .
40
+ }}
41
+ """
42
+ exists = bool(self.rdf.g.query(f"PREFIX vortex: <http://vortex.ai/ontology#> {q}"))
43
+ if not exists:
44
+ if cls not in self.report["missing_props"]: self.report["missing_props"][cls] = []
45
+ self.report["missing_props"][cls].append(prop)
46
+
47
+ return self.report
48
+
49
+ def generate_metrics_dashboard(self):
50
+ """Retourne des KPIs pour l'interface Streamlit"""
51
+ total_triples = len(self.rdf.g)
52
+ total_entities = sum(self.report.get("volumes", {}).values())
53
+ missing_count = sum([len(v) for v in self.report.get("missing_props", {}).values()])
54
+
55
+ return {
56
+ "triples": total_triples,
57
+ "entities": total_entities,
58
+ "coverage_score": max(0, 100 - (missing_count * 2)), # Score arbitraire
59
+ "alerts": self.report.get("missing_props", {})
60
+ }