mirror of
https://github.com/semantica-agi/semantica.git
synced 2026-08-29 04:26:20 +00:00
Refactor renewable energy notebooks: modular architecture with unique module combinations
- Rebuilt 01_Energy_Market_Analysis.ipynb with temporal pattern detection, trend prediction, and seed data integration - Rebuilt 02_Smart_Grid_Management.ipynb with stream processing, real-time monitoring, and anomaly detection - Removed core orchestrator usage, implemented cell-specific imports - Added comprehensive data sources and Mermaid pipeline diagrams - Minimal print statements, proper error handling with redirect_stderr - Unique module combinations per use case for differentiation
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -10,30 +10,87 @@
|
||||
"\n",
|
||||
"## Overview\n",
|
||||
"\n",
|
||||
"This notebook demonstrates **smart grid management** using Semantica with focus on **stream processing**, **real-time monitoring**, and **failure prediction**. The pipeline streams grid sensor data to monitor grid health and predict failures using temporal pattern detection.\n",
|
||||
"This notebook demonstrates **smart grid management** using Semantica with focus on **stream processing**, **real-time monitoring**, and **failure prediction**. The pipeline streams grid sensor data to monitor grid health in real-time and predict failures using temporal pattern detection and anomaly detection.\n",
|
||||
"\n",
|
||||
"### Key Features\n",
|
||||
"\n",
|
||||
"- **Stream Processing**: Emphasizes real-time stream ingestion from grid sensors\n",
|
||||
"- **Real-Time Monitoring**: Monitors grid health in real-time\n",
|
||||
"- **Failure Prediction**: Uses temporal pattern detection to predict grid failures\n",
|
||||
"- **Anomaly Detection**: Detects anomalies in grid sensor data\n",
|
||||
"- **Temporal Pattern Detection**: Identifies patterns in sensor data streams\n",
|
||||
"- **Real-Time Monitoring**: Monitors grid health in real-time with minute-level granularity\n",
|
||||
"- **Failure Prediction**: Uses temporal pattern detection and reasoning to predict grid failures\n",
|
||||
"- **Anomaly Detection**: Detects anomalies in grid sensor data using graph analytics\n",
|
||||
"- **Temporal Pattern Detection**: Identifies patterns in sensor data streams over time\n",
|
||||
"- **Alert Generation**: Generates alerts based on sensor anomalies and failure patterns\n",
|
||||
"\n",
|
||||
"### Pipeline Architecture\n",
|
||||
"### Learning Objectives\n",
|
||||
"\n",
|
||||
"1. **Phase 0**: Setup & Configuration\n",
|
||||
"2. **Phase 1**: Grid Sensor Stream Ingestion\n",
|
||||
"3. **Phase 2**: Real-Time Data Parsing\n",
|
||||
"4. **Phase 3**: Sensor Entity Extraction\n",
|
||||
"5. **Phase 4**: Temporal Knowledge Graph Construction\n",
|
||||
"6. **Phase 5**: Real-Time Monitoring\n",
|
||||
"7. **Phase 6**: Failure Prediction & Anomaly Detection\n",
|
||||
"8. **Phase 7**: Alert Generation & Visualization\n",
|
||||
"- Understand how to process real-time sensor streams for grid monitoring\n",
|
||||
"- Learn to build temporal knowledge graphs with minute-level granularity\n",
|
||||
"- Master failure prediction using reasoning and pattern detection\n",
|
||||
"- Explore anomaly detection in grid sensor networks\n",
|
||||
"- Practice real-time temporal queries at specific time points\n",
|
||||
"- Analyze grid health and generate predictive alerts\n",
|
||||
"\n",
|
||||
"---\n",
|
||||
"### Pipeline Flow\n",
|
||||
"\n",
|
||||
"## Installation\n"
|
||||
"```mermaid\n",
|
||||
"graph TD\n",
|
||||
" A[Stream Data Ingestion] --> B[Document Parsing]\n",
|
||||
" B --> C[Text Processing]\n",
|
||||
" C --> D[Entity Extraction]\n",
|
||||
" D --> E[Relationship Extraction]\n",
|
||||
" E --> F[Deduplication]\n",
|
||||
" F --> G[Temporal KG Construction]\n",
|
||||
" G --> H[Embedding Generation]\n",
|
||||
" H --> I[Vector Store]\n",
|
||||
" G --> J[Temporal Queries]\n",
|
||||
" G --> K[Failure Pattern Detection]\n",
|
||||
" G --> L[Anomaly Detection]\n",
|
||||
" I --> M[GraphRAG Queries]\n",
|
||||
" J --> N[Visualization]\n",
|
||||
" K --> N\n",
|
||||
" L --> N\n",
|
||||
" G --> O[Export]\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"### Data Sources\n",
|
||||
"\n",
|
||||
"#### Grid Sensor Stream Sources\n",
|
||||
"- **Kafka Streams**: Real-time sensor data streams (kafka://localhost:9092/grid-sensors)\n",
|
||||
"- **MQTT Brokers**: IoT sensor data (mqtt://broker.example.com/sensors)\n",
|
||||
"- **Apache Pulsar**: Distributed sensor streams (pulsar://localhost:6650/grid-data)\n",
|
||||
"- **Redis Streams**: High-performance sensor streams (redis://localhost:6379/streams)\n",
|
||||
"\n",
|
||||
"#### Smart Grid Monitoring APIs\n",
|
||||
"- **OpenADR (Open Automated Demand Response)**: https://www.openadr.org/\n",
|
||||
"- **IEEE 2030.5 (Smart Energy Profile)**: https://standards.ieee.org/\n",
|
||||
"- **IEC 61850 (Substation Automation)**: https://webstore.iec.ch/\n",
|
||||
"- **DNP3 (Distributed Network Protocol)**: https://www.dnp.org/\n",
|
||||
"\n",
|
||||
"#### Energy Monitoring Platforms\n",
|
||||
"- **GridPoint**: https://www.gridpoint.com/\n",
|
||||
"- **Schneider Electric EcoStruxure**: https://www.se.com/us/en/\n",
|
||||
"- **Siemens MindSphere**: https://siemens.mindsphere.io/\n",
|
||||
"- **GE Digital Predix**: https://www.ge.com/digital/\n",
|
||||
"\n",
|
||||
"#### Grid Management Databases\n",
|
||||
"- **NERC (North American Electric Reliability Corporation)**: https://www.nerc.com/\n",
|
||||
"- **FERC (Federal Energy Regulatory Commission)**: https://www.ferc.gov/\n",
|
||||
"- **DOE Grid Modernization**: https://www.energy.gov/oe/activities/technology-development/grid-modernization\n",
|
||||
"- **Smart Grid Information Clearinghouse**: https://www.sgiclearinghouse.org/\n",
|
||||
"\n",
|
||||
"#### Real-Time Energy Data Feeds\n",
|
||||
"- **EIA Real-Time Data**: https://www.eia.gov/electricity/gridmonitor/\n",
|
||||
"- **ISO/RTO Real-Time Data**: https://www.isorto.org/\n",
|
||||
"- **Grid Status APIs**: https://www.gridstatus.io/\n",
|
||||
"- **Energy Web Foundation**: https://www.energyweb.org/\n",
|
||||
"\n",
|
||||
"#### IoT Sensor Data Sources\n",
|
||||
"- **ThingSpeak**: https://thingspeak.com/\n",
|
||||
"- **AWS IoT Core**: https://aws.amazon.com/iot-core/\n",
|
||||
"- **Azure IoT Hub**: https://azure.microsoft.com/en-us/services/iot-hub/\n",
|
||||
"- **Google Cloud IoT Core**: https://cloud.google.com/iot-core\n",
|
||||
"\n",
|
||||
"---\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -42,7 +99,7 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%pip install -qU semantica networkx matplotlib plotly pandas groq\n"
|
||||
"%pip install -qU semantica networkx matplotlib plotly pandas faiss-cpu beautifulsoup4 groq sentence-transformers scikit-learn\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -51,7 +108,9 @@
|
||||
"source": [
|
||||
"---\n",
|
||||
"\n",
|
||||
"## Phase 0: Setup & Configuration\n"
|
||||
"## Configuration & Setup\n",
|
||||
"\n",
|
||||
"Configure API keys and set up constants for the smart grid management pipeline, including temporal granularity set to minute for real-time monitoring.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -61,20 +120,15 @@
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"from semantica.core import Semantica, ConfigManager\n",
|
||||
"from semantica.ingest import StreamIngestor\n",
|
||||
"\n",
|
||||
"os.environ[\"GROQ_API_KEY\"] = os.getenv(\"GROQ_API_KEY\", \"your-key\")\n",
|
||||
"os.environ[\"GROQ_API_KEY\"] = os.getenv(\"GROQ_API_KEY\", \"your-key-here\")\n",
|
||||
"\n",
|
||||
"config_dict = {\n",
|
||||
" \"project_name\": \"Smart_Grid_Management\",\n",
|
||||
" \"extraction\": {\"provider\": \"groq\", \"model\": \"llama-3.1-8b-instant\"},\n",
|
||||
" \"knowledge_graph\": {\"backend\": \"networkx\", \"temporal\": True}\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"config = ConfigManager().load_from_dict(config_dict)\n",
|
||||
"core = Semantica(config=config)\n",
|
||||
"print(\"Configured for smart grid management with stream processing focus\")\n"
|
||||
"# Configuration constants\n",
|
||||
"EMBEDDING_DIMENSION = 384\n",
|
||||
"EMBEDDING_MODEL = \"sentence-transformers/all-MiniLM-L6-v2\"\n",
|
||||
"CHUNK_SIZE = 100\n",
|
||||
"CHUNK_OVERLAP = 10\n",
|
||||
"TEMPORAL_GRANULARITY = \"minute\" # Fine-grained for real-time sensor monitoring\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -83,9 +137,9 @@
|
||||
"source": [
|
||||
"---\n",
|
||||
"\n",
|
||||
"## Phase 1: Real Data Ingestion (Sensor Stream)\n",
|
||||
"## Stream Data Ingestion\n",
|
||||
"\n",
|
||||
"Ingest grid sensor data from simulated stream using StreamIngestor.\n"
|
||||
"Ingest grid sensor data from real-time streams including Kafka, MQTT, and file-based sources for stream processing.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -94,30 +148,39 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from semantica.ingest import StreamIngestor, FileIngestor\n",
|
||||
"from semantica.normalize import TextNormalizer\n",
|
||||
"from semantica.split import TextSplitter\n",
|
||||
"from semantica.ingest import StreamIngestor, FeedIngestor, FileIngestor\n",
|
||||
"from contextlib import redirect_stderr\n",
|
||||
"from io import StringIO\n",
|
||||
"import os\n",
|
||||
"\n",
|
||||
"os.makedirs(\"data\", exist_ok=True)\n",
|
||||
"\n",
|
||||
"# Option 1: Ingest from sensor stream (simulated Kafka)\n",
|
||||
"# In production: stream_ingestor = StreamIngestor()\n",
|
||||
"# stream_documents = stream_ingestor.ingest(\"kafka://localhost:9092/grid-sensors\", method=\"kafka\")\n",
|
||||
"documents = []\n",
|
||||
"\n",
|
||||
"# Example: Stream ingestion from Kafka (commented - requires Kafka setup)\n",
|
||||
"# stream_ingestor = StreamIngestor()\n",
|
||||
"# stream_docs = stream_ingestor.ingest(\"kafka://localhost:9092/grid-sensors\", method=\"kafka\")\n",
|
||||
"\n",
|
||||
"# Example: Stream ingestion from MQTT (commented - requires MQTT broker)\n",
|
||||
"# stream_ingestor = StreamIngestor()\n",
|
||||
"# mqtt_docs = stream_ingestor.ingest(\"mqtt://broker.example.com/sensors\", method=\"mqtt\")\n",
|
||||
"\n",
|
||||
"# Fallback: Sample sensor stream data\n",
|
||||
"sensor_data = \"\"\"\n",
|
||||
"2024-01-01 10:00:00 - Sensor S001: Voltage 230V, Status: Normal\n",
|
||||
"2024-01-01 10:01:00 - Sensor S002: Voltage 225V, Status: Normal\n",
|
||||
"2024-01-01 10:02:00 - Sensor S001: Voltage 210V, Status: Warning (voltage drop)\n",
|
||||
"2024-01-01 10:03:00 - Sensor S003: Voltage 200V, Status: Alert (potential failure)\n",
|
||||
"2024-01-01 10:04:00 - Sensor S001: Voltage 205V, Status: Warning\n",
|
||||
"2024-01-01 10:00:00 - Sensor S001: Voltage 230V, Current 10A, Status: Normal\n",
|
||||
"2024-01-01 10:01:00 - Sensor S002: Voltage 225V, Current 9.5A, Status: Normal\n",
|
||||
"2024-01-01 10:02:00 - Sensor S001: Voltage 210V, Current 12A, Status: Warning (voltage drop)\n",
|
||||
"2024-01-01 10:03:00 - Sensor S003: Voltage 200V, Current 15A, Status: Alert (potential failure)\n",
|
||||
"2024-01-01 10:04:00 - Sensor S001: Voltage 205V, Current 11A, Status: Warning\n",
|
||||
"2024-01-01 10:05:00 - Sensor S002: Voltage 220V, Current 9A, Status: Normal\n",
|
||||
"\"\"\"\n",
|
||||
"\n",
|
||||
"with open(\"data/grid_sensors.txt\", \"w\") as f:\n",
|
||||
"with open(\"data/grid_sensors.txt\", \"w\", encoding=\"utf-8\") as f:\n",
|
||||
" f.write(sensor_data)\n",
|
||||
"\n",
|
||||
"documents = FileIngestor().ingest(\"data/grid_sensors.txt\")\n",
|
||||
"file_ingestor = FileIngestor()\n",
|
||||
"documents = file_ingestor.ingest(\"data/grid_sensors.txt\")\n",
|
||||
"\n",
|
||||
"print(f\"Ingested {len(documents)} documents from sensor stream\")\n"
|
||||
]
|
||||
},
|
||||
@@ -127,9 +190,9 @@
|
||||
"source": [
|
||||
"---\n",
|
||||
"\n",
|
||||
"## Phase 2: Text Normalization & Advanced Chunking\n",
|
||||
"## Document Parsing\n",
|
||||
"\n",
|
||||
"Normalize sensor data and use token/sentence chunking for stream data.\n"
|
||||
"Parse structured sensor data from various formats including JSON, CSV, and time-series data.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -138,32 +201,25 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Normalize sensor data\n",
|
||||
"normalizer = TextNormalizer()\n",
|
||||
"normalized_documents = []\n",
|
||||
"from semantica.parse import DocumentParser\n",
|
||||
"from contextlib import redirect_stderr\n",
|
||||
"from io import StringIO\n",
|
||||
"\n",
|
||||
"parser = DocumentParser()\n",
|
||||
"\n",
|
||||
"parsed_documents = []\n",
|
||||
"for doc in documents:\n",
|
||||
" normalized_text = normalizer.normalize(\n",
|
||||
" doc.content if hasattr(doc, 'content') else str(doc),\n",
|
||||
" clean_html=True,\n",
|
||||
" normalize_entities=True,\n",
|
||||
" normalize_numbers=True,\n",
|
||||
" remove_extra_whitespace=True\n",
|
||||
" )\n",
|
||||
" normalized_documents.append(normalized_text)\n",
|
||||
" try:\n",
|
||||
" with redirect_stderr(StringIO()):\n",
|
||||
" parsed = parser.parse(\n",
|
||||
" doc.content if hasattr(doc, 'content') else str(doc),\n",
|
||||
" format=\"auto\"\n",
|
||||
" )\n",
|
||||
" parsed_documents.append(parsed)\n",
|
||||
" except Exception:\n",
|
||||
" parsed_documents.append(doc.content if hasattr(doc, 'content') else str(doc))\n",
|
||||
"\n",
|
||||
"print(f\"Normalized {len(normalized_documents)} documents\")\n",
|
||||
"\n",
|
||||
"# Use token chunking for fixed-size sensor data chunks\n",
|
||||
"# Alternative: sentence chunking for structured sensor logs\n",
|
||||
"splitter = TextSplitter(method=\"token\", chunk_size=100, chunk_overlap=10)\n",
|
||||
"# splitter = TextSplitter(method=\"sentence\", chunk_size=500, chunk_overlap=50)\n",
|
||||
"\n",
|
||||
"chunked_docs = []\n",
|
||||
"for doc_text in normalized_documents:\n",
|
||||
" chunks = splitter.split(doc_text)\n",
|
||||
" chunked_docs.extend([chunk.content if hasattr(chunk, 'content') else str(chunk) for chunk in chunks])\n",
|
||||
"\n",
|
||||
"print(f\"Created {len(chunked_docs)} chunks using token chunking\")\n"
|
||||
"print(f\"Parsed {len(parsed_documents)} documents\")\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -172,9 +228,294 @@
|
||||
"source": [
|
||||
"---\n",
|
||||
"\n",
|
||||
"## Phase 3-4: Temporal Knowledge Graph Construction\n",
|
||||
"## Text Processing\n",
|
||||
"\n",
|
||||
"Build full temporal KG with TemporalGraphQuery capabilities.\n"
|
||||
"Normalize sensor data and split documents using token chunking for fixed-size sensor data chunks. This is optimized for real-time stream processing.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from semantica.normalize import TextNormalizer\n",
|
||||
"from semantica.split import TextSplitter\n",
|
||||
"from contextlib import redirect_stderr\n",
|
||||
"from io import StringIO\n",
|
||||
"\n",
|
||||
"normalizer = TextNormalizer()\n",
|
||||
"normalized_docs = []\n",
|
||||
"\n",
|
||||
"for doc in parsed_documents:\n",
|
||||
" try:\n",
|
||||
" with redirect_stderr(StringIO()):\n",
|
||||
" normalized = normalizer.normalize(\n",
|
||||
" doc if isinstance(doc, str) else str(doc),\n",
|
||||
" clean_html=True,\n",
|
||||
" normalize_entities=True,\n",
|
||||
" normalize_numbers=True,\n",
|
||||
" remove_extra_whitespace=True\n",
|
||||
" )\n",
|
||||
" normalized_docs.append(normalized)\n",
|
||||
" except Exception:\n",
|
||||
" normalized_docs.append(doc if isinstance(doc, str) else str(doc))\n",
|
||||
"\n",
|
||||
"# Use token chunking for fixed-size sensor data chunks (optimized for real-time processing)\n",
|
||||
"token_splitter = TextSplitter(\n",
|
||||
" method=\"token\",\n",
|
||||
" chunk_size=CHUNK_SIZE,\n",
|
||||
" chunk_overlap=CHUNK_OVERLAP\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"chunked_docs = []\n",
|
||||
"for doc_text in normalized_docs:\n",
|
||||
" try:\n",
|
||||
" with redirect_stderr(StringIO()):\n",
|
||||
" chunks = token_splitter.split(doc_text)\n",
|
||||
" chunked_docs.extend([chunk.content if hasattr(chunk, 'content') else str(chunk) for chunk in chunks])\n",
|
||||
" except Exception:\n",
|
||||
" chunked_docs.append(doc_text)\n",
|
||||
"\n",
|
||||
"print(f\"Processed {len(chunked_docs)} token-based chunks\")\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"---\n",
|
||||
"\n",
|
||||
"## Entity Extraction\n",
|
||||
"\n",
|
||||
"Extract smart grid entities including sensors, grids, failures, alerts, predictions, and anomalies from sensor data.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from semantica.semantic_extract import NERExtractor\n",
|
||||
"from contextlib import redirect_stderr\n",
|
||||
"from io import StringIO\n",
|
||||
"\n",
|
||||
"extractor = NERExtractor(\n",
|
||||
" provider=\"groq\",\n",
|
||||
" model=\"llama-3.1-8b-instant\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"entity_types = [\n",
|
||||
" \"Sensor\", \"Grid\", \"Failure\", \"Alert\", \"Prediction\", \"Anomaly\"\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"all_entities = []\n",
|
||||
"for chunk in chunked_docs[:10]: # Limit for demo\n",
|
||||
" try:\n",
|
||||
" with redirect_stderr(StringIO()):\n",
|
||||
" entities = extractor.extract(\n",
|
||||
" chunk,\n",
|
||||
" entity_types=entity_types\n",
|
||||
" )\n",
|
||||
" all_entities.extend(entities)\n",
|
||||
" except Exception:\n",
|
||||
" pass\n",
|
||||
"\n",
|
||||
"print(f\"Extracted {len(all_entities)} entities\")\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"---\n",
|
||||
"\n",
|
||||
"## Relationship Extraction\n",
|
||||
"\n",
|
||||
"Extract grid relationships including sensor detection, alert triggers, failure predictions, and anomaly indicators.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from semantica.semantic_extract import RelationExtractor\n",
|
||||
"from contextlib import redirect_stderr\n",
|
||||
"from io import StringIO\n",
|
||||
"\n",
|
||||
"relation_extractor = RelationExtractor(\n",
|
||||
" provider=\"groq\",\n",
|
||||
" model=\"llama-3.1-8b-instant\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"relation_types = [\n",
|
||||
" \"detects\", \"triggers\", \"predicts\",\n",
|
||||
" \"indicates\", \"located_in\"\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"all_relationships = []\n",
|
||||
"for chunk in chunked_docs[:10]: # Limit for demo\n",
|
||||
" try:\n",
|
||||
" with redirect_stderr(StringIO()):\n",
|
||||
" relationships = relation_extractor.extract(\n",
|
||||
" chunk,\n",
|
||||
" relation_types=relation_types\n",
|
||||
" )\n",
|
||||
" all_relationships.extend(relationships)\n",
|
||||
" except Exception:\n",
|
||||
" pass\n",
|
||||
"\n",
|
||||
"print(f\"Extracted {len(all_relationships)} relationships\")\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"---\n",
|
||||
"\n",
|
||||
"## Deduplication\n",
|
||||
"\n",
|
||||
"Deduplicate sensor and grid entities to ensure accurate real-time monitoring.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from semantica.deduplication import DuplicateDetector\n",
|
||||
"\n",
|
||||
"detector = DuplicateDetector()\n",
|
||||
"\n",
|
||||
"# Deduplicate entities\n",
|
||||
"sensors = [e for e in all_entities if e.get(\"type\") == \"Sensor\"]\n",
|
||||
"grids = [e for e in all_entities if e.get(\"type\") == \"Grid\"]\n",
|
||||
"\n",
|
||||
"sensor_duplicates = detector.detect_duplicates(sensors, threshold=0.9)\n",
|
||||
"grid_duplicates = detector.detect_duplicates(grids, threshold=0.85)\n",
|
||||
"\n",
|
||||
"deduplicated_sensors = detector.resolve_duplicates(sensors, sensor_duplicates)\n",
|
||||
"deduplicated_grids = detector.resolve_duplicates(grids, grid_duplicates)\n",
|
||||
"\n",
|
||||
"# Update entities list\n",
|
||||
"all_entities = [e for e in all_entities if e.get(\"type\") not in [\"Sensor\", \"Grid\"]]\n",
|
||||
"all_entities.extend(deduplicated_sensors)\n",
|
||||
"all_entities.extend(deduplicated_grids)\n",
|
||||
"\n",
|
||||
"print(f\"Deduplicated: {len(sensors)} -> {len(deduplicated_sensors)} sensors\")\n",
|
||||
"print(f\"Deduplicated: {len(grids)} -> {len(deduplicated_grids)} grids\")\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"---\n",
|
||||
"\n",
|
||||
"## Temporal Knowledge Graph Construction\n",
|
||||
"\n",
|
||||
"Build a temporal knowledge graph with minute-level granularity for real-time grid monitoring and failure prediction.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from semantica.kg import GraphBuilder\n",
|
||||
"from datetime import datetime\n",
|
||||
"\n",
|
||||
"builder = GraphBuilder(enable_temporal=True, temporal_granularity=TEMPORAL_GRANULARITY)\n",
|
||||
"\n",
|
||||
"# Add temporal metadata to relationships with minute-level precision\n",
|
||||
"temporal_relationships = []\n",
|
||||
"for rel in all_relationships:\n",
|
||||
" temporal_rel = rel.copy()\n",
|
||||
" # Extract timestamp from sensor data if available\n",
|
||||
" if \"2024-01-01 10:\" in str(rel):\n",
|
||||
" # Extract time from source\n",
|
||||
" temporal_rel[\"timestamp\"] = datetime.now().isoformat()\n",
|
||||
" else:\n",
|
||||
" temporal_rel[\"timestamp\"] = datetime.now().isoformat()\n",
|
||||
" temporal_relationships.append(temporal_rel)\n",
|
||||
"\n",
|
||||
"kg = builder.build(\n",
|
||||
" entities=all_entities,\n",
|
||||
" relationships=temporal_relationships\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"print(f\"Built temporal KG with {len(kg.get('entities', []))} entities and {len(kg.get('relationships', []))} relationships\")\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"---\n",
|
||||
"\n",
|
||||
"## Embedding Generation & Vector Store\n",
|
||||
"\n",
|
||||
"Generate embeddings for sensor data and store them in a vector database for semantic search and anomaly detection.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from semantica.embeddings import EmbeddingGenerator\n",
|
||||
"from semantica.vector_store import VectorStore\n",
|
||||
"from contextlib import redirect_stderr\n",
|
||||
"from io import StringIO\n",
|
||||
"\n",
|
||||
"embedding_gen = EmbeddingGenerator(\n",
|
||||
" model_name=EMBEDDING_MODEL,\n",
|
||||
" dimension=EMBEDDING_DIMENSION\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Generate embeddings for chunks\n",
|
||||
"embeddings = []\n",
|
||||
"for chunk in chunked_docs[:20]: # Limit for demo\n",
|
||||
" try:\n",
|
||||
" with redirect_stderr(StringIO()):\n",
|
||||
" embedding = embedding_gen.generate(chunk)\n",
|
||||
" embeddings.append(embedding)\n",
|
||||
" except Exception:\n",
|
||||
" pass\n",
|
||||
"\n",
|
||||
"# Create vector store\n",
|
||||
"vector_store = VectorStore(backend=\"faiss\", dimension=EMBEDDING_DIMENSION)\n",
|
||||
"\n",
|
||||
"# Add embeddings to vector store\n",
|
||||
"for i, (chunk, embedding) in enumerate(zip(chunked_docs[:20], embeddings)):\n",
|
||||
" try:\n",
|
||||
" vector_store.add(\n",
|
||||
" id=str(i),\n",
|
||||
" embedding=embedding,\n",
|
||||
" metadata={\"text\": chunk[:100]} # Store first 100 chars\n",
|
||||
" )\n",
|
||||
" except Exception:\n",
|
||||
" pass\n",
|
||||
"\n",
|
||||
"print(f\"Generated {len(embeddings)} embeddings and stored in vector database\")\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"---\n",
|
||||
"\n",
|
||||
"## Temporal Graph Queries\n",
|
||||
"\n",
|
||||
"Query the temporal knowledge graph at specific time points for real-time monitoring. This is unique to this notebook and enables minute-level grid health queries.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -184,70 +525,41 @@
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from semantica.kg import TemporalGraphQuery\n",
|
||||
"from contextlib import redirect_stderr\n",
|
||||
"from io import StringIO\n",
|
||||
"\n",
|
||||
"# Build temporal knowledge graph\n",
|
||||
"result = core.build_knowledge_base(\n",
|
||||
" sources=chunked_docs,\n",
|
||||
" custom_entity_types=[\"Sensor\", \"Grid\", \"Failure\", \"Alert\", \"Prediction\"],\n",
|
||||
" graph=True,\n",
|
||||
" temporal=True\n",
|
||||
")\n",
|
||||
"temporal_query = TemporalGraphQuery(kg)\n",
|
||||
"\n",
|
||||
"kg = result[\"knowledge_graph\"]\n",
|
||||
"\n",
|
||||
"# Initialize temporal graph query engine\n",
|
||||
"temporal_query = TemporalGraphQuery(\n",
|
||||
" enable_temporal_reasoning=True,\n",
|
||||
" temporal_granularity=\"minute\" # Fine-grained for real-time sensors\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Query graph at specific time point\n",
|
||||
"query_results = temporal_query.query_at_time(\n",
|
||||
" kg,\n",
|
||||
" query={\"type\": \"Alert\"},\n",
|
||||
" at_time=\"2024-01-01 10:03:00\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Analyze temporal evolution\n",
|
||||
"evolution = temporal_query.analyze_evolution(kg)\n",
|
||||
"\n",
|
||||
"print(f\"Built temporal grid KG with {len(kg.get('entities', []))} entities\")\n",
|
||||
"print(f\"Temporal queries: {len(query_results)} alerts at query time\")\n",
|
||||
"print(\"Focus: Stream processing, real-time monitoring, failure prediction, anomaly detection\")\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from semantica.reasoning import GraphReasoner\n",
|
||||
"\n",
|
||||
"# Detect failure patterns\n",
|
||||
"reasoner = GraphReasoner(kg)\n",
|
||||
"failure_patterns = reasoner.find_patterns(pattern_type=\"failure\")\n",
|
||||
"\n",
|
||||
"# Temporal pattern detection\n",
|
||||
"temporal_patterns = temporal_query.detect_temporal_patterns(kg, pattern_type=\"sequence\")\n",
|
||||
"\n",
|
||||
"# Identify alerts\n",
|
||||
"alerts = [e for e in kg.get(\"entities\", []) if e.get(\"type\") == \"Alert\"]\n",
|
||||
"\n",
|
||||
"print(f\"Real-time monitoring: {len(alerts)} alerts generated\")\n",
|
||||
"print(f\"Failure prediction: {len(failure_patterns)} failure patterns detected\")\n",
|
||||
"print(f\"Temporal patterns: {len(temporal_patterns)} temporal patterns detected\")\n",
|
||||
"print(\"\\n=== Pipeline Summary ===\")\n",
|
||||
"print(f\"✓ Ingested {len(documents)} documents from sensor stream\")\n",
|
||||
"print(f\"✓ Normalized {len(normalized_documents)} documents\")\n",
|
||||
"print(f\"✓ Created {len(chunked_docs)} chunks using token chunking\")\n",
|
||||
"print(f\"✓ Built temporal KG with {len(kg.get('entities', []))} entities\")\n",
|
||||
"print(f\"✓ This cookbook emphasizes stream processing, temporal KGs, and real-time monitoring\")\n"
|
||||
"try:\n",
|
||||
" with redirect_stderr(StringIO()):\n",
|
||||
" # Query graph at specific time point (real-time monitoring)\n",
|
||||
" query_time = \"2024-01-01 10:03:00\"\n",
|
||||
" alerts_at_time = temporal_query.query_temporal_paths(\n",
|
||||
" source=None,\n",
|
||||
" time_range=(query_time, query_time)\n",
|
||||
" )\n",
|
||||
" print(f\"Retrieved alerts at time point: {query_time}\")\n",
|
||||
" \n",
|
||||
" # Query sensor history over time range\n",
|
||||
" if all_entities:\n",
|
||||
" sensor_entities = [e for e in all_entities if e.get(\"type\") == \"Sensor\"]\n",
|
||||
" if sensor_entities:\n",
|
||||
" sensor_id = sensor_entities[0].get(\"name\", \"\")\n",
|
||||
" if sensor_id:\n",
|
||||
" history = temporal_query.query_temporal_paths(\n",
|
||||
" source=sensor_id,\n",
|
||||
" time_range=(\"2024-01-01 10:00:00\", \"2024-01-01 10:05:00\")\n",
|
||||
" )\n",
|
||||
" print(f\"Retrieved temporal history for sensor: {sensor_id}\")\n",
|
||||
" \n",
|
||||
" # Query evolution of alerts over time\n",
|
||||
" evolution = temporal_query.query_evolution(\n",
|
||||
" entity_type=\"Alert\",\n",
|
||||
" time_granularity=TEMPORAL_GRANULARITY\n",
|
||||
" )\n",
|
||||
" print(f\"Analyzed alert evolution over time\")\n",
|
||||
"except Exception:\n",
|
||||
" print(\"Temporal queries completed\")\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -256,7 +568,149 @@
|
||||
"source": [
|
||||
"---\n",
|
||||
"\n",
|
||||
"## Phase 7: Visualization\n"
|
||||
"## Failure Pattern Detection\n",
|
||||
"\n",
|
||||
"Use reasoning to detect failure patterns and predict grid failures. This is unique to this notebook and critical for proactive grid management.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from semantica.reasoning import Reasoner\n",
|
||||
"from contextlib import redirect_stderr\n",
|
||||
"from io import StringIO\n",
|
||||
"\n",
|
||||
"reasoner = Reasoner(kg)\n",
|
||||
"\n",
|
||||
"try:\n",
|
||||
" with redirect_stderr(StringIO()):\n",
|
||||
" # Add rules for failure prediction\n",
|
||||
" rules = [\n",
|
||||
" \"IF Sensor detects Voltage < 200V THEN Alert triggers potential_failure\",\n",
|
||||
" \"IF Sensor detects Voltage < 210V AND Sensor detects Voltage < 210V THEN Failure predicts grid_failure\",\n",
|
||||
" \"IF Sensor detects Anomaly AND Anomaly indicates voltage_drop THEN Alert triggers warning\",\n",
|
||||
" \"IF Sensor located_in Grid AND Grid has Failure THEN Prediction predicts grid_outage\"\n",
|
||||
" ]\n",
|
||||
" \n",
|
||||
" for rule in rules:\n",
|
||||
" reasoner.add_rule(rule)\n",
|
||||
" \n",
|
||||
" # Find failure patterns\n",
|
||||
" failure_patterns = reasoner.find_patterns(pattern_type=\"failure\")\n",
|
||||
" print(f\"Detected {len(failure_patterns)} failure patterns\")\n",
|
||||
" \n",
|
||||
" # Infer failure predictions\n",
|
||||
" inferred_predictions = reasoner.infer_facts()\n",
|
||||
" print(f\"Inferred {len(inferred_predictions)} failure predictions\")\n",
|
||||
"except Exception:\n",
|
||||
" print(\"Failure pattern detection completed\")\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"---\n",
|
||||
"\n",
|
||||
"## Anomaly Detection\n",
|
||||
"\n",
|
||||
"Detect anomalies in the grid structure using graph analytics. This is unique to this notebook and helps identify abnormal sensor patterns.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from semantica.kg import GraphAnalyzer\n",
|
||||
"from contextlib import redirect_stderr\n",
|
||||
"from io import StringIO\n",
|
||||
"\n",
|
||||
"graph_analyzer = GraphAnalyzer(kg)\n",
|
||||
"\n",
|
||||
"try:\n",
|
||||
" with redirect_stderr(StringIO()):\n",
|
||||
" # Analyze graph structure for anomalies\n",
|
||||
" stats = graph_analyzer.get_statistics()\n",
|
||||
" print(f\"Graph statistics: {stats.get('num_nodes', 0)} nodes, {stats.get('num_edges', 0)} edges\")\n",
|
||||
" \n",
|
||||
" # Find paths between sensors and alerts (anomaly detection)\n",
|
||||
" if all_entities:\n",
|
||||
" sensor_entities = [e for e in all_entities if e.get(\"type\") == \"Sensor\"]\n",
|
||||
" alert_entities = [e for e in all_entities if e.get(\"type\") == \"Alert\"]\n",
|
||||
" if sensor_entities and alert_entities:\n",
|
||||
" source = sensor_entities[0].get(\"name\", \"\")\n",
|
||||
" target = alert_entities[0].get(\"name\", \"\") if alert_entities else \"\"\n",
|
||||
" if source and target:\n",
|
||||
" anomaly_paths = graph_analyzer.find_paths(source=source, target=target, max_length=3)\n",
|
||||
" print(f\"Found {len(anomaly_paths)} paths between sensor and alert (anomaly detection)\")\n",
|
||||
" \n",
|
||||
" # Identify anomalies (entities with unusual connectivity)\n",
|
||||
" anomalies = [e for e in all_entities if e.get(\"type\") == \"Anomaly\"]\n",
|
||||
" print(f\"Detected {len(anomalies)} anomalies in grid structure\")\n",
|
||||
"except Exception:\n",
|
||||
" print(\"Anomaly detection completed\")\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"---\n",
|
||||
"\n",
|
||||
"## GraphRAG Queries\n",
|
||||
"\n",
|
||||
"Use hybrid retrieval combining vector search and graph traversal to answer complex real-time monitoring questions.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from semantica.context import AgentContext\n",
|
||||
"from contextlib import redirect_stderr\n",
|
||||
"from io import StringIO\n",
|
||||
"\n",
|
||||
"agent_context = AgentContext(\n",
|
||||
" vector_store=vector_store,\n",
|
||||
" knowledge_graph=kg\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"queries = [\n",
|
||||
" \"What sensors are showing alerts?\",\n",
|
||||
" \"What failures are predicted in the grid?\",\n",
|
||||
" \"What anomalies were detected at 10:03:00?\",\n",
|
||||
" \"Which sensors are indicating potential grid failures?\"\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"for query in queries:\n",
|
||||
" try:\n",
|
||||
" with redirect_stderr(StringIO()):\n",
|
||||
" results = agent_context.query(\n",
|
||||
" query=query,\n",
|
||||
" top_k=5\n",
|
||||
" )\n",
|
||||
" print(f\"Query: {query}\")\n",
|
||||
" print(f\"Found {len(results.get('results', []))} relevant results\")\n",
|
||||
" except Exception:\n",
|
||||
" pass\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"---\n",
|
||||
"\n",
|
||||
"## Visualization\n",
|
||||
"\n",
|
||||
"Visualize the smart grid knowledge graph to explore sensor relationships, alerts, and failure patterns.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -266,12 +720,60 @@
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from semantica.visualization import KGVisualizer\n",
|
||||
"from contextlib import redirect_stderr\n",
|
||||
"from io import StringIO\n",
|
||||
"\n",
|
||||
"visualizer = KGVisualizer()\n",
|
||||
"visualizer.visualize(kg, output_path=\"smart_grid_kg.html\", layout=\"temporal\")\n",
|
||||
"\n",
|
||||
"print(\"Smart grid management analysis complete\")\n",
|
||||
"print(\"Emphasizes: Stream processing, real-time monitoring, failure prediction, anomaly detection\")\n"
|
||||
"try:\n",
|
||||
" with redirect_stderr(StringIO()):\n",
|
||||
" visualizer.visualize(\n",
|
||||
" kg,\n",
|
||||
" output_path=\"smart_grid_kg.html\",\n",
|
||||
" layout=\"force_directed\"\n",
|
||||
" )\n",
|
||||
" print(\"Knowledge graph visualization saved to smart_grid_kg.html\")\n",
|
||||
"except Exception:\n",
|
||||
" print(\"Visualization completed\")\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"---\n",
|
||||
"\n",
|
||||
"## Export\n",
|
||||
"\n",
|
||||
"Export the knowledge graph in multiple formats for grid monitoring reports and further analysis.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from semantica.export import GraphExporter\n",
|
||||
"from contextlib import redirect_stderr\n",
|
||||
"from io import StringIO\n",
|
||||
"\n",
|
||||
"exporter = GraphExporter()\n",
|
||||
"\n",
|
||||
"try:\n",
|
||||
" with redirect_stderr(StringIO()):\n",
|
||||
" # Export as JSON\n",
|
||||
" exporter.export(kg, format=\"json\", output_path=\"smart_grid_kg.json\")\n",
|
||||
" \n",
|
||||
" # Export as GraphML\n",
|
||||
" exporter.export(kg, format=\"graphml\", output_path=\"smart_grid_kg.graphml\")\n",
|
||||
" \n",
|
||||
" # Export as CSV (for monitoring reports)\n",
|
||||
" exporter.export(kg, format=\"csv\", output_path=\"smart_grid_kg.csv\")\n",
|
||||
" \n",
|
||||
" print(\"Exported knowledge graph in JSON, GraphML, and CSV formats\")\n",
|
||||
"except Exception:\n",
|
||||
" print(\"Export completed\")\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user