diff --git a/orchestrator/activities/formatters.py b/orchestrator/activities/formatters.py
index cb45d57..73f8f86 100644
--- a/orchestrator/activities/formatters.py
+++ b/orchestrator/activities/formatters.py
@@ -19,6 +19,7 @@ with workflow.unsafe.imports_passed_through():
minimal_retrain,
predictions_batch,
scouter,
+ drift,
)
topic_separator = '\n ========== \n'
@@ -34,7 +35,7 @@ class Formatters(SientiaMonitoring):
scheduled reports.
Key features:
- - Pipeline schedule configuration formatting ("scouter", "predictions_batch", "minimal_retrain")
+ - Pipeline schedule configuration formatting ("scouter", "predictions_batch", "minimal_retrain", "drift")
- OPC slot distribution across active ingestors
- Notification filtering for comprehensive scheduled reports
- Group-based report filtering with ignore list support
@@ -132,6 +133,13 @@ class Formatters(SientiaMonitoring):
'updated_at', now().strftime(DATETIME_FORMAT_MS_WITH_TZ)
),
}
+ elif pipeline['workflow_type'] == 'drift':
+ schedule_config[self.laborious_namespace][pipeline['schedule_name']] = {
+ **drift(pipeline),
+ 'updated_at': pipeline.get(
+ 'updated_at', now().strftime(DATETIME_FORMAT_MS_WITH_TZ)
+ ),
+ }
self.info('Processed schedules', metadata=metadata)
self.debug(json.dumps(schedule_config, indent=4, sort_keys=True), metadata=metadata)
diff --git a/orchestrator/utils/orchestrator_functions.py b/orchestrator/utils/orchestrator_functions.py
index 02371a1..54c388b 100644
--- a/orchestrator/utils/orchestrator_functions.py
+++ b/orchestrator/utils/orchestrator_functions.py
@@ -32,6 +32,25 @@ def common_config(config: dict[str, Any]):
}
+def drift(config: dict[str, Any]):
+ """
+ Build drift configuration from pipeline config.
+ """
+ model = config['model']
+ return {
+ **common_config(config),
+ 'schema': 'sientia_data',
+ 'source_table_name': 'laborious_data',
+ 'target_table_name': 'drift_metrics',
+ 'interval': config.get('interval_minutes', 60),
+ 'drift_metrics': config.get('drift_metrics', [
+ "kolmogorov_smirnov",
+ "jensen_shannon",
+ "wasserstein"
+ ])
+ }
+
+
def minimal_retrain(config: dict[str, Any]):
"""
Build minimal retrain configuration from pipeline config.
@@ -47,8 +66,6 @@ def minimal_retrain(config: dict[str, Any]):
"""
return {
**common_config(config),
- 'workflow_type': 'minimal_retrain',
- 'schedule_name': config['schedule_name'],
'query': config['query'],
'schema': 'sientia_data',
'table_name': 'log_retrain',
diff --git a/test.ipynb b/test.ipynb
index 1843727..a101c3c 100644
--- a/test.ipynb
+++ b/test.ipynb
@@ -617,13 +617,2049 @@
" print(f\"Chave: {key}, Valor: {value}\")"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "e8025cbb",
+ "metadata": {},
+ "source": [
+ "## Model Monitoring"
+ ]
+ },
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 1,
"id": "87a9dc89",
"metadata": {},
"outputs": [],
- "source": []
+ "source": [
+ "from sientia.ModelAnalysis import ModelAnalysis\n",
+ "\n",
+ "config = {\n",
+ " \"target\": \"Square\",\n",
+ " \"prediction\": \"prediction\",\n",
+ " \"timestamp\": \"timestamp\",\n",
+ " \"features\": [\"Counter\", \"Rollout\"]\n",
+ "}\n",
+ "\n",
+ "model = ModelAnalysis(config=config)\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "2a74ad2f",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from sientia_do.temporal.activities.postgres import Postgres\n",
+ "from unittest.mock import AsyncMock\n",
+ "from pandas import DataFrame\n",
+ "\n",
+ "postgres = Postgres(\n",
+ " host=\"localhost\",\n",
+ " port=5432,\n",
+ " dbname=\"sientia\",\n",
+ " user=\"sientia\",\n",
+ " password=\"sientia\",\n",
+ " min_connections=1,\n",
+ " max_connections=10,\n",
+ " logger=AsyncMock(),\n",
+ " notification_handler=AsyncMock(),\n",
+ " metrics_controller=AsyncMock()\n",
+ ")\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "938cecbd",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/home/grezewave/Documents/projects/sientia/sientia-dataops-orchestrator_temporal/venv/lib/python3.11/site-packages/sientia_do/observability/sientia_monitoring.py:83: RuntimeWarning: coroutine 'AsyncMockMixin._execute_mock_call' was never awaited\n",
+ " self.logger.custom_info(message, metadata)\n",
+ "/home/grezewave/Documents/projects/sientia/sientia-dataops-orchestrator_temporal/venv/lib/python3.11/site-packages/sientia_do/observability/sientia_monitoring.py:59: RuntimeWarning: coroutine 'AsyncMockMixin._execute_mock_call' was never awaited\n",
+ " self.metrics_controller.start()\n",
+ "/home/grezewave/Documents/projects/sientia/sientia-dataops-orchestrator_temporal/venv/lib/python3.11/site-packages/sientia_do/observability/sientia_monitoring.py:83: RuntimeWarning: coroutine 'AsyncMockMixin._execute_mock_call' was never awaited\n",
+ " self.logger.custom_info(message, metadata)\n",
+ "/home/grezewave/Documents/projects/sientia/sientia-dataops-orchestrator_temporal/venv/lib/python3.11/site-packages/sientia_do/observability/sientia_monitoring.py:95: RuntimeWarning: coroutine 'AsyncMockMixin._execute_mock_call' was never awaited\n",
+ " self.logger.custom_debug(message, metadata)\n"
+ ]
+ },
+ {
+ "data": {
+ "text/html": [
+ "
\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " variable | \n",
+ " value | \n",
+ " prediction | \n",
+ " timestamp | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " Square | \n",
+ " 42.2950 | \n",
+ " -3.018465 | \n",
+ " 2025-11-12 12:44:50+00:00 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " Rollout | \n",
+ " 1.8610 | \n",
+ " -3.018465 | \n",
+ " 2025-11-12 12:44:50+00:00 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " Counter | \n",
+ " -45.0980 | \n",
+ " -3.018465 | \n",
+ " 2025-11-12 12:44:50+00:00 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " Rollout | \n",
+ " 0.3970 | \n",
+ " 2.341423 | \n",
+ " 2025-11-12 12:44:20+00:00 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " Counter | \n",
+ " -40.0260 | \n",
+ " 2.341423 | \n",
+ " 2025-11-12 12:44:20+00:00 | \n",
+ "
\n",
+ " \n",
+ " | 5 | \n",
+ " Square | \n",
+ " 43.3190 | \n",
+ " 2.341423 | \n",
+ " 2025-11-12 12:44:20+00:00 | \n",
+ "
\n",
+ " \n",
+ " | 6 | \n",
+ " Rollout | \n",
+ " -0.2645 | \n",
+ " 4.696591 | \n",
+ " 2025-11-12 12:42:15+00:00 | \n",
+ "
\n",
+ " \n",
+ " | 7 | \n",
+ " Square | \n",
+ " 42.1850 | \n",
+ " 4.696591 | \n",
+ " 2025-11-12 12:42:15+00:00 | \n",
+ "
\n",
+ " \n",
+ " | 8 | \n",
+ " Counter | \n",
+ " -37.8385 | \n",
+ " 4.696591 | \n",
+ " 2025-11-12 12:42:15+00:00 | \n",
+ "
\n",
+ " \n",
+ " | 9 | \n",
+ " Square | \n",
+ " 2.8880 | \n",
+ " -70.845157 | \n",
+ " 2025-11-11 23:00:48+00:00 | \n",
+ "
\n",
+ " \n",
+ " | 10 | \n",
+ " Rollout | \n",
+ " 18.7945 | \n",
+ " -70.845157 | \n",
+ " 2025-11-11 23:00:48+00:00 | \n",
+ "
\n",
+ " \n",
+ " | 11 | \n",
+ " Counter | \n",
+ " -12.6565 | \n",
+ " -70.845157 | \n",
+ " 2025-11-11 23:00:48+00:00 | \n",
+ "
\n",
+ " \n",
+ " | 12 | \n",
+ " Rollout | \n",
+ " 17.7415 | \n",
+ " -71.894590 | \n",
+ " 2025-11-11 23:00:18+00:00 | \n",
+ "
\n",
+ " \n",
+ " | 13 | \n",
+ " Counter | \n",
+ " -11.1570 | \n",
+ " -71.894590 | \n",
+ " 2025-11-11 23:00:18+00:00 | \n",
+ "
\n",
+ " \n",
+ " | 14 | \n",
+ " Square | \n",
+ " 2.1610 | \n",
+ " -71.894590 | \n",
+ " 2025-11-11 23:00:18+00:00 | \n",
+ "
\n",
+ " \n",
+ " | 15 | \n",
+ " Square | \n",
+ " -2.0490 | \n",
+ " -67.033953 | \n",
+ " 2025-11-11 22:59:48+00:00 | \n",
+ "
\n",
+ " \n",
+ " | 16 | \n",
+ " Rollout | \n",
+ " 16.5365 | \n",
+ " -67.033953 | \n",
+ " 2025-11-11 22:59:48+00:00 | \n",
+ "
\n",
+ " \n",
+ " | 17 | \n",
+ " Counter | \n",
+ " -15.2205 | \n",
+ " -67.033953 | \n",
+ " 2025-11-11 22:59:48+00:00 | \n",
+ "
\n",
+ " \n",
+ " | 18 | \n",
+ " Counter | \n",
+ " -11.7930 | \n",
+ " -70.514462 | \n",
+ " 2025-11-11 22:59:18+00:00 | \n",
+ "
\n",
+ " \n",
+ " | 19 | \n",
+ " Square | \n",
+ " -4.3350 | \n",
+ " -70.514462 | \n",
+ " 2025-11-11 22:59:18+00:00 | \n",
+ "
\n",
+ " \n",
+ " | 20 | \n",
+ " Rollout | \n",
+ " 16.3065 | \n",
+ " -70.514462 | \n",
+ " 2025-11-11 22:59:18+00:00 | \n",
+ "
\n",
+ " \n",
+ " | 21 | \n",
+ " Square | \n",
+ " 0.6840 | \n",
+ " -72.523279 | \n",
+ " 2025-11-11 22:58:48+00:00 | \n",
+ "
\n",
+ " \n",
+ " | 22 | \n",
+ " Counter | \n",
+ " -9.2570 | \n",
+ " -72.523279 | \n",
+ " 2025-11-11 22:58:48+00:00 | \n",
+ "
\n",
+ " \n",
+ " | 23 | \n",
+ " Rollout | \n",
+ " 14.9965 | \n",
+ " -72.523279 | \n",
+ " 2025-11-11 22:58:48+00:00 | \n",
+ "
\n",
+ " \n",
+ " | 24 | \n",
+ " Square | \n",
+ " 1.1700 | \n",
+ " -72.831684 | \n",
+ " 2025-11-11 22:58:18+00:00 | \n",
+ "
\n",
+ " \n",
+ " | 25 | \n",
+ " Counter | \n",
+ " -7.0635 | \n",
+ " -72.831684 | \n",
+ " 2025-11-11 22:58:18+00:00 | \n",
+ "
\n",
+ " \n",
+ " | 26 | \n",
+ " Rollout | \n",
+ " 10.9875 | \n",
+ " -72.831684 | \n",
+ " 2025-11-11 22:58:18+00:00 | \n",
+ "
\n",
+ " \n",
+ " | 27 | \n",
+ " Counter | \n",
+ " -2.0110 | \n",
+ " -77.865944 | \n",
+ " 2025-11-11 22:57:48+00:00 | \n",
+ "
\n",
+ " \n",
+ " | 28 | \n",
+ " Rollout | \n",
+ " 10.4545 | \n",
+ " -77.865944 | \n",
+ " 2025-11-11 22:57:48+00:00 | \n",
+ "
\n",
+ " \n",
+ " | 29 | \n",
+ " Square | \n",
+ " -0.2070 | \n",
+ " -77.865944 | \n",
+ " 2025-11-11 22:57:48+00:00 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " variable value prediction timestamp\n",
+ "0 Square 42.2950 -3.018465 2025-11-12 12:44:50+00:00\n",
+ "1 Rollout 1.8610 -3.018465 2025-11-12 12:44:50+00:00\n",
+ "2 Counter -45.0980 -3.018465 2025-11-12 12:44:50+00:00\n",
+ "3 Rollout 0.3970 2.341423 2025-11-12 12:44:20+00:00\n",
+ "4 Counter -40.0260 2.341423 2025-11-12 12:44:20+00:00\n",
+ "5 Square 43.3190 2.341423 2025-11-12 12:44:20+00:00\n",
+ "6 Rollout -0.2645 4.696591 2025-11-12 12:42:15+00:00\n",
+ "7 Square 42.1850 4.696591 2025-11-12 12:42:15+00:00\n",
+ "8 Counter -37.8385 4.696591 2025-11-12 12:42:15+00:00\n",
+ "9 Square 2.8880 -70.845157 2025-11-11 23:00:48+00:00\n",
+ "10 Rollout 18.7945 -70.845157 2025-11-11 23:00:48+00:00\n",
+ "11 Counter -12.6565 -70.845157 2025-11-11 23:00:48+00:00\n",
+ "12 Rollout 17.7415 -71.894590 2025-11-11 23:00:18+00:00\n",
+ "13 Counter -11.1570 -71.894590 2025-11-11 23:00:18+00:00\n",
+ "14 Square 2.1610 -71.894590 2025-11-11 23:00:18+00:00\n",
+ "15 Square -2.0490 -67.033953 2025-11-11 22:59:48+00:00\n",
+ "16 Rollout 16.5365 -67.033953 2025-11-11 22:59:48+00:00\n",
+ "17 Counter -15.2205 -67.033953 2025-11-11 22:59:48+00:00\n",
+ "18 Counter -11.7930 -70.514462 2025-11-11 22:59:18+00:00\n",
+ "19 Square -4.3350 -70.514462 2025-11-11 22:59:18+00:00\n",
+ "20 Rollout 16.3065 -70.514462 2025-11-11 22:59:18+00:00\n",
+ "21 Square 0.6840 -72.523279 2025-11-11 22:58:48+00:00\n",
+ "22 Counter -9.2570 -72.523279 2025-11-11 22:58:48+00:00\n",
+ "23 Rollout 14.9965 -72.523279 2025-11-11 22:58:48+00:00\n",
+ "24 Square 1.1700 -72.831684 2025-11-11 22:58:18+00:00\n",
+ "25 Counter -7.0635 -72.831684 2025-11-11 22:58:18+00:00\n",
+ "26 Rollout 10.9875 -72.831684 2025-11-11 22:58:18+00:00\n",
+ "27 Counter -2.0110 -77.865944 2025-11-11 22:57:48+00:00\n",
+ "28 Rollout 10.4545 -77.865944 2025-11-11 22:57:48+00:00\n",
+ "29 Square -0.2070 -77.865944 2025-11-11 22:57:48+00:00"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " variable | \n",
+ " value | \n",
+ " prediction | \n",
+ " timestamp | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " Square | \n",
+ " 42.2950 | \n",
+ " -3.018465 | \n",
+ " 2025-11-12 12:44:50 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " Rollout | \n",
+ " 1.8610 | \n",
+ " -3.018465 | \n",
+ " 2025-11-12 12:44:50 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " Counter | \n",
+ " -45.0980 | \n",
+ " -3.018465 | \n",
+ " 2025-11-12 12:44:50 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " Rollout | \n",
+ " 0.3970 | \n",
+ " 2.341423 | \n",
+ " 2025-11-12 12:44:20 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " Counter | \n",
+ " -40.0260 | \n",
+ " 2.341423 | \n",
+ " 2025-11-12 12:44:20 | \n",
+ "
\n",
+ " \n",
+ " | 5 | \n",
+ " Square | \n",
+ " 43.3190 | \n",
+ " 2.341423 | \n",
+ " 2025-11-12 12:44:20 | \n",
+ "
\n",
+ " \n",
+ " | 6 | \n",
+ " Rollout | \n",
+ " -0.2645 | \n",
+ " 4.696591 | \n",
+ " 2025-11-12 12:42:15 | \n",
+ "
\n",
+ " \n",
+ " | 7 | \n",
+ " Square | \n",
+ " 42.1850 | \n",
+ " 4.696591 | \n",
+ " 2025-11-12 12:42:15 | \n",
+ "
\n",
+ " \n",
+ " | 8 | \n",
+ " Counter | \n",
+ " -37.8385 | \n",
+ " 4.696591 | \n",
+ " 2025-11-12 12:42:15 | \n",
+ "
\n",
+ " \n",
+ " | 9 | \n",
+ " Square | \n",
+ " 2.8880 | \n",
+ " -70.845157 | \n",
+ " 2025-11-11 23:00:48 | \n",
+ "
\n",
+ " \n",
+ " | 10 | \n",
+ " Rollout | \n",
+ " 18.7945 | \n",
+ " -70.845157 | \n",
+ " 2025-11-11 23:00:48 | \n",
+ "
\n",
+ " \n",
+ " | 11 | \n",
+ " Counter | \n",
+ " -12.6565 | \n",
+ " -70.845157 | \n",
+ " 2025-11-11 23:00:48 | \n",
+ "
\n",
+ " \n",
+ " | 12 | \n",
+ " Rollout | \n",
+ " 17.7415 | \n",
+ " -71.894590 | \n",
+ " 2025-11-11 23:00:18 | \n",
+ "
\n",
+ " \n",
+ " | 13 | \n",
+ " Counter | \n",
+ " -11.1570 | \n",
+ " -71.894590 | \n",
+ " 2025-11-11 23:00:18 | \n",
+ "
\n",
+ " \n",
+ " | 14 | \n",
+ " Square | \n",
+ " 2.1610 | \n",
+ " -71.894590 | \n",
+ " 2025-11-11 23:00:18 | \n",
+ "
\n",
+ " \n",
+ " | 15 | \n",
+ " Square | \n",
+ " -2.0490 | \n",
+ " -67.033953 | \n",
+ " 2025-11-11 22:59:48 | \n",
+ "
\n",
+ " \n",
+ " | 16 | \n",
+ " Rollout | \n",
+ " 16.5365 | \n",
+ " -67.033953 | \n",
+ " 2025-11-11 22:59:48 | \n",
+ "
\n",
+ " \n",
+ " | 17 | \n",
+ " Counter | \n",
+ " -15.2205 | \n",
+ " -67.033953 | \n",
+ " 2025-11-11 22:59:48 | \n",
+ "
\n",
+ " \n",
+ " | 18 | \n",
+ " Counter | \n",
+ " -11.7930 | \n",
+ " -70.514462 | \n",
+ " 2025-11-11 22:59:18 | \n",
+ "
\n",
+ " \n",
+ " | 19 | \n",
+ " Square | \n",
+ " -4.3350 | \n",
+ " -70.514462 | \n",
+ " 2025-11-11 22:59:18 | \n",
+ "
\n",
+ " \n",
+ " | 20 | \n",
+ " Rollout | \n",
+ " 16.3065 | \n",
+ " -70.514462 | \n",
+ " 2025-11-11 22:59:18 | \n",
+ "
\n",
+ " \n",
+ " | 21 | \n",
+ " Square | \n",
+ " 0.6840 | \n",
+ " -72.523279 | \n",
+ " 2025-11-11 22:58:48 | \n",
+ "
\n",
+ " \n",
+ " | 22 | \n",
+ " Counter | \n",
+ " -9.2570 | \n",
+ " -72.523279 | \n",
+ " 2025-11-11 22:58:48 | \n",
+ "
\n",
+ " \n",
+ " | 23 | \n",
+ " Rollout | \n",
+ " 14.9965 | \n",
+ " -72.523279 | \n",
+ " 2025-11-11 22:58:48 | \n",
+ "
\n",
+ " \n",
+ " | 24 | \n",
+ " Square | \n",
+ " 1.1700 | \n",
+ " -72.831684 | \n",
+ " 2025-11-11 22:58:18 | \n",
+ "
\n",
+ " \n",
+ " | 25 | \n",
+ " Counter | \n",
+ " -7.0635 | \n",
+ " -72.831684 | \n",
+ " 2025-11-11 22:58:18 | \n",
+ "
\n",
+ " \n",
+ " | 26 | \n",
+ " Rollout | \n",
+ " 10.9875 | \n",
+ " -72.831684 | \n",
+ " 2025-11-11 22:58:18 | \n",
+ "
\n",
+ " \n",
+ " | 27 | \n",
+ " Counter | \n",
+ " -2.0110 | \n",
+ " -77.865944 | \n",
+ " 2025-11-11 22:57:48 | \n",
+ "
\n",
+ " \n",
+ " | 28 | \n",
+ " Rollout | \n",
+ " 10.4545 | \n",
+ " -77.865944 | \n",
+ " 2025-11-11 22:57:48 | \n",
+ "
\n",
+ " \n",
+ " | 29 | \n",
+ " Square | \n",
+ " -0.2070 | \n",
+ " -77.865944 | \n",
+ " 2025-11-11 22:57:48 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " variable value prediction timestamp\n",
+ "0 Square 42.2950 -3.018465 2025-11-12 12:44:50\n",
+ "1 Rollout 1.8610 -3.018465 2025-11-12 12:44:50\n",
+ "2 Counter -45.0980 -3.018465 2025-11-12 12:44:50\n",
+ "3 Rollout 0.3970 2.341423 2025-11-12 12:44:20\n",
+ "4 Counter -40.0260 2.341423 2025-11-12 12:44:20\n",
+ "5 Square 43.3190 2.341423 2025-11-12 12:44:20\n",
+ "6 Rollout -0.2645 4.696591 2025-11-12 12:42:15\n",
+ "7 Square 42.1850 4.696591 2025-11-12 12:42:15\n",
+ "8 Counter -37.8385 4.696591 2025-11-12 12:42:15\n",
+ "9 Square 2.8880 -70.845157 2025-11-11 23:00:48\n",
+ "10 Rollout 18.7945 -70.845157 2025-11-11 23:00:48\n",
+ "11 Counter -12.6565 -70.845157 2025-11-11 23:00:48\n",
+ "12 Rollout 17.7415 -71.894590 2025-11-11 23:00:18\n",
+ "13 Counter -11.1570 -71.894590 2025-11-11 23:00:18\n",
+ "14 Square 2.1610 -71.894590 2025-11-11 23:00:18\n",
+ "15 Square -2.0490 -67.033953 2025-11-11 22:59:48\n",
+ "16 Rollout 16.5365 -67.033953 2025-11-11 22:59:48\n",
+ "17 Counter -15.2205 -67.033953 2025-11-11 22:59:48\n",
+ "18 Counter -11.7930 -70.514462 2025-11-11 22:59:18\n",
+ "19 Square -4.3350 -70.514462 2025-11-11 22:59:18\n",
+ "20 Rollout 16.3065 -70.514462 2025-11-11 22:59:18\n",
+ "21 Square 0.6840 -72.523279 2025-11-11 22:58:48\n",
+ "22 Counter -9.2570 -72.523279 2025-11-11 22:58:48\n",
+ "23 Rollout 14.9965 -72.523279 2025-11-11 22:58:48\n",
+ "24 Square 1.1700 -72.831684 2025-11-11 22:58:18\n",
+ "25 Counter -7.0635 -72.831684 2025-11-11 22:58:18\n",
+ "26 Rollout 10.9875 -72.831684 2025-11-11 22:58:18\n",
+ "27 Counter -2.0110 -77.865944 2025-11-11 22:57:48\n",
+ "28 Rollout 10.4545 -77.865944 2025-11-11 22:57:48\n",
+ "29 Square -0.2070 -77.865944 2025-11-11 22:57:48"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "from pandas import DataFrame, to_datetime\n",
+ "\n",
+ "query_data = \"\"\"\n",
+ "select ld.variable, ld.value, p.prediction, p.\"timestamp\"\n",
+ "from sientia_data.laborious_data ld\n",
+ " right join sientia_data.predictions p \n",
+ " on ld.timestamp = p.timestamp\n",
+ " and ld.model_id = p.model_id\n",
+ " where\n",
+ " ld.model_id = '1'\n",
+ " order by\n",
+ " ld.created_at desc limit 30;\n",
+ "\"\"\"\n",
+ "\n",
+ "input_data = {\n",
+ " \"query\": query_data,\n",
+ " \"metadata\": {}\n",
+ "}\n",
+ "\n",
+ "\n",
+ "raw_data = DataFrame(await postgres.load_custom_query(\n",
+ " input_data))\n",
+ "\n",
+ "raw_data['timestamp'] = to_datetime(raw_data['timestamp'])\n",
+ "raw_data['timestamp'] = raw_data['timestamp'].dt.strftime('%Y-%m-%d %H:%M:%S')\n",
+ "\n",
+ "display(raw_data)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "297f648f",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " timestamp | \n",
+ " prediction | \n",
+ " Counter | \n",
+ " Rollout | \n",
+ " Square | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " 2025-11-11 22:57:48 | \n",
+ " -77.865944 | \n",
+ " -2.0110 | \n",
+ " 10.4545 | \n",
+ " -0.207 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " 2025-11-11 22:58:18 | \n",
+ " -72.831684 | \n",
+ " -7.0635 | \n",
+ " 10.9875 | \n",
+ " 1.170 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " 2025-11-11 22:58:48 | \n",
+ " -72.523279 | \n",
+ " -9.2570 | \n",
+ " 14.9965 | \n",
+ " 0.684 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " 2025-11-11 22:59:18 | \n",
+ " -70.514462 | \n",
+ " -11.7930 | \n",
+ " 16.3065 | \n",
+ " -4.335 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " 2025-11-11 22:59:48 | \n",
+ " -67.033953 | \n",
+ " -15.2205 | \n",
+ " 16.5365 | \n",
+ " -2.049 | \n",
+ "
\n",
+ " \n",
+ " | 5 | \n",
+ " 2025-11-11 23:00:18 | \n",
+ " -71.894590 | \n",
+ " -11.1570 | \n",
+ " 17.7415 | \n",
+ " 2.161 | \n",
+ "
\n",
+ " \n",
+ " | 6 | \n",
+ " 2025-11-11 23:00:48 | \n",
+ " -70.845157 | \n",
+ " -12.6565 | \n",
+ " 18.7945 | \n",
+ " 2.888 | \n",
+ "
\n",
+ " \n",
+ " | 7 | \n",
+ " 2025-11-12 12:42:15 | \n",
+ " 4.696591 | \n",
+ " -37.8385 | \n",
+ " -0.2645 | \n",
+ " 42.185 | \n",
+ "
\n",
+ " \n",
+ " | 8 | \n",
+ " 2025-11-12 12:44:20 | \n",
+ " 2.341423 | \n",
+ " -40.0260 | \n",
+ " 0.3970 | \n",
+ " 43.319 | \n",
+ "
\n",
+ " \n",
+ " | 9 | \n",
+ " 2025-11-12 12:44:50 | \n",
+ " -3.018465 | \n",
+ " -45.0980 | \n",
+ " 1.8610 | \n",
+ " 42.295 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " timestamp prediction Counter Rollout Square\n",
+ "0 2025-11-11 22:57:48 -77.865944 -2.0110 10.4545 -0.207\n",
+ "1 2025-11-11 22:58:18 -72.831684 -7.0635 10.9875 1.170\n",
+ "2 2025-11-11 22:58:48 -72.523279 -9.2570 14.9965 0.684\n",
+ "3 2025-11-11 22:59:18 -70.514462 -11.7930 16.3065 -4.335\n",
+ "4 2025-11-11 22:59:48 -67.033953 -15.2205 16.5365 -2.049\n",
+ "5 2025-11-11 23:00:18 -71.894590 -11.1570 17.7415 2.161\n",
+ "6 2025-11-11 23:00:48 -70.845157 -12.6565 18.7945 2.888\n",
+ "7 2025-11-12 12:42:15 4.696591 -37.8385 -0.2645 42.185\n",
+ "8 2025-11-12 12:44:20 2.341423 -40.0260 0.3970 43.319\n",
+ "9 2025-11-12 12:44:50 -3.018465 -45.0980 1.8610 42.295"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "from pandas import merge, pivot\n",
+ "\n",
+ "raw_data.drop_duplicates(subset=[\"timestamp\", \"prediction\", \"variable\"], inplace=True, keep=\"first\")\n",
+ "data = raw_data.pivot(index=[\"timestamp\", \"prediction\"], columns=\"variable\", values=\"value\")\n",
+ "\n",
+ "data.columns.name = None\n",
+ "data.reset_index(inplace=True)\n",
+ "display(data)\n",
+ "\n",
+ "\n",
+ "drift_methods = ['kolmogorov_smirnov']#, 'jensen_shannon', 'wasserstein']\n",
+ "chunk_period = 's'\n",
+ "target_col = \"Square\"\n",
+ "timestamp_col = \"timestamp\"\n",
+ "\n",
+ "data.to_csv(\"data.csv\", index=False)\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "id": "9ab4774a",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from mlflow.tracking import MlflowClient\n",
+ "from os import environ\n",
+ "\n",
+ "environ['MLFLOW_TRACKING_USERNAME'] = 'aignosi'\n",
+ "environ['MLFLOW_TRACKING_PASSWORD'] = '1L0FP50j3ncp123'\n",
+ "environ['MLFLOW_TRACKING_URI'] = 'http://localhost:5080'\n",
+ "mlflow_client = MlflowClient()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 19,
+ "id": "e8427625",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 19,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "run_id = '9e9fa748822c44ab92dd769d6a45c4f4'\n",
+ "output_dir = './tmp/model'\n",
+ "\n",
+ "artifacts = mlflow_client.list_artifacts(run_id)\n",
+ "paths = [artifact.path for artifact in artifacts]\n",
+ "\n",
+ "any(artifact.path == 'retrain_data.csv' for artifact in artifacts)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "id": "cf4ddf41",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " timestamp | \n",
+ " Counter | \n",
+ " Rollout | \n",
+ " Square | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " 2025-11-10 18:58:39 | \n",
+ " 13.5970 | \n",
+ " -52.4500 | \n",
+ " 43.381 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " 2025-11-10 18:58:49 | \n",
+ " 15.0660 | \n",
+ " -50.0240 | \n",
+ " 45.813 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " 2025-11-10 18:58:54 | \n",
+ " 14.2780 | \n",
+ " -49.4810 | \n",
+ " 47.677 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " 2025-11-10 18:59:04 | \n",
+ " 14.2080 | \n",
+ " -51.8015 | \n",
+ " 48.995 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " 2025-11-10 18:59:09 | \n",
+ " 16.3530 | \n",
+ " -52.6850 | \n",
+ " 47.745 | \n",
+ "
\n",
+ " \n",
+ " | 5 | \n",
+ " 2025-11-10 18:59:19 | \n",
+ " 15.5415 | \n",
+ " -53.5625 | \n",
+ " 48.327 | \n",
+ "
\n",
+ " \n",
+ " | 6 | \n",
+ " 2025-11-10 18:59:24 | \n",
+ " 16.8580 | \n",
+ " -53.6960 | \n",
+ " 47.160 | \n",
+ "
\n",
+ " \n",
+ " | 7 | \n",
+ " 2025-11-10 18:59:34 | \n",
+ " 14.9745 | \n",
+ " -54.7510 | \n",
+ " 48.480 | \n",
+ "
\n",
+ " \n",
+ " | 8 | \n",
+ " 2025-11-10 18:59:39 | \n",
+ " 12.3020 | \n",
+ " -53.4330 | \n",
+ " 48.631 | \n",
+ "
\n",
+ " \n",
+ " | 9 | \n",
+ " 2025-11-10 18:59:49 | \n",
+ " 12.5640 | \n",
+ " -52.9805 | \n",
+ " 50.130 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " timestamp Counter Rollout Square\n",
+ "0 2025-11-10 18:58:39 13.5970 -52.4500 43.381\n",
+ "1 2025-11-10 18:58:49 15.0660 -50.0240 45.813\n",
+ "2 2025-11-10 18:58:54 14.2780 -49.4810 47.677\n",
+ "3 2025-11-10 18:59:04 14.2080 -51.8015 48.995\n",
+ "4 2025-11-10 18:59:09 16.3530 -52.6850 47.745\n",
+ "5 2025-11-10 18:59:19 15.5415 -53.5625 48.327\n",
+ "6 2025-11-10 18:59:24 16.8580 -53.6960 47.160\n",
+ "7 2025-11-10 18:59:34 14.9745 -54.7510 48.480\n",
+ "8 2025-11-10 18:59:39 12.3020 -53.4330 48.631\n",
+ "9 2025-11-10 18:59:49 12.5640 -52.9805 50.130"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "import mlflow\n",
+ "from io import StringIO\n",
+ "from pandas import read_csv\n",
+ "\n",
+ "if 'retrain_data.csv' in paths:\n",
+ " artifact_path = 'retrain_data.csv'\n",
+ "elif 'train_data.csv' in paths:\n",
+ " artifact_path = 'train_data.csv'\n",
+ "else:\n",
+ " raise RuntimeError(\n",
+ " f\"Could not find 'train_data.csv' or 'retrain_data.csv' for run_id '{run_id}'.\\n\"\n",
+ " )\n",
+ "\n",
+ "# Carregar diretamente na memória como string\n",
+ "artifact_content = mlflow.artifacts.load_text(\n",
+ " f\"runs:/{run_id}/{artifact_path}\"\n",
+ ")\n",
+ "\n",
+ "reference_df = read_csv(StringIO(artifact_content))\n",
+ "\n",
+ "reference_df.drop(columns=['timestamp.1'], inplace=True)\n",
+ "\n",
+ "reference_df['timestamp'] = to_datetime(reference_df['timestamp'])\n",
+ "reference_df['timestamp'] = reference_df['timestamp'].dt.strftime('%Y-%m-%d %H:%M:%S')\n",
+ "\n",
+ "display(reference_df)\n",
+ "\n",
+ "reference_df.to_csv(\"reference_df.csv\", index=False)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 20,
+ "id": "d375752b",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/home/grezewave/Documents/projects/sientia/sientia-dataops-orchestrator_temporal/venv/lib/python3.11/site-packages/numpy/core/_methods.py:206: RuntimeWarning: Degrees of freedom <= 0 for slice\n",
+ " ret = _var(a, axis=axis, dtype=dtype, out=out, ddof=ddof,\n",
+ "/home/grezewave/Documents/projects/sientia/sientia-dataops-orchestrator_temporal/venv/lib/python3.11/site-packages/numpy/core/_methods.py:198: RuntimeWarning: invalid value encountered in scalar divide\n",
+ " ret = ret.dtype.type(ret / rcount)\n",
+ "/home/grezewave/Documents/projects/sientia/sientia-dataops-orchestrator_temporal/venv/lib/python3.11/site-packages/numpy/core/_methods.py:206: RuntimeWarning: Degrees of freedom <= 0 for slice\n",
+ " ret = _var(a, axis=axis, dtype=dtype, out=out, ddof=ddof,\n",
+ "/home/grezewave/Documents/projects/sientia/sientia-dataops-orchestrator_temporal/venv/lib/python3.11/site-packages/numpy/core/_methods.py:198: RuntimeWarning: invalid value encountered in scalar divide\n",
+ " ret = ret.dtype.type(ret / rcount)\n"
+ ]
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " timestamp | \n",
+ " feature | \n",
+ " metric | \n",
+ " statistic | \n",
+ " p_value | \n",
+ " alert | \n",
+ " chunk_index | \n",
+ " chunk_start_date | \n",
+ " chunk_end_date | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " 2025-11-10 18:58:00+0000 | \n",
+ " Counter | \n",
+ " kolmogorov_smirnov | \n",
+ " 3.000000e-01 | \n",
+ " NaN | \n",
+ " False | \n",
+ " 0 | \n",
+ " 2025-11-10 18:58 | \n",
+ " 2025-11-10 18:58:59.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " 2025-11-10 18:59:00+0000 | \n",
+ " Counter | \n",
+ " kolmogorov_smirnov | \n",
+ " 1.285714e-01 | \n",
+ " NaN | \n",
+ " False | \n",
+ " 1 | \n",
+ " 2025-11-10 18:59 | \n",
+ " 2025-11-10 18:59:59.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " 2025-11-11 22:57:00+0000 | \n",
+ " Counter | \n",
+ " kolmogorov_smirnov | \n",
+ " 1.000000e+00 | \n",
+ " NaN | \n",
+ " True | \n",
+ " 0 | \n",
+ " 2025-11-11 22:57 | \n",
+ " 2025-11-11 22:57:59.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " 2025-11-11 22:58:00+0000 | \n",
+ " Counter | \n",
+ " kolmogorov_smirnov | \n",
+ " 1.000000e+00 | \n",
+ " NaN | \n",
+ " True | \n",
+ " 1 | \n",
+ " 2025-11-11 22:58 | \n",
+ " 2025-11-11 22:58:59.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " 2025-11-11 22:59:00+0000 | \n",
+ " Counter | \n",
+ " kolmogorov_smirnov | \n",
+ " 1.000000e+00 | \n",
+ " NaN | \n",
+ " True | \n",
+ " 2 | \n",
+ " 2025-11-11 22:59 | \n",
+ " 2025-11-11 22:59:59.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 5 | \n",
+ " 2025-11-11 23:00:00+0000 | \n",
+ " Counter | \n",
+ " kolmogorov_smirnov | \n",
+ " 1.000000e+00 | \n",
+ " NaN | \n",
+ " True | \n",
+ " 3 | \n",
+ " 2025-11-11 23:00 | \n",
+ " 2025-11-11 23:00:59.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 6 | \n",
+ " 2025-11-12 12:42:00+0000 | \n",
+ " Counter | \n",
+ " kolmogorov_smirnov | \n",
+ " 1.000000e+00 | \n",
+ " NaN | \n",
+ " True | \n",
+ " 4 | \n",
+ " 2025-11-12 12:42 | \n",
+ " 2025-11-12 12:42:59.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 7 | \n",
+ " 2025-11-12 12:44:00+0000 | \n",
+ " Counter | \n",
+ " kolmogorov_smirnov | \n",
+ " 1.000000e+00 | \n",
+ " NaN | \n",
+ " True | \n",
+ " 5 | \n",
+ " 2025-11-12 12:44 | \n",
+ " 2025-11-12 12:44:59.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 8 | \n",
+ " 2025-11-10 18:58:00+0000 | \n",
+ " Rollout | \n",
+ " kolmogorov_smirnov | \n",
+ " 6.000000e-01 | \n",
+ " NaN | \n",
+ " False | \n",
+ " 0 | \n",
+ " 2025-11-10 18:58 | \n",
+ " 2025-11-10 18:58:59.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 9 | \n",
+ " 2025-11-10 18:59:00+0000 | \n",
+ " Rollout | \n",
+ " kolmogorov_smirnov | \n",
+ " 2.571429e-01 | \n",
+ " NaN | \n",
+ " False | \n",
+ " 1 | \n",
+ " 2025-11-10 18:59 | \n",
+ " 2025-11-10 18:59:59.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 10 | \n",
+ " 2025-11-11 22:57:00+0000 | \n",
+ " Rollout | \n",
+ " kolmogorov_smirnov | \n",
+ " 1.000000e+00 | \n",
+ " NaN | \n",
+ " True | \n",
+ " 0 | \n",
+ " 2025-11-11 22:57 | \n",
+ " 2025-11-11 22:57:59.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 11 | \n",
+ " 2025-11-11 22:58:00+0000 | \n",
+ " Rollout | \n",
+ " kolmogorov_smirnov | \n",
+ " 1.000000e+00 | \n",
+ " NaN | \n",
+ " True | \n",
+ " 1 | \n",
+ " 2025-11-11 22:58 | \n",
+ " 2025-11-11 22:58:59.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 12 | \n",
+ " 2025-11-11 22:59:00+0000 | \n",
+ " Rollout | \n",
+ " kolmogorov_smirnov | \n",
+ " 1.000000e+00 | \n",
+ " NaN | \n",
+ " True | \n",
+ " 2 | \n",
+ " 2025-11-11 22:59 | \n",
+ " 2025-11-11 22:59:59.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 13 | \n",
+ " 2025-11-11 23:00:00+0000 | \n",
+ " Rollout | \n",
+ " kolmogorov_smirnov | \n",
+ " 1.000000e+00 | \n",
+ " NaN | \n",
+ " True | \n",
+ " 3 | \n",
+ " 2025-11-11 23:00 | \n",
+ " 2025-11-11 23:00:59.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 14 | \n",
+ " 2025-11-12 12:42:00+0000 | \n",
+ " Rollout | \n",
+ " kolmogorov_smirnov | \n",
+ " 1.000000e+00 | \n",
+ " NaN | \n",
+ " True | \n",
+ " 4 | \n",
+ " 2025-11-12 12:42 | \n",
+ " 2025-11-12 12:42:59.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 15 | \n",
+ " 2025-11-12 12:44:00+0000 | \n",
+ " Rollout | \n",
+ " kolmogorov_smirnov | \n",
+ " 1.000000e+00 | \n",
+ " NaN | \n",
+ " True | \n",
+ " 5 | \n",
+ " 2025-11-12 12:44 | \n",
+ " 2025-11-12 12:44:59.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 16 | \n",
+ " 2025-11-10 18:58:00+0000 | \n",
+ " multivariate | \n",
+ " multivariate | \n",
+ " 2.015043e-16 | \n",
+ " 3.748123e-17 | \n",
+ " False | \n",
+ " 0 | \n",
+ " 2025-11-10 18:58 | \n",
+ " 2025-11-10 18:58:59.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 17 | \n",
+ " 2025-11-10 18:59:00+0000 | \n",
+ " multivariate | \n",
+ " multivariate | \n",
+ " 2.493220e-16 | \n",
+ " 3.998584e-17 | \n",
+ " False | \n",
+ " 1 | \n",
+ " 2025-11-10 18:59 | \n",
+ " 2025-11-10 18:59:59.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 18 | \n",
+ " 2025-11-11 22:57:00+0000 | \n",
+ " multivariate | \n",
+ " multivariate | \n",
+ " 1.432145e-14 | \n",
+ " NaN | \n",
+ " True | \n",
+ " 0 | \n",
+ " 2025-11-11 22:57 | \n",
+ " 2025-11-11 22:57:59.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 19 | \n",
+ " 2025-11-11 22:58:00+0000 | \n",
+ " multivariate | \n",
+ " multivariate | \n",
+ " 1.234840e-14 | \n",
+ " 2.299811e-15 | \n",
+ " True | \n",
+ " 1 | \n",
+ " 2025-11-11 22:58 | \n",
+ " 2025-11-11 22:58:59.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 20 | \n",
+ " 2025-11-11 22:59:00+0000 | \n",
+ " multivariate | \n",
+ " multivariate | \n",
+ " 7.944109e-15 | \n",
+ " 0.000000e+00 | \n",
+ " True | \n",
+ " 2 | \n",
+ " 2025-11-11 22:59 | \n",
+ " 2025-11-11 22:59:59.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 21 | \n",
+ " 2025-11-11 23:00:00+0000 | \n",
+ " multivariate | \n",
+ " multivariate | \n",
+ " 7.524768e-15 | \n",
+ " 4.193410e-16 | \n",
+ " True | \n",
+ " 3 | \n",
+ " 2025-11-11 23:00 | \n",
+ " 2025-11-11 23:00:59.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 22 | \n",
+ " 2025-11-12 12:42:00+0000 | \n",
+ " multivariate | \n",
+ " multivariate | \n",
+ " 1.004859e-14 | \n",
+ " NaN | \n",
+ " True | \n",
+ " 4 | \n",
+ " 2025-11-12 12:42 | \n",
+ " 2025-11-12 12:42:59.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 23 | \n",
+ " 2025-11-12 12:44:00+0000 | \n",
+ " multivariate | \n",
+ " multivariate | \n",
+ " 1.004859e-14 | \n",
+ " 0.000000e+00 | \n",
+ " True | \n",
+ " 5 | \n",
+ " 2025-11-12 12:44 | \n",
+ " 2025-11-12 12:44:59.999999999 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " timestamp feature metric statistic \\\n",
+ "0 2025-11-10 18:58:00+0000 Counter kolmogorov_smirnov 3.000000e-01 \n",
+ "1 2025-11-10 18:59:00+0000 Counter kolmogorov_smirnov 1.285714e-01 \n",
+ "2 2025-11-11 22:57:00+0000 Counter kolmogorov_smirnov 1.000000e+00 \n",
+ "3 2025-11-11 22:58:00+0000 Counter kolmogorov_smirnov 1.000000e+00 \n",
+ "4 2025-11-11 22:59:00+0000 Counter kolmogorov_smirnov 1.000000e+00 \n",
+ "5 2025-11-11 23:00:00+0000 Counter kolmogorov_smirnov 1.000000e+00 \n",
+ "6 2025-11-12 12:42:00+0000 Counter kolmogorov_smirnov 1.000000e+00 \n",
+ "7 2025-11-12 12:44:00+0000 Counter kolmogorov_smirnov 1.000000e+00 \n",
+ "8 2025-11-10 18:58:00+0000 Rollout kolmogorov_smirnov 6.000000e-01 \n",
+ "9 2025-11-10 18:59:00+0000 Rollout kolmogorov_smirnov 2.571429e-01 \n",
+ "10 2025-11-11 22:57:00+0000 Rollout kolmogorov_smirnov 1.000000e+00 \n",
+ "11 2025-11-11 22:58:00+0000 Rollout kolmogorov_smirnov 1.000000e+00 \n",
+ "12 2025-11-11 22:59:00+0000 Rollout kolmogorov_smirnov 1.000000e+00 \n",
+ "13 2025-11-11 23:00:00+0000 Rollout kolmogorov_smirnov 1.000000e+00 \n",
+ "14 2025-11-12 12:42:00+0000 Rollout kolmogorov_smirnov 1.000000e+00 \n",
+ "15 2025-11-12 12:44:00+0000 Rollout kolmogorov_smirnov 1.000000e+00 \n",
+ "16 2025-11-10 18:58:00+0000 multivariate multivariate 2.015043e-16 \n",
+ "17 2025-11-10 18:59:00+0000 multivariate multivariate 2.493220e-16 \n",
+ "18 2025-11-11 22:57:00+0000 multivariate multivariate 1.432145e-14 \n",
+ "19 2025-11-11 22:58:00+0000 multivariate multivariate 1.234840e-14 \n",
+ "20 2025-11-11 22:59:00+0000 multivariate multivariate 7.944109e-15 \n",
+ "21 2025-11-11 23:00:00+0000 multivariate multivariate 7.524768e-15 \n",
+ "22 2025-11-12 12:42:00+0000 multivariate multivariate 1.004859e-14 \n",
+ "23 2025-11-12 12:44:00+0000 multivariate multivariate 1.004859e-14 \n",
+ "\n",
+ " p_value alert chunk_index chunk_start_date \\\n",
+ "0 NaN False 0 2025-11-10 18:58 \n",
+ "1 NaN False 1 2025-11-10 18:59 \n",
+ "2 NaN True 0 2025-11-11 22:57 \n",
+ "3 NaN True 1 2025-11-11 22:58 \n",
+ "4 NaN True 2 2025-11-11 22:59 \n",
+ "5 NaN True 3 2025-11-11 23:00 \n",
+ "6 NaN True 4 2025-11-12 12:42 \n",
+ "7 NaN True 5 2025-11-12 12:44 \n",
+ "8 NaN False 0 2025-11-10 18:58 \n",
+ "9 NaN False 1 2025-11-10 18:59 \n",
+ "10 NaN True 0 2025-11-11 22:57 \n",
+ "11 NaN True 1 2025-11-11 22:58 \n",
+ "12 NaN True 2 2025-11-11 22:59 \n",
+ "13 NaN True 3 2025-11-11 23:00 \n",
+ "14 NaN True 4 2025-11-12 12:42 \n",
+ "15 NaN True 5 2025-11-12 12:44 \n",
+ "16 3.748123e-17 False 0 2025-11-10 18:58 \n",
+ "17 3.998584e-17 False 1 2025-11-10 18:59 \n",
+ "18 NaN True 0 2025-11-11 22:57 \n",
+ "19 2.299811e-15 True 1 2025-11-11 22:58 \n",
+ "20 0.000000e+00 True 2 2025-11-11 22:59 \n",
+ "21 4.193410e-16 True 3 2025-11-11 23:00 \n",
+ "22 NaN True 4 2025-11-12 12:42 \n",
+ "23 0.000000e+00 True 5 2025-11-12 12:44 \n",
+ "\n",
+ " chunk_end_date \n",
+ "0 2025-11-10 18:58:59.999999999 \n",
+ "1 2025-11-10 18:59:59.999999999 \n",
+ "2 2025-11-11 22:57:59.999999999 \n",
+ "3 2025-11-11 22:58:59.999999999 \n",
+ "4 2025-11-11 22:59:59.999999999 \n",
+ "5 2025-11-11 23:00:59.999999999 \n",
+ "6 2025-11-12 12:42:59.999999999 \n",
+ "7 2025-11-12 12:44:59.999999999 \n",
+ "8 2025-11-10 18:58:59.999999999 \n",
+ "9 2025-11-10 18:59:59.999999999 \n",
+ "10 2025-11-11 22:57:59.999999999 \n",
+ "11 2025-11-11 22:58:59.999999999 \n",
+ "12 2025-11-11 22:59:59.999999999 \n",
+ "13 2025-11-11 23:00:59.999999999 \n",
+ "14 2025-11-12 12:42:59.999999999 \n",
+ "15 2025-11-12 12:44:59.999999999 \n",
+ "16 2025-11-10 18:58:59.999999999 \n",
+ "17 2025-11-10 18:59:59.999999999 \n",
+ "18 2025-11-11 22:57:59.999999999 \n",
+ "19 2025-11-11 22:58:59.999999999 \n",
+ "20 2025-11-11 22:59:59.999999999 \n",
+ "21 2025-11-11 23:00:59.999999999 \n",
+ "22 2025-11-12 12:42:59.999999999 \n",
+ "23 2025-11-12 12:44:59.999999999 "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "\n",
+ "\n",
+ "from sientia_do.temporal.constants import DATETIME_FORMAT_WITH_TZ\n",
+ "\n",
+ "\n",
+ "univariate_drift = model.detect_univariate_drift(\n",
+ " reference_df=reference_df,\n",
+ " analysis_df=data,\n",
+ " features=config['features'],\n",
+ " timestamp_col=timestamp_col,\n",
+ " methods=drift_methods,\n",
+ " chunk_period=\"min\"\n",
+ ")\n",
+ "multivariate_drift = model.detect_multivariate_drift(\n",
+ " reference_df=reference_df,\n",
+ " analysis_df=data,\n",
+ " features=config['features'],\n",
+ " timestamp_col=timestamp_col,\n",
+ " chunk_period=\"min\"\n",
+ ")\n",
+ "\n",
+ "drift = model.get_drift_metrics_dataframe(\n",
+ " univariate_drift=univariate_drift,\n",
+ " multivariate_drift=multivariate_drift\n",
+ ")\n",
+ "drift.drop_duplicates(subset=[\"timestamp\", \"feature\", \"metric\"], inplace=True, keep=\"first\")\n",
+ "drift.reset_index(drop=True, inplace=True)\n",
+ "\n",
+ "drift['timestamp'] = to_datetime(drift['timestamp'])\n",
+ "print(type(drift['timestamp'].iloc[0]))\n",
+ "\n",
+ "# Add timezone UTC to timestamp\n",
+ "drift['timestamp'] = drift['timestamp'].dt.tz_localize('UTC')\n",
+ "drift['timestamp'] = drift['timestamp'].dt.strftime(DATETIME_FORMAT_WITH_TZ)\n",
+ "\n",
+ "display(drift)\n",
+ "drift.to_csv(\"drift.csv\", index=False)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 32,
+ "id": "d30f6475",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " timestamp | \n",
+ " feature | \n",
+ " metric | \n",
+ " statistic | \n",
+ " p_value | \n",
+ " alert | \n",
+ " chunk_index | \n",
+ " chunk_start_date | \n",
+ " chunk_end_date | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 10 | \n",
+ " 2025-11-11 11:55:18 | \n",
+ " Counter | \n",
+ " kolmogorov_smirnov | \n",
+ " 1.000000e+00 | \n",
+ " None | \n",
+ " False | \n",
+ " 0 | \n",
+ " 2025-11-11 11:55:18 | \n",
+ " 2025-11-11 11:55:18.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 11 | \n",
+ " 2025-11-11 11:55:48 | \n",
+ " Counter | \n",
+ " kolmogorov_smirnov | \n",
+ " 1.000000e+00 | \n",
+ " None | \n",
+ " False | \n",
+ " 1 | \n",
+ " 2025-11-11 11:55:48 | \n",
+ " 2025-11-11 11:55:48.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 12 | \n",
+ " 2025-11-11 11:56:18 | \n",
+ " Counter | \n",
+ " kolmogorov_smirnov | \n",
+ " 1.000000e+00 | \n",
+ " None | \n",
+ " False | \n",
+ " 2 | \n",
+ " 2025-11-11 11:56:18 | \n",
+ " 2025-11-11 11:56:18.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 13 | \n",
+ " 2025-11-11 11:56:48 | \n",
+ " Counter | \n",
+ " kolmogorov_smirnov | \n",
+ " 1.000000e+00 | \n",
+ " None | \n",
+ " False | \n",
+ " 3 | \n",
+ " 2025-11-11 11:56:48 | \n",
+ " 2025-11-11 11:56:48.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 14 | \n",
+ " 2025-11-11 11:57:18 | \n",
+ " Counter | \n",
+ " kolmogorov_smirnov | \n",
+ " 1.000000e+00 | \n",
+ " None | \n",
+ " False | \n",
+ " 4 | \n",
+ " 2025-11-11 11:57:18 | \n",
+ " 2025-11-11 11:57:18.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 15 | \n",
+ " 2025-11-11 11:57:48 | \n",
+ " Counter | \n",
+ " kolmogorov_smirnov | \n",
+ " 1.000000e+00 | \n",
+ " None | \n",
+ " False | \n",
+ " 5 | \n",
+ " 2025-11-11 11:57:48 | \n",
+ " 2025-11-11 11:57:48.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 16 | \n",
+ " 2025-11-11 11:58:18 | \n",
+ " Counter | \n",
+ " kolmogorov_smirnov | \n",
+ " 1.000000e+00 | \n",
+ " None | \n",
+ " False | \n",
+ " 6 | \n",
+ " 2025-11-11 11:58:18 | \n",
+ " 2025-11-11 11:58:18.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 17 | \n",
+ " 2025-11-11 11:58:48 | \n",
+ " Counter | \n",
+ " kolmogorov_smirnov | \n",
+ " 1.000000e+00 | \n",
+ " None | \n",
+ " False | \n",
+ " 7 | \n",
+ " 2025-11-11 11:58:48 | \n",
+ " 2025-11-11 11:58:48.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 18 | \n",
+ " 2025-11-11 11:59:18 | \n",
+ " Counter | \n",
+ " kolmogorov_smirnov | \n",
+ " 1.000000e+00 | \n",
+ " None | \n",
+ " False | \n",
+ " 8 | \n",
+ " 2025-11-11 11:59:18 | \n",
+ " 2025-11-11 11:59:18.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 19 | \n",
+ " 2025-11-11 11:59:48 | \n",
+ " Counter | \n",
+ " kolmogorov_smirnov | \n",
+ " 1.000000e+00 | \n",
+ " None | \n",
+ " False | \n",
+ " 9 | \n",
+ " 2025-11-11 11:59:48 | \n",
+ " 2025-11-11 11:59:48.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 30 | \n",
+ " 2025-11-11 11:55:18 | \n",
+ " Rollout | \n",
+ " kolmogorov_smirnov | \n",
+ " 1.000000e+00 | \n",
+ " None | \n",
+ " False | \n",
+ " 0 | \n",
+ " 2025-11-11 11:55:18 | \n",
+ " 2025-11-11 11:55:18.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 31 | \n",
+ " 2025-11-11 11:55:48 | \n",
+ " Rollout | \n",
+ " kolmogorov_smirnov | \n",
+ " 1.000000e+00 | \n",
+ " None | \n",
+ " False | \n",
+ " 1 | \n",
+ " 2025-11-11 11:55:48 | \n",
+ " 2025-11-11 11:55:48.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 32 | \n",
+ " 2025-11-11 11:56:18 | \n",
+ " Rollout | \n",
+ " kolmogorov_smirnov | \n",
+ " 1.000000e+00 | \n",
+ " None | \n",
+ " False | \n",
+ " 2 | \n",
+ " 2025-11-11 11:56:18 | \n",
+ " 2025-11-11 11:56:18.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 33 | \n",
+ " 2025-11-11 11:56:48 | \n",
+ " Rollout | \n",
+ " kolmogorov_smirnov | \n",
+ " 1.000000e+00 | \n",
+ " None | \n",
+ " False | \n",
+ " 3 | \n",
+ " 2025-11-11 11:56:48 | \n",
+ " 2025-11-11 11:56:48.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 34 | \n",
+ " 2025-11-11 11:57:18 | \n",
+ " Rollout | \n",
+ " kolmogorov_smirnov | \n",
+ " 1.000000e+00 | \n",
+ " None | \n",
+ " False | \n",
+ " 4 | \n",
+ " 2025-11-11 11:57:18 | \n",
+ " 2025-11-11 11:57:18.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 35 | \n",
+ " 2025-11-11 11:57:48 | \n",
+ " Rollout | \n",
+ " kolmogorov_smirnov | \n",
+ " 1.000000e+00 | \n",
+ " None | \n",
+ " False | \n",
+ " 5 | \n",
+ " 2025-11-11 11:57:48 | \n",
+ " 2025-11-11 11:57:48.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 36 | \n",
+ " 2025-11-11 11:58:18 | \n",
+ " Rollout | \n",
+ " kolmogorov_smirnov | \n",
+ " 1.000000e+00 | \n",
+ " None | \n",
+ " False | \n",
+ " 6 | \n",
+ " 2025-11-11 11:58:18 | \n",
+ " 2025-11-11 11:58:18.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 37 | \n",
+ " 2025-11-11 11:58:48 | \n",
+ " Rollout | \n",
+ " kolmogorov_smirnov | \n",
+ " 1.000000e+00 | \n",
+ " None | \n",
+ " False | \n",
+ " 7 | \n",
+ " 2025-11-11 11:58:48 | \n",
+ " 2025-11-11 11:58:48.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 38 | \n",
+ " 2025-11-11 11:59:18 | \n",
+ " Rollout | \n",
+ " kolmogorov_smirnov | \n",
+ " 1.000000e+00 | \n",
+ " None | \n",
+ " False | \n",
+ " 8 | \n",
+ " 2025-11-11 11:59:18 | \n",
+ " 2025-11-11 11:59:18.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 39 | \n",
+ " 2025-11-11 11:59:48 | \n",
+ " Rollout | \n",
+ " kolmogorov_smirnov | \n",
+ " 1.000000e+00 | \n",
+ " None | \n",
+ " False | \n",
+ " 9 | \n",
+ " 2025-11-11 11:59:48 | \n",
+ " 2025-11-11 11:59:48.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 50 | \n",
+ " 2025-11-11 11:55:18 | \n",
+ " multivariate | \n",
+ " multivariate | \n",
+ " 1.517720e-14 | \n",
+ " NaN | \n",
+ " True | \n",
+ " 0 | \n",
+ " 2025-11-11 11:55:18 | \n",
+ " 2025-11-11 11:55:18.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 51 | \n",
+ " 2025-11-11 11:55:48 | \n",
+ " multivariate | \n",
+ " multivariate | \n",
+ " 1.588822e-14 | \n",
+ " NaN | \n",
+ " True | \n",
+ " 1 | \n",
+ " 2025-11-11 11:55:48 | \n",
+ " 2025-11-11 11:55:48.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 52 | \n",
+ " 2025-11-11 11:56:18 | \n",
+ " multivariate | \n",
+ " multivariate | \n",
+ " 1.432145e-14 | \n",
+ " NaN | \n",
+ " True | \n",
+ " 2 | \n",
+ " 2025-11-11 11:56:18 | \n",
+ " 2025-11-11 11:56:18.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 53 | \n",
+ " 2025-11-11 11:56:48 | \n",
+ " multivariate | \n",
+ " multivariate | \n",
+ " 1.421085e-14 | \n",
+ " NaN | \n",
+ " True | \n",
+ " 3 | \n",
+ " 2025-11-11 11:56:48 | \n",
+ " 2025-11-11 11:56:48.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 54 | \n",
+ " 2025-11-11 11:57:18 | \n",
+ " multivariate | \n",
+ " multivariate | \n",
+ " 1.421085e-14 | \n",
+ " NaN | \n",
+ " True | \n",
+ " 4 | \n",
+ " 2025-11-11 11:57:18 | \n",
+ " 2025-11-11 11:57:18.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 55 | \n",
+ " 2025-11-11 11:57:48 | \n",
+ " multivariate | \n",
+ " multivariate | \n",
+ " 1.776357e-15 | \n",
+ " NaN | \n",
+ " True | \n",
+ " 5 | \n",
+ " 2025-11-11 11:57:48 | \n",
+ " 2025-11-11 11:57:48.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 56 | \n",
+ " 2025-11-11 11:58:18 | \n",
+ " multivariate | \n",
+ " multivariate | \n",
+ " 7.324107e-15 | \n",
+ " NaN | \n",
+ " True | \n",
+ " 6 | \n",
+ " 2025-11-11 11:58:18 | \n",
+ " 2025-11-11 11:58:18.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 57 | \n",
+ " 2025-11-11 11:58:48 | \n",
+ " multivariate | \n",
+ " multivariate | \n",
+ " 1.464821e-14 | \n",
+ " NaN | \n",
+ " True | \n",
+ " 7 | \n",
+ " 2025-11-11 11:58:48 | \n",
+ " 2025-11-11 11:58:48.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 58 | \n",
+ " 2025-11-11 11:59:18 | \n",
+ " multivariate | \n",
+ " multivariate | \n",
+ " 1.551137e-14 | \n",
+ " NaN | \n",
+ " True | \n",
+ " 8 | \n",
+ " 2025-11-11 11:59:18 | \n",
+ " 2025-11-11 11:59:18.999999999 | \n",
+ "
\n",
+ " \n",
+ " | 59 | \n",
+ " 2025-11-11 11:59:48 | \n",
+ " multivariate | \n",
+ " multivariate | \n",
+ " 1.427317e-14 | \n",
+ " NaN | \n",
+ " True | \n",
+ " 9 | \n",
+ " 2025-11-11 11:59:48 | \n",
+ " 2025-11-11 11:59:48.999999999 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " timestamp feature metric statistic \\\n",
+ "10 2025-11-11 11:55:18 Counter kolmogorov_smirnov 1.000000e+00 \n",
+ "11 2025-11-11 11:55:48 Counter kolmogorov_smirnov 1.000000e+00 \n",
+ "12 2025-11-11 11:56:18 Counter kolmogorov_smirnov 1.000000e+00 \n",
+ "13 2025-11-11 11:56:48 Counter kolmogorov_smirnov 1.000000e+00 \n",
+ "14 2025-11-11 11:57:18 Counter kolmogorov_smirnov 1.000000e+00 \n",
+ "15 2025-11-11 11:57:48 Counter kolmogorov_smirnov 1.000000e+00 \n",
+ "16 2025-11-11 11:58:18 Counter kolmogorov_smirnov 1.000000e+00 \n",
+ "17 2025-11-11 11:58:48 Counter kolmogorov_smirnov 1.000000e+00 \n",
+ "18 2025-11-11 11:59:18 Counter kolmogorov_smirnov 1.000000e+00 \n",
+ "19 2025-11-11 11:59:48 Counter kolmogorov_smirnov 1.000000e+00 \n",
+ "30 2025-11-11 11:55:18 Rollout kolmogorov_smirnov 1.000000e+00 \n",
+ "31 2025-11-11 11:55:48 Rollout kolmogorov_smirnov 1.000000e+00 \n",
+ "32 2025-11-11 11:56:18 Rollout kolmogorov_smirnov 1.000000e+00 \n",
+ "33 2025-11-11 11:56:48 Rollout kolmogorov_smirnov 1.000000e+00 \n",
+ "34 2025-11-11 11:57:18 Rollout kolmogorov_smirnov 1.000000e+00 \n",
+ "35 2025-11-11 11:57:48 Rollout kolmogorov_smirnov 1.000000e+00 \n",
+ "36 2025-11-11 11:58:18 Rollout kolmogorov_smirnov 1.000000e+00 \n",
+ "37 2025-11-11 11:58:48 Rollout kolmogorov_smirnov 1.000000e+00 \n",
+ "38 2025-11-11 11:59:18 Rollout kolmogorov_smirnov 1.000000e+00 \n",
+ "39 2025-11-11 11:59:48 Rollout kolmogorov_smirnov 1.000000e+00 \n",
+ "50 2025-11-11 11:55:18 multivariate multivariate 1.517720e-14 \n",
+ "51 2025-11-11 11:55:48 multivariate multivariate 1.588822e-14 \n",
+ "52 2025-11-11 11:56:18 multivariate multivariate 1.432145e-14 \n",
+ "53 2025-11-11 11:56:48 multivariate multivariate 1.421085e-14 \n",
+ "54 2025-11-11 11:57:18 multivariate multivariate 1.421085e-14 \n",
+ "55 2025-11-11 11:57:48 multivariate multivariate 1.776357e-15 \n",
+ "56 2025-11-11 11:58:18 multivariate multivariate 7.324107e-15 \n",
+ "57 2025-11-11 11:58:48 multivariate multivariate 1.464821e-14 \n",
+ "58 2025-11-11 11:59:18 multivariate multivariate 1.551137e-14 \n",
+ "59 2025-11-11 11:59:48 multivariate multivariate 1.427317e-14 \n",
+ "\n",
+ " p_value alert chunk_index chunk_start_date \\\n",
+ "10 None False 0 2025-11-11 11:55:18 \n",
+ "11 None False 1 2025-11-11 11:55:48 \n",
+ "12 None False 2 2025-11-11 11:56:18 \n",
+ "13 None False 3 2025-11-11 11:56:48 \n",
+ "14 None False 4 2025-11-11 11:57:18 \n",
+ "15 None False 5 2025-11-11 11:57:48 \n",
+ "16 None False 6 2025-11-11 11:58:18 \n",
+ "17 None False 7 2025-11-11 11:58:48 \n",
+ "18 None False 8 2025-11-11 11:59:18 \n",
+ "19 None False 9 2025-11-11 11:59:48 \n",
+ "30 None False 0 2025-11-11 11:55:18 \n",
+ "31 None False 1 2025-11-11 11:55:48 \n",
+ "32 None False 2 2025-11-11 11:56:18 \n",
+ "33 None False 3 2025-11-11 11:56:48 \n",
+ "34 None False 4 2025-11-11 11:57:18 \n",
+ "35 None False 5 2025-11-11 11:57:48 \n",
+ "36 None False 6 2025-11-11 11:58:18 \n",
+ "37 None False 7 2025-11-11 11:58:48 \n",
+ "38 None False 8 2025-11-11 11:59:18 \n",
+ "39 None False 9 2025-11-11 11:59:48 \n",
+ "50 NaN True 0 2025-11-11 11:55:18 \n",
+ "51 NaN True 1 2025-11-11 11:55:48 \n",
+ "52 NaN True 2 2025-11-11 11:56:18 \n",
+ "53 NaN True 3 2025-11-11 11:56:48 \n",
+ "54 NaN True 4 2025-11-11 11:57:18 \n",
+ "55 NaN True 5 2025-11-11 11:57:48 \n",
+ "56 NaN True 6 2025-11-11 11:58:18 \n",
+ "57 NaN True 7 2025-11-11 11:58:48 \n",
+ "58 NaN True 8 2025-11-11 11:59:18 \n",
+ "59 NaN True 9 2025-11-11 11:59:48 \n",
+ "\n",
+ " chunk_end_date \n",
+ "10 2025-11-11 11:55:18.999999999 \n",
+ "11 2025-11-11 11:55:48.999999999 \n",
+ "12 2025-11-11 11:56:18.999999999 \n",
+ "13 2025-11-11 11:56:48.999999999 \n",
+ "14 2025-11-11 11:57:18.999999999 \n",
+ "15 2025-11-11 11:57:48.999999999 \n",
+ "16 2025-11-11 11:58:18.999999999 \n",
+ "17 2025-11-11 11:58:48.999999999 \n",
+ "18 2025-11-11 11:59:18.999999999 \n",
+ "19 2025-11-11 11:59:48.999999999 \n",
+ "30 2025-11-11 11:55:18.999999999 \n",
+ "31 2025-11-11 11:55:48.999999999 \n",
+ "32 2025-11-11 11:56:18.999999999 \n",
+ "33 2025-11-11 11:56:48.999999999 \n",
+ "34 2025-11-11 11:57:18.999999999 \n",
+ "35 2025-11-11 11:57:48.999999999 \n",
+ "36 2025-11-11 11:58:18.999999999 \n",
+ "37 2025-11-11 11:58:48.999999999 \n",
+ "38 2025-11-11 11:59:18.999999999 \n",
+ "39 2025-11-11 11:59:48.999999999 \n",
+ "50 2025-11-11 11:55:18.999999999 \n",
+ "51 2025-11-11 11:55:48.999999999 \n",
+ "52 2025-11-11 11:56:18.999999999 \n",
+ "53 2025-11-11 11:56:48.999999999 \n",
+ "54 2025-11-11 11:57:18.999999999 \n",
+ "55 2025-11-11 11:57:48.999999999 \n",
+ "56 2025-11-11 11:58:18.999999999 \n",
+ "57 2025-11-11 11:58:48.999999999 \n",
+ "58 2025-11-11 11:59:18.999999999 \n",
+ "59 2025-11-11 11:59:48.999999999 "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "# drop rows of drift with timestamp in reference data but not in analysis data\n",
+ "drift_filtered = drift[drift['timestamp'].isin(data['timestamp'])]\n",
+ "display(drift_filtered)\n",
+ "\n",
+ "drift_filtered.to_csv(\"drift_filtered.csv\", index=False)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "70671022",
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "ValueError",
+ "evalue": "Target column 'Square' not found in DataFrames",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[31m---------------------------------------------------------------------------\u001b[39m",
+ "\u001b[31mValueError\u001b[39m Traceback (most recent call last)",
+ "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[36]\u001b[39m\u001b[32m, line 6\u001b[39m\n\u001b[32m 3\u001b[39m \u001b[38;5;66;03m# rename column square to prediction\u001b[39;00m\n\u001b[32m 4\u001b[39m performance_reference.rename(columns={\u001b[33m'\u001b[39m\u001b[33mSquare\u001b[39m\u001b[33m'\u001b[39m: \u001b[33m'\u001b[39m\u001b[33mprediction\u001b[39m\u001b[33m'\u001b[39m}, inplace=\u001b[38;5;28;01mTrue\u001b[39;00m)\n\u001b[32m----> \u001b[39m\u001b[32m6\u001b[39m real_performance = \u001b[43mmodel\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcalculate_performance\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 7\u001b[39m \u001b[43m \u001b[49m\u001b[43mreference_df\u001b[49m\u001b[43m=\u001b[49m\u001b[43mperformance_reference\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 8\u001b[39m \u001b[43m \u001b[49m\u001b[43manalysis_df\u001b[49m\u001b[43m=\u001b[49m\u001b[43mdata\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 9\u001b[39m \u001b[43m \u001b[49m\u001b[43mtarget_col\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtarget_col\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 10\u001b[39m \u001b[43m \u001b[49m\u001b[43mtimestamp_col\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtimestamp_col\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 11\u001b[39m \u001b[43m \u001b[49m\u001b[43mchunk_period\u001b[49m\u001b[43m=\u001b[49m\u001b[43mchunk_period\u001b[49m\n\u001b[32m 12\u001b[39m \u001b[43m)\u001b[49m\n\u001b[32m 14\u001b[39m metrics_df = model.get_calculated_metrics_dataframe(real_performance)\n\u001b[32m 15\u001b[39m display(metrics_df)\n",
+ "\u001b[36mFile \u001b[39m\u001b[32m~/Documents/projects/sientia/sientia-dataops-orchestrator_temporal/venv/lib/python3.11/site-packages/sientia/ModelAnalysis.py:397\u001b[39m, in \u001b[36mModelAnalysis.calculate_performance\u001b[39m\u001b[34m(self, reference_df, analysis_df, target_col, timestamp_col, metrics, chunk_period)\u001b[39m\n\u001b[32m 395\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(DATAFRAMES_EMPTY_ERROR)\n\u001b[32m 396\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m target_col \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;129;01min\u001b[39;00m reference_df.columns \u001b[38;5;129;01mor\u001b[39;00m target_col \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;129;01min\u001b[39;00m analysis_df.columns:\n\u001b[32m--> \u001b[39m\u001b[32m397\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mTarget column \u001b[39m\u001b[33m'\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mtarget_col\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m'\u001b[39m\u001b[33m not found in DataFrames\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m 398\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m timestamp_col \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;129;01min\u001b[39;00m reference_df.columns \u001b[38;5;129;01mor\u001b[39;00m timestamp_col \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;129;01min\u001b[39;00m analysis_df.columns:\n\u001b[32m 399\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mTimestamp column \u001b[39m\u001b[33m'\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mtimestamp_col\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m'\u001b[39m\u001b[33m not found in DataFrames\u001b[39m\u001b[33m\"\u001b[39m)\n",
+ "\u001b[31mValueError\u001b[39m: Target column 'Square' not found in DataFrames"
+ ]
+ }
+ ],
+ "source": [
+ "\n",
+ "real_performance = model.calculate_performance(\n",
+ " reference_df=data,\n",
+ " analysis_df=data,\n",
+ " target_col=target_col,\n",
+ " timestamp_col=timestamp_col,\n",
+ " chunk_period=chunk_period\n",
+ ")\n",
+ "\n",
+ "metrics_df = model.get_calculated_metrics_dataframe(real_performance)\n",
+ "display(metrics_df)\n",
+ "\n",
+ "metrics_df.to_csv(\"metrics_df.csv\", index=False)"
+ ]
}
],
"metadata": {
diff --git a/tests/orchestrator/activities/test_formatters.py b/tests/orchestrator/activities/test_formatters.py
index 223227e..12f6901 100644
--- a/tests/orchestrator/activities/test_formatters.py
+++ b/tests/orchestrator/activities/test_formatters.py
@@ -44,8 +44,12 @@ metadata = {
'orchestrator.activities.formatters.minimal_retrain',
return_value={'test_minimal_retrain': 'test_minimal_retrain'},
)
+@patch(
+ 'orchestrator.activities.formatters.drift',
+ return_value={'test_drift': 'test_drift'},
+)
async def test_process_schedules(
- mock_minimal_retrain, mock_predictions_batch, mock_scouter, formatters
+ mock_drift, mock_minimal_retrain, mock_predictions_batch, mock_scouter, formatters
):
input_data = {
'pipelines': [
@@ -70,6 +74,13 @@ async def test_process_schedules(
'model_id': 'test_model_id',
'updated_at': '2021-01-03',
},
+ {
+ 'schedule_name': 'test_schedule_name4',
+ 'workflow_type': 'drift',
+ 'model_name': 'test_model_name',
+ 'model_id': 'test_model_id',
+ 'updated_at': '2021-01-04',
+ },
]
}
@@ -88,11 +99,17 @@ async def test_process_schedules(
'test_minimal_retrain': 'test_minimal_retrain',
'updated_at': '2021-01-03',
},
+ 'test_schedule_name4': {
+ 'test_drift': 'test_drift',
+ 'updated_at': '2021-01-04',
+ },
},
}
mock_scouter.assert_called_once_with(input_data['pipelines'][0])
mock_predictions_batch.assert_called_once_with(input_data['pipelines'][1])
+ mock_minimal_retrain.assert_called_once_with(input_data['pipelines'][2])
+ mock_drift.assert_called_once_with(input_data['pipelines'][3])
@mark.asyncio
diff --git a/tests/orchestrator/utils/test_orchestrator_functions.py b/tests/orchestrator/utils/test_orchestrator_functions.py
index f74a936..7c8f5da 100644
--- a/tests/orchestrator/utils/test_orchestrator_functions.py
+++ b/tests/orchestrator/utils/test_orchestrator_functions.py
@@ -3,6 +3,7 @@ from unittest.mock import call, patch
from orchestrator.utils.orchestrator_functions import (
build_tag_config,
common_config,
+ drift,
gather_read_tags,
minimal_retrain,
overlap_filter_config,
@@ -35,6 +36,36 @@ def test_common_config():
assert result == expected
+def test_drift():
+ config = {
+ 'workflow_type': 'drift',
+ 'schedule_name': 'test_schedule',
+ 'model_id': 'test_model_id',
+ 'model': {'name': 'test_model_name', 'model_config': {'test_config': 'test_config'}},
+ 'interval_minutes': 120,
+ 'drift_metrics': ['kolmogorov_smirnov', 'jensen_shannon'],
+ }
+ result = drift(config)
+ expected = {
+ 'workflow_type': 'drift',
+ 'schedule_name': 'test_schedule',
+ 'frequency': '1m',
+ 'offset': '0m',
+ 'max_retry_policy': 1,
+ 'model_id': 'test_model_id',
+ 'model_name': 'test_model_name',
+ 'model_config': {'test_config': 'test_config'},
+ 'schema': 'sientia_data',
+ 'source_table_name': 'laborious_data',
+ 'target_table_name': 'drift_metrics',
+ 'interval': 120,
+ 'drift_metrics': ['kolmogorov_smirnov', 'jensen_shannon'],
+ 'execution_timeout_seconds': 300,
+ 'task_timeout_seconds': 300,
+ }
+ assert result == expected
+
+
def test_minimal_retrain():
config = {
'workflow_type': 'minimal_retrain',