stride-xai 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. stride_xai-0.1.0/LICENSE +21 -0
  2. stride_xai-0.1.0/PKG-INFO +372 -0
  3. stride_xai-0.1.0/README.md +296 -0
  4. stride_xai-0.1.0/pyproject.toml +130 -0
  5. stride_xai-0.1.0/src/stride/__init__.py +68 -0
  6. stride_xai-0.1.0/src/stride/common/__init__.py +163 -0
  7. stride_xai-0.1.0/src/stride/datasets/__init__.py +63 -0
  8. stride_xai-0.1.0/src/stride/datasets/base.py +80 -0
  9. stride_xai-0.1.0/src/stride/datasets/csv_dataset.py +32 -0
  10. stride_xai-0.1.0/src/stride/datasets/dataset_registry.py +78 -0
  11. stride_xai-0.1.0/src/stride/datasets/dataset_urls.json +387 -0
  12. stride_xai-0.1.0/src/stride/datasets/hyperplane_drift.py +100 -0
  13. stride_xai-0.1.0/src/stride/datasets/imported_dataset.py +52 -0
  14. stride_xai-0.1.0/src/stride/datasets/linear_weight_inversion_drift.py +86 -0
  15. stride_xai-0.1.0/src/stride/datasets/mixed_multi_window.py +85 -0
  16. stride_xai-0.1.0/src/stride/datasets/plane_multi_window.py +64 -0
  17. stride_xai-0.1.0/src/stride/datasets/protree_data/__init__.py +32 -0
  18. stride_xai-0.1.0/src/stride/datasets/protree_data/named_stream.py +90 -0
  19. stride_xai-0.1.0/src/stride/datasets/protree_data/real_stream.py +123 -0
  20. stride_xai-0.1.0/src/stride/datasets/protree_data/river_generators.py +163 -0
  21. stride_xai-0.1.0/src/stride/datasets/protree_data/static.py +369 -0
  22. stride_xai-0.1.0/src/stride/datasets/protree_data/stream_generators.py +210 -0
  23. stride_xai-0.1.0/src/stride/datasets/protree_data/utils.py +32 -0
  24. stride_xai-0.1.0/src/stride/datasets/random_rbf_drift.py +74 -0
  25. stride_xai-0.1.0/src/stride/datasets/random_tree_multi_window.py +92 -0
  26. stride_xai-0.1.0/src/stride/datasets/rbf_drift.py +120 -0
  27. stride_xai-0.1.0/src/stride/datasets/rbf_multi_window.py +92 -0
  28. stride_xai-0.1.0/src/stride/datasets/river_dataset.py +58 -0
  29. stride_xai-0.1.0/src/stride/datasets/sea_drift.py +45 -0
  30. stride_xai-0.1.0/src/stride/datasets/sea_multi_window.py +64 -0
  31. stride_xai-0.1.0/src/stride/datasets/sine_multi_window.py +91 -0
  32. stride_xai-0.1.0/src/stride/datasets/stagger_multi_window.py +85 -0
  33. stride_xai-0.1.0/src/stride/datasets/utils.py +139 -0
  34. stride_xai-0.1.0/src/stride/drift/__init__.py +8 -0
  35. stride_xai-0.1.0/src/stride/drift/_types.py +16 -0
  36. stride_xai-0.1.0/src/stride/drift/binary_descriptor.py +348 -0
  37. stride_xai-0.1.0/src/stride/exceptions.py +41 -0
  38. stride_xai-0.1.0/src/stride/models/__init__.py +9 -0
  39. stride_xai-0.1.0/src/stride/models/base.py +88 -0
  40. stride_xai-0.1.0/src/stride/models/mlp.py +41 -0
  41. stride_xai-0.1.0/src/stride/models/random_forest.py +33 -0
  42. stride_xai-0.1.0/src/stride/plotting/__init__.py +15 -0
  43. stride_xai-0.1.0/src/stride/plotting/_renderers.py +118 -0
  44. stride_xai-0.1.0/src/stride/plotting/stream.py +374 -0
  45. stride_xai-0.1.0/src/stride/py.typed +1 -0
  46. stride_xai-0.1.0/src/stride/xai/__init__.py +18 -0
  47. stride_xai-0.1.0/src/stride/xai/boundary/__init__.py +0 -0
  48. stride_xai-0.1.0/src/stride/xai/boundary/analysis.py +203 -0
  49. stride_xai-0.1.0/src/stride/xai/boundary/disagreement.py +303 -0
  50. stride_xai-0.1.0/src/stride/xai/boundary/ssnp.py +252 -0
  51. stride_xai-0.1.0/src/stride/xai/boundary/visualization.py +234 -0
  52. stride_xai-0.1.0/src/stride/xai/clustering/__init__.py +11 -0
  53. stride_xai-0.1.0/src/stride/xai/clustering/clustering.py +385 -0
  54. stride_xai-0.1.0/src/stride/xai/clustering/matching.py +180 -0
  55. stride_xai-0.1.0/src/stride/xai/clustering/statistics.py +255 -0
  56. stride_xai-0.1.0/src/stride/xai/clustering/visualization.py +404 -0
  57. stride_xai-0.1.0/src/stride/xai/clustering/xmeans.py +89 -0
  58. stride_xai-0.1.0/src/stride/xai/importance/__init__.py +11 -0
  59. stride_xai-0.1.0/src/stride/xai/importance/analysis.py +447 -0
  60. stride_xai-0.1.0/src/stride/xai/importance/base.py +23 -0
  61. stride_xai-0.1.0/src/stride/xai/importance/methods.py +183 -0
  62. stride_xai-0.1.0/src/stride/xai/importance/visualization.py +206 -0
  63. stride_xai-0.1.0/src/stride/xai/recurrence/full_window_storage.py +226 -0
  64. stride_xai-0.1.0/src/stride/xai/recurrence/methods.py +282 -0
  65. stride_xai-0.1.0/src/stride/xai/recurrence/protree/__init__.py +12 -0
  66. stride_xai-0.1.0/src/stride/xai/recurrence/protree/detectors.py +188 -0
  67. stride_xai-0.1.0/src/stride/xai/recurrence/protree/explainers/__init__.py +18 -0
  68. stride_xai-0.1.0/src/stride/xai/recurrence/protree/explainers/naive.py +103 -0
  69. stride_xai-0.1.0/src/stride/xai/recurrence/protree/explainers/tree_distance.py +338 -0
  70. stride_xai-0.1.0/src/stride/xai/recurrence/protree/explainers/utils.py +50 -0
  71. stride_xai-0.1.0/src/stride/xai/recurrence/protree/meta.py +4 -0
  72. stride_xai-0.1.0/src/stride/xai/recurrence/protree/metrics/__init__.py +0 -0
  73. stride_xai-0.1.0/src/stride/xai/recurrence/protree/metrics/classification.py +10 -0
  74. stride_xai-0.1.0/src/stride/xai/recurrence/protree/metrics/compare.py +463 -0
  75. stride_xai-0.1.0/src/stride/xai/recurrence/protree/metrics/group.py +123 -0
  76. stride_xai-0.1.0/src/stride/xai/recurrence/protree/metrics/individual.py +95 -0
  77. stride_xai-0.1.0/src/stride/xai/recurrence/protree/pruning.py +12 -0
  78. stride_xai-0.1.0/src/stride/xai/recurrence/protree/transformations.py +59 -0
  79. stride_xai-0.1.0/src/stride/xai/recurrence/protree/utils.py +94 -0
  80. stride_xai-0.1.0/src/stride/xai/recurrence/visualisation.py +6 -0
  81. stride_xai-0.1.0/src/stride/xai/recurrence/visualization.py +448 -0
  82. stride_xai-0.1.0/src/stride/xai/stats/__init__.py +7 -0
  83. stride_xai-0.1.0/src/stride/xai/stats/descriptive_statistics.py +357 -0
  84. stride_xai-0.1.0/src/stride/xai/stats/statistical_tests.py +223 -0
  85. stride_xai-0.1.0/src/stride/xai/stats/visualization.py +315 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 KubaCzech
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,372 @@
1
+ Metadata-Version: 2.4
2
+ Name: stride-xai
3
+ Version: 0.1.0
4
+ Summary: STRIDE: Explainable AI and Drift Detection Framework
5
+ Keywords: concept-drift,data-drift,explainable-ai,xai,stream-learning,drift-detection,decision-boundary
6
+ Author: Deniz Aksoy, Kuba Czech, Wojciech Nagórka, Michał Redmer
7
+ Requires-Python: >=3.10
8
+ Description-Content-Type: text/markdown
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Intended Audience :: Science/Research
11
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ License-File: LICENSE
18
+ Requires-Dist: numpy<2.0
19
+ Requires-Dist: pandas
20
+ Requires-Dist: scipy
21
+ Requires-Dist: scikit-learn
22
+ Requires-Dist: river
23
+ Requires-Dist: matplotlib ; extra == "all"
24
+ Requires-Dist: seaborn ; extra == "all"
25
+ Requires-Dist: plotly ; extra == "all"
26
+ Requires-Dist: river ; extra == "all"
27
+ Requires-Dist: pyclustering ; extra == "all"
28
+ Requires-Dist: hdbscan ; extra == "all"
29
+ Requires-Dist: umap-learn ; extra == "all"
30
+ Requires-Dist: shap ; extra == "all"
31
+ Requires-Dist: lime ; extra == "all"
32
+ Requires-Dist: tensorflow>=2.15.0 ; extra == "all"
33
+ Requires-Dist: streamlit ; extra == "all"
34
+ Requires-Dist: icecream ; extra == "all"
35
+ Requires-Dist: ruff ; extra == "all"
36
+ Requires-Dist: pyclustering ; extra == "clustering"
37
+ Requires-Dist: hdbscan ; extra == "clustering"
38
+ Requires-Dist: umap-learn ; extra == "clustering"
39
+ Requires-Dist: streamlit ; extra == "dashboard"
40
+ Requires-Dist: matplotlib ; extra == "dashboard"
41
+ Requires-Dist: seaborn ; extra == "dashboard"
42
+ Requires-Dist: plotly ; extra == "dashboard"
43
+ Requires-Dist: river ; extra == "dashboard"
44
+ Requires-Dist: pyclustering ; extra == "dashboard"
45
+ Requires-Dist: hdbscan ; extra == "dashboard"
46
+ Requires-Dist: umap-learn ; extra == "dashboard"
47
+ Requires-Dist: shap ; extra == "dashboard"
48
+ Requires-Dist: lime ; extra == "dashboard"
49
+ Requires-Dist: tensorflow>=2.15.0 ; extra == "dashboard"
50
+ Requires-Dist: icecream ; extra == "dashboard"
51
+ Requires-Dist: tensorflow>=2.15.0 ; extra == "deeplearning"
52
+ Requires-Dist: ruff ; extra == "dev"
53
+ Requires-Dist: pytest ; extra == "dev"
54
+ Requires-Dist: build ; extra == "dev"
55
+ Requires-Dist: twine ; extra == "dev"
56
+ Requires-Dist: river ; extra == "drift"
57
+ Requires-Dist: matplotlib ; extra == "vis"
58
+ Requires-Dist: seaborn ; extra == "vis"
59
+ Requires-Dist: plotly ; extra == "vis"
60
+ Requires-Dist: shap ; extra == "xai"
61
+ Requires-Dist: lime ; extra == "xai"
62
+ Project-URL: Changelog, https://github.com/KubaCzech/STRIDE/blob/main/CHANGELOG.md
63
+ Project-URL: Documentation, https://kubaczech.github.io/STRIDE/
64
+ Project-URL: Homepage, https://michalredm.github.io/stride-website/
65
+ Project-URL: Issues, https://github.com/KubaCzech/STRIDE/issues
66
+ Project-URL: Repository, https://github.com/KubaCzech/STRIDE
67
+ Provides-Extra: all
68
+ Provides-Extra: clustering
69
+ Provides-Extra: dashboard
70
+ Provides-Extra: deeplearning
71
+ Provides-Extra: dev
72
+ Provides-Extra: drift
73
+ Provides-Extra: vis
74
+ Provides-Extra: xai
75
+
76
+ # STRIDE: STReam Insight and Drift Explanation
77
+
78
+ A Python Toolkit for Concept Drift Detection, Characterization, and Explanation
79
+
80
+ [![ECML PKDD 2026](https://img.shields.io/badge/ECML--PKDD_2026-Demo_Track-1E88E5.svg)](https://michalredm.github.io/stride-website/assets/pdf/paper.pdf)
81
+ [![DOI: 10.1007/978-3-032-37685-5_32](https://img.shields.io/badge/DOI-10.1007%2F978--3--032--37685--5__32-blue.svg)](https://link.springer.com/chapter/10.1007/978-3-032-37685-5_32)
82
+ [![PyPI version](https://img.shields.io/pypi/v/stride-xai.svg)](https://pypi.org/project/stride-xai/)
83
+ [![Python Versions](https://img.shields.io/pypi/pyversions/stride-xai.svg)](https://pypi.org/project/stride-xai/)
84
+ [![Website](https://img.shields.io/badge/Website-STRIDE-0A66C2?logo=googlechrome&logoColor=white)](https://michalredm.github.io/stride-website/)
85
+ [![Live Demo](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://stream-insight-and-drift-explanation.streamlit.app/)
86
+ [![CI](https://github.com/KubaCzech/STRIDE/actions/workflows/ci.yml/badge.svg)](https://github.com/KubaCzech/STRIDE/actions/workflows/ci.yml)
87
+ [![Code style: ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
88
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/KubaCzech/STRIDE/blob/main/LICENSE)
89
+
90
+ [Website](https://michalredm.github.io/stride-website/) &bull; [Live Dashboard](https://stream-insight-and-drift-explanation.streamlit.app/) &bull; [Springer Chapter](https://link.springer.com/chapter/10.1007/978-3-032-37685-5_32) &bull; [Paper (PDF)](https://michalredm.github.io/stride-website/assets/pdf/paper.pdf) &bull; [Architecture](#three-layer-architecture) &bull; [Quickstart](#quickstart) &bull; [Citation](#citation)
91
+
92
+ ---
93
+
94
+ ## Overview
95
+
96
+ Concept drift in streaming environments degrades machine learning models when underlying data distributions evolve over time. Traditional drift detectors (e.g., DDM, EDDM, ADWIN) signal **when** classifier accuracy drops, but treat the model and data as black boxes—failing to explain **how** the distribution shifted or **where** in the feature space decision boundaries deteriorated.
97
+
98
+ **STRIDE** (*STReam Insight and Drift Explanation*) bridges this diagnostic gap. Presented at **ECML PKDD 2026** (Demo Track), STRIDE is an open-source Python framework and interactive dashboard that orchestrates analytical signals across three concurrent layers:
99
+
100
+ 1. **Data Layer** (*How*): Monitors raw input distributions and cluster geometry independently of the model.
101
+ 2. **Model Layer** (*When*): Tracks predictive performance metrics and fires sequential drift alerts.
102
+ 3. **Explanation Layer** (*Where*): Adapts Explainable AI (xAI) methods to locate local decision boundary shifts, identify drift-driving features, and detect recurring concepts.
103
+
104
+ Instead of triggering post-hoc explanations only after significant performance degradation, STRIDE executes a **synchronous pipeline** that processes incoming windows across all three layers in parallel. This design enables analysts to trace the emergence of drift and observe the evolution of model logic in real time.
105
+
106
+ ---
107
+
108
+ ## Three-Layer Architecture
109
+
110
+ ![STRIDE Synchronous Processing Pipeline](https://raw.githubusercontent.com/KubaCzech/STRIDE/main/assets/pipeline.png)
111
+
112
+ ### 1. Data Layer (Statistical & Geometric Shifts)
113
+ Evaluates covariate shifts independent of the predictive model:
114
+ * **Descriptive Statistics & Divergences**: Computes class-conditional moments, variances, and 1D Wasserstein distances to evaluate distribution movement.
115
+ * **Non-Parametric Hypothesis Tests**: Two-sample Kolmogorov-Smirnov (KS) and Anderson-Darling tests detect significant univariate distribution differences between sliding windows.
116
+ * **Clustering Dynamics**: Evaluates density shifts using X-means clustering, applying the Hungarian algorithm to track cluster splitting, migration, and centroid displacement across consecutive batches.
117
+
118
+ ### 2. Model Layer (Performance Triggers)
119
+ Tracks streaming model health and online error rates:
120
+ * **Streaming Detectors**: Integrates the [River](https://riverml.xyz/) stream learning ecosystem, supporting Drift Detection Method (DDM) and related sequential algorithms.
121
+ * **Continuous Error Profiling**: Real-time evaluation of error rate trajectories, warning bands, and predictive confidence across sliding windows.
122
+
123
+ ### 3. Explanation Layer (Model-Agnostic Interpretability)
124
+ Explains the mechanics of detected drift within the classifier's feature space:
125
+ * **Supervised Decision Boundary Maps (SDBM)**: Projects high-dimensional feature spaces into 2D to visualize how class separation boundaries rotate, compress, or deform between pre-drift and post-drift states.
126
+ * **Feature Importance Attribution**: Evaluates both model-centric (SHAP, Permutation Feature Importance) and data-centric importance shifts to differentiate features driving model degradation from those preserving predictive utility.
127
+ * **Recurring Concept Analysis**: Extracts prototype representations per window and applies HDBSCAN clustering to distance matrices, distinguishing re-emerging historical concepts from novel anomalies.
128
+
129
+ ---
130
+
131
+ ## Interactive Dashboard
132
+
133
+ STRIDE includes a reactive [Streamlit](https://streamlit.io/) dashboard designed for interactive forensics and exploratory research.
134
+
135
+ * **Replay Streams**: Step through continuous streams or jump directly to detected drift points.
136
+ * **Comparative Window Analysis**: Compare pre-drift reference windows with post-drift detection windows across all three analytical layers side by side.
137
+ * **Dynamic Configuration**: Adjust sliding window sizes, statistical test significance thresholds ($\alpha$), and classifier architectures on the fly.
138
+ * **Hosted Demo**: An interactive demo is deployed at [stream-insight-and-drift-explanation.streamlit.app](https://stream-insight-and-drift-explanation.streamlit.app/).
139
+
140
+ ---
141
+
142
+ ## Quickstart
143
+
144
+ ### Running the Interactive Dashboard
145
+
146
+ Launch the dashboard locally:
147
+
148
+ ```bash
149
+ streamlit run dashboard/app.py
150
+ ```
151
+
152
+ The application opens at `http://localhost:8501`.
153
+
154
+ ### Python API Usage
155
+
156
+ STRIDE exposes a clean programmatic API under the `stride` namespace. After installation (see below), no `sys.path` manipulation is required:
157
+
158
+ ```python
159
+ from stride.datasets import HyperplaneDriftDataset
160
+ from stride.xai.stats import StatisticalTestsDriftDetector, StatisticalTestType
161
+ from stride.models import RandomForestModel
162
+
163
+ # 1. Generate a synthetic streaming dataset with rotating hyperplane drift
164
+ dataset = HyperplaneDriftDataset()
165
+ X, y = dataset.generate(
166
+ n_samples_before=1000,
167
+ n_samples_after=1000,
168
+ n_features=5,
169
+ n_drift_features=2,
170
+ drift_width=100,
171
+ random_seed=42,
172
+ )
173
+
174
+ # 2. Partition into reference (pre-drift) and detection (post-drift) windows
175
+ X_ref, y_ref = X.iloc[:1000], y.iloc[:1000]
176
+ X_det, y_det = X.iloc[1000:], y.iloc[1000:]
177
+
178
+ # 3. Train a streaming classifier on the reference window
179
+ model = RandomForestModel()
180
+ model.fit(X_ref, y_ref)
181
+
182
+ # 4. Detect and characterize distribution shifts via non-parametric statistical tests
183
+ detector = StatisticalTestsDriftDetector(X_ref, y_ref, X_det, y_det)
184
+ has_drift = detector.detect(StatisticalTestType.KolmogorovSmirnov)
185
+
186
+ print(f"Drift detected: {has_drift}")
187
+ print(f"Per-feature test outcomes: {detector.drift_flags}")
188
+ ```
189
+
190
+ Top-level convenience imports are also available directly from `stride`:
191
+
192
+ ```python
193
+ import stride
194
+
195
+ model = stride.RandomForestModel()
196
+ detector = stride.DescriptiveStatisticsDriftDetector(...)
197
+ ```
198
+
199
+ ---
200
+
201
+ ## Installation
202
+
203
+ ### Prerequisites
204
+
205
+ * Python 3.10, 3.11, or 3.12
206
+ * Git
207
+
208
+ ### From PyPI (Recommended for Users)
209
+
210
+ Install the core package directly from PyPI:
211
+
212
+ ```bash
213
+ pip install stride-xai
214
+ ```
215
+
216
+ Optional capability extras can be installed as needed:
217
+ ```bash
218
+ pip install "stride-xai[all]" # All extras (visualizations, XAI, deep learning, dashboard)
219
+ pip install "stride-xai[dashboard]" # Interactive Streamlit dashboard dependencies
220
+ pip install "stride-xai[xai]" # SHAP and LIME explainers
221
+ ```
222
+
223
+ ### From Source (Development)
224
+
225
+ 1. **Clone the repository**:
226
+ ```bash
227
+ git clone https://github.com/KubaCzech/STRIDE.git
228
+ cd STRIDE
229
+ ```
230
+
231
+ 2. **Create and activate a virtual environment**:
232
+ ```bash
233
+ # Linux / macOS
234
+ python3 -m venv .venv
235
+ source .venv/bin/activate
236
+
237
+ # Windows (PowerShell)
238
+ python -m venv .venv
239
+ .venv\Scripts\Activate.ps1
240
+ ```
241
+
242
+ 3. **Install the package and its dependencies**:
243
+ ```bash
244
+ pip install --upgrade pip
245
+ pip install -r requirements.txt
246
+ pip install -e .
247
+ ```
248
+
249
+ The editable install (`-e .`) registers the `stride` package in your environment so that `from stride.datasets import ...` works without any `sys.path` manipulation.
250
+
251
+ **Optional extras** can be appended in brackets to install additional capability groups:
252
+
253
+ | Extra | Installs |
254
+ |---|---|
255
+ | `pip install -e ".[vis]"` | `matplotlib`, `seaborn`, `plotly` |
256
+ | `pip install -e ".[drift]"` | `river` (online stream learning) |
257
+ | `pip install -e ".[clustering]"` | `pyclustering`, `hdbscan`, `umap-learn` |
258
+ | `pip install -e ".[xai]"` | `shap`, `lime` |
259
+ | `pip install -e ".[deeplearning]"` | `tensorflow>=2.15` (for SSNP boundary projection) |
260
+ | `pip install -e ".[dashboard]"` | `streamlit`, `icecream` |
261
+ | `pip install -e ".[all]"` | All of the above |
262
+
263
+ 4. **Verify the installation**:
264
+ ```bash
265
+ python -m unittest discover tests
266
+ ```
267
+
268
+ ---
269
+
270
+ ## Supported Drift Scenarios & Models
271
+
272
+ ### Synthetic Drift Generators
273
+ * **Hyperplane Drift**: Continuously rotating hyperplane in $d$-dimensional space simulating gradual concept drift.
274
+ * **SEA Drift**: Abrupt decision threshold displacement with noise features.
275
+ * **RBF Drift**: Non-linear cluster movement and centroid translation in continuous feature space.
276
+ * **Linear Weight Inversion (LWI)**: Correlation inversion testing model sensitivity to feature attribution flips.
277
+ * **Multi-Window Generators**: Mixed, Sine, STAGGER, and Random Tree streams for multi-concept scenarios.
278
+ * **Real-World Benchmarks**: Pre-configured support for benchmark datasets (e.g., Electricity, Covertype, NOAA weather).
279
+
280
+ ### Model Implementations
281
+ * Multi-Layer Perceptrons (MLP / Neural Networks)
282
+ * Random Forests
283
+ * Support Vector Machines (SVM)
284
+ * Logistic Regression & incremental online models via River
285
+
286
+ ---
287
+
288
+ ## Project Structure
289
+
290
+ ```text
291
+ STRIDE/
292
+ ├── assets/ # Architecture diagrams and visual documentation
293
+ │ └── pipeline.png
294
+ ├── dashboard/ # Streamlit interactive application
295
+ │ ├── app.py # Application entry point
296
+ │ ├── assets/ # Dashboard styles and custom CSS
297
+ │ ├── components/ # UI tabs (Data, Model, Explanation layers)
298
+ │ └── config/ # Dashboard-only widget schemas & presets
299
+ │ ├── dataset_schemas.py # Dataset UI configuration (decoupled from core)
300
+ │ └── model_schemas.py # Model UI configuration (decoupled from core)
301
+ ├── src/ # PyPA src-layout root
302
+ │ ├── stride/ # Canonical Python package (import as `stride`)
303
+ │ │ ├── __init__.py # Top-level public API & convenience re-exports
304
+ │ │ ├── exceptions.py # Domain exception hierarchy (StrideError, …)
305
+ │ │ ├── py.typed # PEP 561 marker for static type checkers
306
+ │ │ ├── common/ # Shared utilities and window helpers
307
+ │ │ ├── datasets/ # Streaming data generators and real datasets
308
+ │ │ │ ├── hyperplane_drift.py
309
+ │ │ │ ├── sea_drift.py
310
+ │ │ │ ├── rbf_drift.py
311
+ │ │ │ ├── linear_weight_inversion_drift.py
312
+ │ │ │ ├── *_multi_window.py # Multi-concept stream generators
313
+ │ │ │ ├── csv_dataset.py
314
+ │ │ │ └── river_dataset.py
315
+ │ │ ├── drift/ # Sequential drift detectors
316
+ │ │ │ └── binary_descriptor.py # BinaryErrorDriftDescriptor (DDM-based)
317
+ │ │ ├── models/ # Model wrappers with fit/predict API
318
+ │ │ │ ├── mlp.py # Multi-Layer Perceptron
319
+ │ │ │ └── random_forest.py # Random Forest
320
+ │ │ ├── plotting/ # Stream-level matplotlib visualizations
321
+ │ │ └── xai/ # Explainable AI analyzers
322
+ │ │ ├── boundary/ # Decision boundary maps (SDBM / SSNP)
323
+ │ │ ├── clustering/ # X-means clustering dynamics
324
+ │ │ ├── importance/ # SHAP & Permutation Feature Importance
325
+ │ │ ├── recurrence/ # ProTree prototype & HDBSCAN concept detection
326
+ │ │ └── stats/ # Statistical tests (KS, AD, Wasserstein)
327
+ │ └── DDM/ # Backward-compatibility bridge → stride.drift
328
+ ├── tests/ # Automated test suite
329
+ ├── pyproject.toml # PEP 621 package metadata, extras, and ruff config
330
+ └── requirements.txt # Pinned runtime dependencies
331
+ ```
332
+
333
+ ---
334
+
335
+ ## Citation
336
+
337
+ If you use STRIDE in your research, please cite our paper from the **ECML PKDD 2026 Demo Track**:
338
+
339
+ ```bibtex
340
+ @inproceedings{nagorka2026stride,
341
+ title = {{STReam Insight and Drift Explanation (STRIDE): A Python Toolkit for Concept Drift Detection and Explanation}},
342
+ author = {Nag{\'o}rka, Wojciech and Redmer, Micha{\l} and Czech, Kuba and Aksoy, Deniz and Stefanowski, Jerzy},
343
+ booktitle = {Machine Learning and Knowledge Discovery in Databases. Applied Data Science Track, Demo Track and Industrial Track (ECML PKDD)},
344
+ series = {Lecture Notes in Computer Science},
345
+ pages = {348--352},
346
+ year = {2026},
347
+ publisher = {Springer, Cham},
348
+ doi = {10.1007/978-3-032-37685-5_32},
349
+ url = {https://link.springer.com/chapter/10.1007/978-3-032-37685-5_32}
350
+ }
351
+ ```
352
+
353
+ ---
354
+
355
+ ## Authors & Acknowledgments
356
+
357
+ * **Wojciech Nagórka** &bull; Poznań University of Technology
358
+ * **Michał Redmer** &bull; Poznań University of Technology
359
+ * **Kuba Czech** &bull; Poznań University of Technology
360
+ * **Deniz Aksoy** &bull; Poznań University of Technology
361
+ * **Jerzy Stefanowski** &bull; Poznań University of Technology
362
+
363
+ **Funding**: The research by Jerzy Stefanowski was funded by the National Science Centre, Poland, under OPUS grant no. `2023/51/B/ST6/00545`.
364
+
365
+ Project Website: [https://michalredm.github.io/stride-website/](https://michalredm.github.io/stride-website/)
366
+
367
+ ---
368
+
369
+ ## License
370
+
371
+ This project is licensed under the MIT License. See the [LICENSE](https://github.com/KubaCzech/STRIDE/blob/main/LICENSE) file for details.
372
+