diff --git a/doc/rtd/content/03_machine_learning/mlpro_oa/main.rst b/doc/rtd/content/03_machine_learning/mlpro_oa/main.rst index 61f716813..18cc6d7f7 100644 --- a/doc/rtd/content/03_machine_learning/mlpro_oa/main.rst +++ b/doc/rtd/content/03_machine_learning/mlpro_oa/main.rst @@ -2,9 +2,12 @@ MLPro-OA - Online Adaptivity ============================ -This framework addresses topics of online machine learning and is already implemented and ready to be used by early adopters. The -documentation is still in preparation but the API description is already done. Just browse through the menu structure and follow -the links provided... +This framework addresses the challenge of continuously adapting to changing conditions by processing new information in real time. Unlike traditional offline approaches, +which rely on predefined models trained on historical data, online-adaptive methods dynamically refine their behavior as new data becomes available. This enables +continuous learning, rapid adaptation to non-stationary environments, and increased robustness in uncertain or evolving scenarios. Such methods are essential in domains +requiring real-time decision-making and continuous model updates, including autonomous systems, predictive analytics, and self-optimizing processes. + +The following subfields are available in MLPro-OA: .. toctree:: :maxdepth: 2 diff --git a/doc/rtd/content/03_machine_learning/mlpro_oa/sub/01_oa_stream_processing.rst b/doc/rtd/content/03_machine_learning/mlpro_oa/sub/01_oa_stream_processing.rst new file mode 100644 index 000000000..58dc3f787 --- /dev/null +++ b/doc/rtd/content/03_machine_learning/mlpro_oa/sub/01_oa_stream_processing.rst @@ -0,0 +1,32 @@ +.. _target_oa_streams: +Online-adaptive data stream processing (OADSP) +============================================== + +This sub-framework of MLPro-OA is directly related to the research topic of online machine learning (OML). It deals with +online-adaptive stream tasks embedded in a stream workflow as part of an extended process model. This process model extends +the non-adaptive DSP process model of sub-framework MLPro-BF-Streams by advanced adaptation mechanisms like + + - Event-oriented adaptation + - Cascaded adaptation + - Reverse adaptation + +which are explained in more detail below. + +The description is still under contruction but parts of the sub-menu and first howtos and API specifications are already available. +Browse the menu and see Section 'Cross reference' for further details. + + +**Learn more** + +.. toctree:: + :maxdepth: 3 + :glob: + + streams/* + + +**Cross reference** + - :ref:`Howtos MPro-OA ` + - :ref:`API reference: MLPro-OA-Streams ` + - :ref:`API reference: MLPro-OA-Streams - Pool of objects ` + - :ref:`Basics of data stream processing in MLPro ` \ No newline at end of file diff --git a/doc/rtd/content/03_machine_learning/mlpro_oa/sub/01_overview.rst b/doc/rtd/content/03_machine_learning/mlpro_oa/sub/01_overview.rst deleted file mode 100644 index 5d5a4e930..000000000 --- a/doc/rtd/content/03_machine_learning/mlpro_oa/sub/01_overview.rst +++ /dev/null @@ -1,5 +0,0 @@ -.. _target_oa_overview: -Overview -======== - -Further descriptions coming soon... \ No newline at end of file diff --git a/doc/rtd/content/03_machine_learning/mlpro_oa/sub/02_getstarted.rst b/doc/rtd/content/03_machine_learning/mlpro_oa/sub/02_getstarted.rst deleted file mode 100644 index d164b5365..000000000 --- a/doc/rtd/content/03_machine_learning/mlpro_oa/sub/02_getstarted.rst +++ /dev/null @@ -1,6 +0,0 @@ -.. _target_oa_getstarted: -Getting Started -=============== - -Further descriptions coming soon... - diff --git a/doc/rtd/content/03_machine_learning/mlpro_oa/sub/03_oa_stream_processing.rst b/doc/rtd/content/03_machine_learning/mlpro_oa/sub/03_oa_stream_processing.rst deleted file mode 100644 index 28d62550d..000000000 --- a/doc/rtd/content/03_machine_learning/mlpro_oa/sub/03_oa_stream_processing.rst +++ /dev/null @@ -1,21 +0,0 @@ -.. _target_oa_streams: -Online Adaptive Stream Processing -================================= - -Description under contruction. Please consider the cross reference for first technical information. - - -**Learn more** - -.. toctree:: - :maxdepth: 3 - :glob: - - layer0_oa_stream_processing/* - - -**Cross Reference** - - :ref:`Howtos MPro-OA ` - - :ref:`API Reference: MLPro-OA ` - - :ref:`API Reference: MLPro-OA Pool of Objects ` - - :ref:`Basics of stream processing in MLPro ` \ No newline at end of file diff --git a/doc/rtd/content/03_machine_learning/mlpro_oa/sub/04_oa_systems.rst.off b/doc/rtd/content/03_machine_learning/mlpro_oa/sub/03_oa_systems.rst.off similarity index 54% rename from doc/rtd/content/03_machine_learning/mlpro_oa/sub/04_oa_systems.rst.off rename to doc/rtd/content/03_machine_learning/mlpro_oa/sub/03_oa_systems.rst.off index 6deb29d73..3838ed72c 100644 --- a/doc/rtd/content/03_machine_learning/mlpro_oa/sub/04_oa_systems.rst.off +++ b/doc/rtd/content/03_machine_learning/mlpro_oa/sub/03_oa_systems.rst.off @@ -1,6 +1,6 @@ .. _target_oa_systems: -Online Adaptive Systems -======================= +Online-adaptive state-based systems +=================================== Further descriptions coming soon... @@ -8,4 +8,4 @@ Further descriptions coming soon... :maxdepth: 2 :glob: - layer1_oa_systems/* \ No newline at end of file + systems/* \ No newline at end of file diff --git a/doc/rtd/content/03_machine_learning/mlpro_oa/sub/layer0_oa_stream_processing/01_overview.rst b/doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/01_overview.rst similarity index 100% rename from doc/rtd/content/03_machine_learning/mlpro_oa/sub/layer0_oa_stream_processing/01_overview.rst rename to doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/01_overview.rst diff --git a/doc/rtd/content/03_machine_learning/mlpro_oa/sub/layer0_oa_stream_processing/01_overview/01_oa_stream_task.rst b/doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/01_overview/01_oa_stream_task.rst similarity index 68% rename from doc/rtd/content/03_machine_learning/mlpro_oa/sub/layer0_oa_stream_processing/01_overview/01_oa_stream_task.rst rename to doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/01_overview/01_oa_stream_task.rst index 915658a36..b11b06036 100644 --- a/doc/rtd/content/03_machine_learning/mlpro_oa/sub/layer0_oa_stream_processing/01_overview/01_oa_stream_task.rst +++ b/doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/01_overview/01_oa_stream_task.rst @@ -1,5 +1,5 @@ .. _target_oa_stream_tasks: -Online Adaptive Stream Tasks +Online-adaptive stream tasks ============================ ... diff --git a/doc/rtd/content/03_machine_learning/mlpro_oa/sub/layer0_oa_stream_processing/01_overview/02_oa_stream_workflow.rst b/doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/01_overview/02_oa_stream_workflow.rst similarity index 68% rename from doc/rtd/content/03_machine_learning/mlpro_oa/sub/layer0_oa_stream_processing/01_overview/02_oa_stream_workflow.rst rename to doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/01_overview/02_oa_stream_workflow.rst index 15e56a1bf..19deb36af 100644 --- a/doc/rtd/content/03_machine_learning/mlpro_oa/sub/layer0_oa_stream_processing/01_overview/02_oa_stream_workflow.rst +++ b/doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/01_overview/02_oa_stream_workflow.rst @@ -1,5 +1,5 @@ .. _target_oa_stream_workflows: -Online Adaptive Stream Workflows +Online-adaptive stream workflows ================================ diff --git a/doc/rtd/content/03_machine_learning/mlpro_oa/sub/layer0_oa_stream_processing/02_oa_boundary_detector.rst b/doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/02_oa_boundary_detector.rst similarity index 87% rename from doc/rtd/content/03_machine_learning/mlpro_oa/sub/layer0_oa_stream_processing/02_oa_boundary_detector.rst rename to doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/02_oa_boundary_detector.rst index 301f3237c..a656d6d79 100644 --- a/doc/rtd/content/03_machine_learning/mlpro_oa/sub/layer0_oa_stream_processing/02_oa_boundary_detector.rst +++ b/doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/02_oa_boundary_detector.rst @@ -1,5 +1,5 @@ .. _target_oa_boundary_detector: -Boundary Detection +Boundary detection ================== Further descriptions coming soon... diff --git a/doc/rtd/content/03_machine_learning/mlpro_oa/sub/layer0_oa_stream_processing/03_oa_normalization.rst b/doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/03_oa_normalization.rst similarity index 100% rename from doc/rtd/content/03_machine_learning/mlpro_oa/sub/layer0_oa_stream_processing/03_oa_normalization.rst rename to doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/03_oa_normalization.rst diff --git a/doc/rtd/content/03_machine_learning/mlpro_oa/sub/layer0_oa_stream_processing/03_oa_normalization/01_oa_minmax.rst b/doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/03_oa_normalization/01_oa_minmax.rst similarity index 100% rename from doc/rtd/content/03_machine_learning/mlpro_oa/sub/layer0_oa_stream_processing/03_oa_normalization/01_oa_minmax.rst rename to doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/03_oa_normalization/01_oa_minmax.rst diff --git a/doc/rtd/content/03_machine_learning/mlpro_oa/sub/layer0_oa_stream_processing/03_oa_normalization/02_oa_zscaling.rst b/doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/03_oa_normalization/02_oa_zscaling.rst similarity index 100% rename from doc/rtd/content/03_machine_learning/mlpro_oa/sub/layer0_oa_stream_processing/03_oa_normalization/02_oa_zscaling.rst rename to doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/03_oa_normalization/02_oa_zscaling.rst diff --git a/doc/rtd/content/03_machine_learning/mlpro_oa/sub/layer0_oa_stream_processing/10_cluster_analysis.rst b/doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/10_cluster_analysis.rst similarity index 93% rename from doc/rtd/content/03_machine_learning/mlpro_oa/sub/layer0_oa_stream_processing/10_cluster_analysis.rst rename to doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/10_cluster_analysis.rst index ec1059338..16fa57439 100644 --- a/doc/rtd/content/03_machine_learning/mlpro_oa/sub/layer0_oa_stream_processing/10_cluster_analysis.rst +++ b/doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/10_cluster_analysis.rst @@ -1,5 +1,5 @@ .. _target_oa_cluster_analyzer: -Cluster Analysis +Cluster analysis ================ Further descriptions coming soon... diff --git a/doc/rtd/content/03_machine_learning/mlpro_oa/sub/layer0_oa_stream_processing/10_cluster_analysis/.gitkeep b/doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/10_cluster_analysis/.gitkeep similarity index 100% rename from doc/rtd/content/03_machine_learning/mlpro_oa/sub/layer0_oa_stream_processing/10_cluster_analysis/.gitkeep rename to doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/10_cluster_analysis/.gitkeep diff --git a/doc/rtd/content/03_machine_learning/mlpro_oa/sub/layer0_oa_stream_processing/20_anomaly_detection.rst b/doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/20_anomaly_detection.rst similarity index 97% rename from doc/rtd/content/03_machine_learning/mlpro_oa/sub/layer0_oa_stream_processing/20_anomaly_detection.rst rename to doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/20_anomaly_detection.rst index 8acdea62a..a36222a11 100644 --- a/doc/rtd/content/03_machine_learning/mlpro_oa/sub/layer0_oa_stream_processing/20_anomaly_detection.rst +++ b/doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/20_anomaly_detection.rst @@ -1,19 +1,19 @@ .. _target_oa_anomaly_detection: -Anomaly Detection +Anomaly detection ================= Anomaly detection involves identifying instances that are structurally or dimensionally similar to non-anomalous data but deviate significantly from the normal data distribution or pattern. In real-world problems, anomaly detection helps uncover unusual activities in banking and finance, abnormalities in medical test results, uncommon behavior or sensor readings of machines, defective products in manufacturing lines, or malicious activities in network traffic monitoring. Detecting and analyzing these instances or behaviors is crucial for taking immediate action, preventing future occurrences of undesirable events, and ensuring data quality. Moreover, anomaly detection plays a pivotal role in making unbiased and accurate decisions across various domains. Anomaly detection techniques can be broadly classified into two categories based on the under- lying principles and methodologies. The two categories are Statistical anomaly detectors and Machine Learning anomaly detectors. -**Types of Anomalies** +**Types of anomalies** There are three main types of anomalies- Point anomalies, Contextual anomalies and Collective anomalies. (a) Point Anomalies : Type I anomalies or point anomalies are individual data instances that are significantly different from the rest of the dataset. Also known as global anomalies, these do not fit the normal distribution or pattern of the dataset. (b) Contextual Anomalies : Type II anomalies or contextual anomalies are data instances that are anomalies only in a particular context or subset of the dataset. Also known as conditional anomalies, these are not necessarily anomalies in the context of the whole dataset but anomalous within a specific context or condition. (c) Group Anomalies : Type III anomalies or group anomalies or collective anomalies are anomalous data instances when taken as a group or subset of the dataset. They may or may not be anomalies when considered individually. Also known as group anomalies, these occur when there is a deviation or unexpected relationship or behaviour among a group of data instances from the normal distribution of data. -**Classification of Anomaly Detectors** +**Classification of anomaly detectors** Anomaly detection techniques can be broadly classified into two categories based on the under- lying principles and methodologies. The two categories are Statistical anomaly detectors and Machine Learning anomaly detectors. (a) Statistical Anomaly Detectors : Statistical anomaly detectors use statistical methods to find data point deviations from the normal distribution. Common algorithms for this category of anomaly detectors are Z-score, Kernel Density Estimate, and Gaussian Mixture Models (GMM). @@ -29,7 +29,7 @@ Anomaly detection techniques can be broadly classified into two categories based 20_anomaly_detection/* -**Cross Reference** +**Cross reference** - Selected open access papers - Howtos diff --git a/doc/rtd/content/03_machine_learning/mlpro_oa/sub/layer0_oa_stream_processing/20_anomaly_detection/01_cbad.rst b/doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/20_anomaly_detection/01_cbad.rst similarity index 90% rename from doc/rtd/content/03_machine_learning/mlpro_oa/sub/layer0_oa_stream_processing/20_anomaly_detection/01_cbad.rst rename to doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/20_anomaly_detection/01_cbad.rst index df676878b..e8db463eb 100644 --- a/doc/rtd/content/03_machine_learning/mlpro_oa/sub/layer0_oa_stream_processing/20_anomaly_detection/01_cbad.rst +++ b/doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/20_anomaly_detection/01_cbad.rst @@ -1,5 +1,5 @@ .. _target_oa_cbad: -Cluster-based Anomaly Detection +Cluster-based anomaly detection =============================== Cluster-based anomaly detection uses clustering algorithms to form clustered data and identify anomolous behaviours of these clusters, which are flagged as anomalies. @@ -18,7 +18,8 @@ Can uncover contextual anomalies (data points that are anomalous in one cluster Can identify global anomalies (points far from all clusters) and local anomalies (outliers within a cluster). Scalability with various clustering algorithms, such as k-means for simpler scenarios or DBSCAN for non-spherical and dense data distributions. -**New Types of Anomalies** + +**New types of anomalies** Cluster-based methods introduce nuanced anomaly categorizations: @@ -28,9 +29,10 @@ Scalability with various clustering algorithms, such as k-means for simpler scen (c) Cluster Structural Anomalies: Unusual clusters themselves, such as unexpected densities, shapes, or sizes, signaling broader irregularities. -**Special Dependencies on Cluster Algorithms** - Cluster-based anomaly detection heavily depends on the choice of clustering algorithm, as it directly impacts the detection process: +**Special dependencies on cluster algorithms** + +Cluster-based anomaly detection heavily depends on the choice of clustering algorithm, as it directly impacts the detection process: k-means: Effective for spherical clusters but may miss anomalies in datasets with non-convex shapes or varying densities. DBSCAN: Ideal for discovering density-based anomalies but sensitive to hyperparameter tuning (e.g., minPts, ε). @@ -39,7 +41,8 @@ Gaussian Mixture Models (GMM): Handles soft clustering and detects probabilistic Spectral Clustering: Good for identifying anomalies in non-linear manifolds but computationally intensive for large datasets. Effective anomaly detection requires understanding the clustering algorithm’s limitations and ensuring it aligns with the data characteristics and problem context. -**Cross Reference** + +**Cross reference** - Howtos - API diff --git a/doc/rtd/content/03_machine_learning/mlpro_oa/sub/layer0_oa_stream_processing/30_anomaly_prediction.rst b/doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/21_anomaly_prediction.rst.off similarity index 76% rename from doc/rtd/content/03_machine_learning/mlpro_oa/sub/layer0_oa_stream_processing/30_anomaly_prediction.rst rename to doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/21_anomaly_prediction.rst.off index 273e957f2..422188a1d 100644 --- a/doc/rtd/content/03_machine_learning/mlpro_oa/sub/layer0_oa_stream_processing/30_anomaly_prediction.rst +++ b/doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/21_anomaly_prediction.rst.off @@ -1,5 +1,5 @@ .. _target_oa_anomaly_prediction: -Anomaly Prediction +Anomaly prediction ================== Further descriptions coming soon... @@ -11,10 +11,10 @@ Further descriptions coming soon... :maxdepth: 2 :glob: - 20_anomaly_prediction/* + 21_anomaly_prediction/* -**Cross Reference** +**Cross reference** - Selected open access papers - Howtos diff --git a/doc/rtd/content/03_machine_learning/mlpro_oa/sub/layer0_oa_stream_processing/30_anomaly_prediction/.gitkeep b/doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/21_anomaly_prediction/.gitkeep similarity index 100% rename from doc/rtd/content/03_machine_learning/mlpro_oa/sub/layer0_oa_stream_processing/30_anomaly_prediction/.gitkeep rename to doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/21_anomaly_prediction/.gitkeep diff --git a/doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/30_drift_detection.rst b/doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/30_drift_detection.rst new file mode 100644 index 000000000..23d9a7c4c --- /dev/null +++ b/doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/30_drift_detection.rst @@ -0,0 +1,21 @@ +.. _target_oa_drift_detection: +Drift detection +=============== + +Further descriptions coming soon... + + +**Learn more** + +.. toctree:: + :maxdepth: 2 + :glob: + + 30_drift_detection/* + + +**Cross reference** + +- Selected open access papers +- Howtos +- API diff --git a/doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/30_drift_detection/01_cbdd.rst b/doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/30_drift_detection/01_cbdd.rst new file mode 100644 index 000000000..81e8efda7 --- /dev/null +++ b/doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/30_drift_detection/01_cbdd.rst @@ -0,0 +1,21 @@ +.. _target_oa_cbdd: +Cluster-based drift detection +============================= + +Further descriptions coming soon... + + +**New types of drift** + +... + + +**Special dependencies on cluster algorithms** + +... + + +**Cross reference** + +- Howtos +- API diff --git a/doc/rtd/content/03_machine_learning/mlpro_oa/sub/layer1_oa_systems/.gitkeep b/doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/31_drift_prediction/.gitkeep similarity index 100% rename from doc/rtd/content/03_machine_learning/mlpro_oa/sub/layer1_oa_systems/.gitkeep rename to doc/rtd/content/03_machine_learning/mlpro_oa/sub/streams/31_drift_prediction/.gitkeep diff --git a/doc/rtd/content/03_machine_learning/mlpro_oa/sub/systems/.gitkeep b/doc/rtd/content/03_machine_learning/mlpro_oa/sub/systems/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/doc/rtd/content/99_appendices/appendix1/sub/mlpro_oa/01_streams.rst b/doc/rtd/content/99_appendices/appendix1/sub/mlpro_oa/01_streams.rst index ec0513982..376f34a3a 100644 --- a/doc/rtd/content/99_appendices/appendix1/sub/mlpro_oa/01_streams.rst +++ b/doc/rtd/content/99_appendices/appendix1/sub/mlpro_oa/01_streams.rst @@ -1,8 +1,8 @@ -Online Adaptive Stream Processing -================================= +Online-adaptive data stream processing +====================================== .. toctree:: :maxdepth: 1 :glob: - oa_dsp/* + streams/* diff --git a/doc/rtd/content/99_appendices/appendix1/sub/mlpro_oa/streams/howto_oa_pp_009.rst b/doc/rtd/content/99_appendices/appendix1/sub/mlpro_oa/streams/howto_oa_pp_009.rst deleted file mode 100644 index fd5588ec5..000000000 --- a/doc/rtd/content/99_appendices/appendix1/sub/mlpro_oa/streams/howto_oa_pp_009.rst +++ /dev/null @@ -1,26 +0,0 @@ -.. _Howto_OA_PP_009: -Howto OA-PP-009: Complex Preprocessing with Parallel Tasks -========================================================== - - -**Executable code** - -.. literalinclude:: ../../../../../../../../test/howtos/oa/howto_oa_pp_009_complex_preprocessing.py - :language: python - - - -**Results** - -After starting the Howto, the Workflow and Tasks windows appear. These can now be arranged on -the screen before the actual processing is started with a keystroke... - -.. image:: - images/howto_oa_pp_009.gif - :width: 700px - - - -**Cross Reference** - -- :ref:`API Reference - Online Adaptive Stream Processing ` diff --git a/doc/rtd/content/99_appendices/appendix1/sub/mlpro_oa/streams/howto_oa_pp_121.rst b/doc/rtd/content/99_appendices/appendix1/sub/mlpro_oa/streams/howto_oa_pp_121.rst new file mode 100644 index 000000000..07617824d --- /dev/null +++ b/doc/rtd/content/99_appendices/appendix1/sub/mlpro_oa/streams/howto_oa_pp_121.rst @@ -0,0 +1,26 @@ +.. _Howto_OA_PP_121: +Howto OA-PP-121: Complex preprocessing with parallel tasks +========================================================== + + +**Executable code** + +.. literalinclude:: ../../../../../../../../test/howtos/oa/streams/hybrid/howto_oa_streams_pp_121_complex_preprocessing.py + :language: python + + + +**Results** + +After starting the Howto, the Workflow and Tasks windows appear. These can now be arranged on +the screen before the actual processing is started with a keystroke... + +.. image:: + images/howto_oa_pp_121.gif + :width: 700px + + + +**Cross reference** + +- :ref:`API Reference - Online-adaptive data stream processing ` diff --git a/doc/rtd/content/99_appendices/appendix1/sub/mlpro_oa/streams/images/howto_oa_pp_009.gif b/doc/rtd/content/99_appendices/appendix1/sub/mlpro_oa/streams/images/howto_oa_pp_121.gif similarity index 100% rename from doc/rtd/content/99_appendices/appendix1/sub/mlpro_oa/streams/images/howto_oa_pp_009.gif rename to doc/rtd/content/99_appendices/appendix1/sub/mlpro_oa/streams/images/howto_oa_pp_121.gif diff --git a/doc/rtd/content/99_appendices/appendix2/sub/core/mlpro_oa/01_streams.rst b/doc/rtd/content/99_appendices/appendix2/sub/core/mlpro_oa/01_streams.rst index 0feed5d49..1a1e80460 100644 --- a/doc/rtd/content/99_appendices/appendix2/sub/core/mlpro_oa/01_streams.rst +++ b/doc/rtd/content/99_appendices/appendix2/sub/core/mlpro_oa/01_streams.rst @@ -1,6 +1,6 @@ .. _target_api_oa_streams: -OA Stream Processing -==================== +Online-adaptive data stream processing +====================================== .. image:: streams/images/MLPro-OA-Stream-Processing_class_diagram.drawio.png :scale: 50% diff --git a/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/10_streams.rst b/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/10_streams.rst index cfee65612..e501c8832 100644 --- a/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/10_streams.rst +++ b/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/10_streams.rst @@ -1,6 +1,6 @@ .. _target_api_pool_oa_streams: -OA Stream Processing -==================== +Online-adaptive data stream processing +====================================== .. toctree:: :maxdepth: 2 diff --git a/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/20_systems.rst b/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/20_systems.rst.off similarity index 100% rename from doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/20_systems.rst rename to doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/20_systems.rst.off diff --git a/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/01_stream_tasks.rst b/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/01_stream_tasks.rst index fd9c2ab0b..050f59448 100644 --- a/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/01_stream_tasks.rst +++ b/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/01_stream_tasks.rst @@ -1,6 +1,6 @@ .. _target_api_oa_streams_tasks: -OA Stream Tasks -=============== +Online-adaptive stream tasks +============================ .. toctree:: :maxdepth: 2 diff --git a/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/01_preprocessing_tasks.rst b/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/10_preprocessing_tasks.rst similarity index 90% rename from doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/01_preprocessing_tasks.rst rename to doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/10_preprocessing_tasks.rst index 959b5f3c1..8638031f1 100644 --- a/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/01_preprocessing_tasks.rst +++ b/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/10_preprocessing_tasks.rst @@ -1,12 +1,12 @@ .. _target_api_oa_stream_tasks_prepro: -OA Data Preprocessing -===================== +Preprocessing +============= .. image:: images/MLPro-OA-Preprocessing-Tasks_class_diagram.drawio.png :scale: 50% -Boundary Detector +Boundary detector ----------------- .. automodule:: mlpro.oa.streams.tasks.boundarydetectors diff --git a/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/02_cluster_analyzers.rst b/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/20_cluster_analyzers.rst similarity index 93% rename from doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/02_cluster_analyzers.rst rename to doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/20_cluster_analyzers.rst index 13c65ec5e..7a5a73b58 100644 --- a/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/02_cluster_analyzers.rst +++ b/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/20_cluster_analyzers.rst @@ -1,12 +1,12 @@ .. _target_api_oa_stream_tasks_clu: -Cluster Analysis +Cluster analyzer ================ .. image:: images/MLPro-OA-Cluster_Analyzers_class_diagram.drawio.png :scale: 50% -Template for Cluster Algorithms +Template for cluster algorithms ------------------------------- .. automodule:: mlpro.oa.streams.tasks.clusteranalyzers.basics diff --git a/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/03_anomaly_detectors.rst b/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/30_anomaly_detectors.rst similarity index 97% rename from doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/03_anomaly_detectors.rst rename to doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/30_anomaly_detectors.rst index bd4d77d36..79e2bc780 100644 --- a/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/03_anomaly_detectors.rst +++ b/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/30_anomaly_detectors.rst @@ -1,5 +1,5 @@ .. _target_api_oa_stream_tasks_ad: -Anomaly Detectors +Anomaly detectors ================= .. image:: anomaly_detectors/images/MLPro-OA-Anomaly-Detectors_class_diagram.drawio.png diff --git a/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/04_anomaly_predictors.rst b/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/31_anomaly_predictors.rst.off similarity index 78% rename from doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/04_anomaly_predictors.rst rename to doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/31_anomaly_predictors.rst.off index d4c847a1a..0ce038b8b 100644 --- a/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/04_anomaly_predictors.rst +++ b/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/31_anomaly_predictors.rst.off @@ -1,5 +1,5 @@ .. _target_api_oa_stream_tasks_ap: -Anomaly Predictors +Anomaly predictors ================== In progress... diff --git a/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/40_drift_detectors.rst b/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/40_drift_detectors.rst new file mode 100644 index 000000000..227bbaec4 --- /dev/null +++ b/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/40_drift_detectors.rst @@ -0,0 +1,36 @@ +.. _target_api_oa_stream_tasks_dd: +Drift detectors +=============== + +.. image:: drift_detectors/images/MLPro-OA-Drift-Detectors_class_diagram.drawio.png + :scale: 50% + + +Template for drift detectors +---------------------------- + +.. automodule:: mlpro.oa.streams.tasks.driftdetectors.basics + :members: + :undoc-members: + :private-members: + :show-inheritance: + + +Template for drift events +------------------------- + +.. automodule:: mlpro.oa.streams.tasks.driftdetectors.drift.basics + :members: + :undoc-members: + :private-members: + :show-inheritance: + + +Concrete drift events and algorithms +------------------------------------ + +.. toctree:: + :maxdepth: 2 + :glob: + + drift_detectors/* diff --git a/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/drift_detectors/10_common_drifts.rst b/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/drift_detectors/10_common_drifts.rst new file mode 100644 index 000000000..dcb3085f4 --- /dev/null +++ b/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/drift_detectors/10_common_drifts.rst @@ -0,0 +1,10 @@ +.. _target_api_oa_stream_tasks_ad_common_drifts: +Common drifts +============= + + +.. toctree:: + :maxdepth: 2 + :glob: + + common_drifts/* \ No newline at end of file diff --git a/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/drift_detectors/20_common_algorithms.rst b/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/drift_detectors/20_common_algorithms.rst new file mode 100644 index 000000000..ae5e1efb6 --- /dev/null +++ b/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/drift_detectors/20_common_algorithms.rst @@ -0,0 +1,10 @@ +.. _target_api_oa_stream_tasks_ad_common_algorithms: +Common algorithms +================= + + +.. toctree:: + :maxdepth: 2 + :glob: + + common_algorithms/* \ No newline at end of file diff --git a/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/drift_detectors/30_cluster_based.rst b/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/drift_detectors/30_cluster_based.rst new file mode 100644 index 000000000..30d1b7a43 --- /dev/null +++ b/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/drift_detectors/30_cluster_based.rst @@ -0,0 +1,14 @@ +.. _target_api_oa_stream_tasks_ad_cb: +Cluster-based drifts and detectors +===================================== + + +.. image:: cluster_based/images/MLPro-OA-CB-Drift-Detectors_class_diagram.drawio.png + :scale: 50% + + +.. toctree:: + :maxdepth: 2 + :glob: + + cluster_based/* \ No newline at end of file diff --git a/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/drift_detectors/cluster_based/images/.$MLPro-OA-CB-Drift-Detectors_class_diagram.drawio.dtmp b/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/drift_detectors/cluster_based/images/.$MLPro-OA-CB-Drift-Detectors_class_diagram.drawio.dtmp new file mode 100644 index 000000000..9249c1e80 --- /dev/null +++ b/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/drift_detectors/cluster_based/images/.$MLPro-OA-CB-Drift-Detectors_class_diagram.drawio.dtmp @@ -0,0 +1,229 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/drift_detectors/cluster_based/images/MLPro-OA-CB-Drift-Detectors_class_diagram.drawio b/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/drift_detectors/cluster_based/images/MLPro-OA-CB-Drift-Detectors_class_diagram.drawio new file mode 100644 index 000000000..3e94fcfa5 --- /dev/null +++ b/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/drift_detectors/cluster_based/images/MLPro-OA-CB-Drift-Detectors_class_diagram.drawio @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/drift_detectors/images/.$MLPro-OA-Drift-Detectors_class_diagram.drawio.bkp b/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/drift_detectors/images/.$MLPro-OA-Drift-Detectors_class_diagram.drawio.bkp new file mode 100644 index 000000000..3e94fcfa5 --- /dev/null +++ b/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/drift_detectors/images/.$MLPro-OA-Drift-Detectors_class_diagram.drawio.bkp @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/drift_detectors/images/MLPro-OA-Drift-Detectors_class_diagram-Page-1.drawio.png b/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/drift_detectors/images/MLPro-OA-Drift-Detectors_class_diagram-Page-1.drawio.png new file mode 100644 index 000000000..6ad9bdc5a Binary files /dev/null and b/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/drift_detectors/images/MLPro-OA-Drift-Detectors_class_diagram-Page-1.drawio.png differ diff --git a/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/drift_detectors/images/MLPro-OA-Drift-Detectors_class_diagram.drawio b/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/drift_detectors/images/MLPro-OA-Drift-Detectors_class_diagram.drawio new file mode 100644 index 000000000..3e94fcfa5 --- /dev/null +++ b/doc/rtd/content/99_appendices/appendix2/sub/pool/mlpro_oa/streams/tasks/drift_detectors/images/MLPro-OA-Drift-Detectors_class_diagram.drawio @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mlpro/oa/streams/tasks/anomalydetectors/anomalies/clusterbased/__init__.py b/src/mlpro/oa/streams/tasks/anomalydetectors/anomalies/clusterbased/__init__.py index 134079f20..b5e76cf4f 100644 --- a/src/mlpro/oa/streams/tasks/anomalydetectors/anomalies/clusterbased/__init__.py +++ b/src/mlpro/oa/streams/tasks/anomalydetectors/anomalies/clusterbased/__init__.py @@ -1,7 +1,6 @@ from mlpro.oa.streams.tasks.anomalydetectors.anomalies.clusterbased.basics import CBAnomaly from mlpro.oa.streams.tasks.anomalydetectors.anomalies.clusterbased.density import ClusterDensityVariation from mlpro.oa.streams.tasks.anomalydetectors.anomalies.clusterbased.disappearance import ClusterDisappearance -from mlpro.oa.streams.tasks.anomalydetectors.anomalies.clusterbased.drift import ClusterDrift from mlpro.oa.streams.tasks.anomalydetectors.anomalies.clusterbased.enlargement import ClusterEnlargement from mlpro.oa.streams.tasks.anomalydetectors.anomalies.clusterbased.shrinkage import ClusterShrinkage from mlpro.oa.streams.tasks.anomalydetectors.anomalies.clusterbased.new_cluster import NewClusterAppearance \ No newline at end of file diff --git a/src/mlpro/oa/streams/tasks/anomalydetectors/cb_detectors/__init__.py b/src/mlpro/oa/streams/tasks/anomalydetectors/cb_detectors/__init__.py index cc3af768a..bc88be69d 100644 --- a/src/mlpro/oa/streams/tasks/anomalydetectors/cb_detectors/__init__.py +++ b/src/mlpro/oa/streams/tasks/anomalydetectors/cb_detectors/__init__.py @@ -1,6 +1,5 @@ from mlpro.oa.streams.tasks.anomalydetectors.cb_detectors.basics import AnomalyDetectorCB from mlpro.oa.streams.tasks.anomalydetectors.cb_detectors.disappearance_detector import ClusterDisappearanceDetector -from mlpro.oa.streams.tasks.anomalydetectors.cb_detectors.drift_detector import ClusterDriftDetector from mlpro.oa.streams.tasks.anomalydetectors.cb_detectors.density_change_detector import ClusterDensityChangeDetector from mlpro.oa.streams.tasks.anomalydetectors.cb_detectors.geo_size_change_detector import ClusterGeometricSizeChangeDetector from mlpro.oa.streams.tasks.anomalydetectors.cb_detectors.new_cluster_detector import NewClusterDetector diff --git a/src/mlpro/oa/streams/tasks/driftdetectors/basics.py b/src/mlpro/oa/streams/tasks/driftdetectors/basics.py index 38bc9f0f1..7126782e1 100644 --- a/src/mlpro/oa/streams/tasks/driftdetectors/basics.py +++ b/src/mlpro/oa/streams/tasks/driftdetectors/basics.py @@ -31,8 +31,9 @@ class Figure : pass ## ------------------------------------------------------------------------------------------------- class DriftDetector (OAStreamTask): """ - Base class for online anomaly detectors. It raises an event when an - anomaly is detected. + Base class for online anomaly detectors. It raises an event whenever the beginning or the end + of a drift is detected. Please describe in child classes which event classes are used. Always + use the _raise_drift_event() method when raising an event. Parameters ---------- @@ -52,13 +53,9 @@ class DriftDetector (OAStreamTask): Further optional named parameters. """ - C_TYPE = 'Drift Detector' - - C_EVENT_DRIFT_ADDED = 'DRIFT_ADDED' - C_EVENT_DRIFT_REMOVED = 'DRIFT_REMOVED' - - C_PLOT_ACTIVE = True - C_PLOT_STANDALONE = False + C_TYPE = 'Drift Detector' + C_PLOT_ACTIVE = True + C_PLOT_STANDALONE = False ## ------------------------------------------------------------------------------------------------- def __init__( self, @@ -78,14 +75,23 @@ def __init__( self, p_logging = p_logging, **p_kwargs ) - self._drift_id = 0 - self._drifts = {} + self._drift_id = 0 + self._drifts = {} ## ------------------------------------------------------------------------------------------------- - def _run(self, p_inst : InstDict): - pass + def get_drifts(self): + """ + Method to return the current list of drifts. + + Returns + ------- + drifts : dict[Drift] + Current dictionary of drifts. + """ + return self._drifts + ## ------------------------------------------------------------------------------------------------- def _get_next_drift_id(self): @@ -101,20 +107,6 @@ def _get_next_drift_id(self): return self._drift_id -## ------------------------------------------------------------------------------------------------- - def get_drifts(self): - """ - Method to return the current list of drifts. - - Returns - ------- - drifts : dict[Drift] - Current dictionary of drifts. - """ - - return self._drifts - - ## ------------------------------------------------------------------------------------------------- def _buffer_drift(self, p_drift:Drift): """ @@ -137,7 +129,7 @@ def _buffer_drift(self, p_drift:Drift): ## ------------------------------------------------------------------------------------------------- - def remove_drift(self, p_drift:Drift): + def _remove_drift(self, p_drift:Drift): """ Method to remove an existing drift object. Please use as part of your algorithm. @@ -152,16 +144,12 @@ def remove_drift(self, p_drift:Drift): ## ------------------------------------------------------------------------------------------------- - def _raise_drift_event( self, - p_event_id : str, - p_drift : Drift ): + def _raise_drift_event( self, p_drift : Drift ): """ Specialized method to raise drift events. Parameters ---------- - p_event_id : str - Event id. See class constants C_EVENT_DRIFT_ADDED/REMOVED. p_drift : Drift Drift event object to be raised. """ @@ -171,7 +159,7 @@ def _raise_drift_event( self, if self.get_visualization(): p_drift.init_plot( p_figure=self._figure, p_plot_settings=self.get_plot_settings() ) - return super()._raise_event( p_event_id = p_event_id, p_event_object = p_drift ) + return super()._raise_event( p_event_id = p_drift.event_id, p_event_object = p_drift ) ## ------------------------------------------------------------------------------------------------- diff --git a/src/mlpro/oa/streams/tasks/driftdetectors/clusterbased/__init__.py b/src/mlpro/oa/streams/tasks/driftdetectors/clusterbased/__init__.py index c08a54cbc..a4f80c4ae 100644 --- a/src/mlpro/oa/streams/tasks/driftdetectors/clusterbased/__init__.py +++ b/src/mlpro/oa/streams/tasks/driftdetectors/clusterbased/__init__.py @@ -1 +1,2 @@ -from mlpro.oa.streams.tasks.driftdetectors.clusterbased.basics import DriftDetectorCB \ No newline at end of file +from mlpro.oa.streams.tasks.driftdetectors.clusterbased.basics import DriftDetectorCB +from mlpro.oa.streams.tasks.driftdetectors.clusterbased.movement import DriftDetectorCBMovement \ No newline at end of file diff --git a/src/mlpro/oa/streams/tasks/driftdetectors/clusterbased/basics.py b/src/mlpro/oa/streams/tasks/driftdetectors/clusterbased/basics.py index ed3036c8f..6f0dc275b 100644 --- a/src/mlpro/oa/streams/tasks/driftdetectors/clusterbased/basics.py +++ b/src/mlpro/oa/streams/tasks/driftdetectors/clusterbased/basics.py @@ -15,7 +15,7 @@ """ from mlpro.bf.various import Log -from mlpro.bf.math.properties import * +from mlpro.bf.math.properties import PropertyDefinitions from mlpro.oa.streams.basics import OAStreamTask from mlpro.oa.streams.tasks.driftdetectors.basics import DriftDetector @@ -65,15 +65,15 @@ def __init__( self, p_duplicate_data : bool = False, p_visualize : bool = False, p_logging=Log.C_LOG_ALL, - **p_kwargs): + **p_kwargs ): - super().__init__(p_name = p_name, - p_range_max = p_range_max, - p_ada = p_ada, - p_duplicate_data = p_duplicate_data, - p_visualize = p_visualize, - p_logging = p_logging, - **p_kwargs) + super().__init__( p_name = p_name, + p_range_max = p_range_max, + p_ada = p_ada, + p_duplicate_data = p_duplicate_data, + p_visualize = p_visualize, + p_logging = p_logging, + **p_kwargs ) self._clusterer = p_clusterer unknown_prop = self._clusterer.align_cluster_properties(p_properties=self.C_REQ_CLUSTER_PROPERTIES) diff --git a/src/mlpro/oa/streams/tasks/driftdetectors/clusterbased/drift_detector.py b/src/mlpro/oa/streams/tasks/driftdetectors/clusterbased/movement.py similarity index 72% rename from src/mlpro/oa/streams/tasks/driftdetectors/clusterbased/drift_detector.py rename to src/mlpro/oa/streams/tasks/driftdetectors/clusterbased/movement.py index b88be9f5f..a25c363ec 100644 --- a/src/mlpro/oa/streams/tasks/driftdetectors/clusterbased/drift_detector.py +++ b/src/mlpro/oa/streams/tasks/driftdetectors/clusterbased/movement.py @@ -1,7 +1,7 @@ ## -- ---------------------------------------------------------------------------------------------- ## -- Project : MLPro - The integrative middleware framework for standardized machine learning ## -- Package : mlpro.oa.tasks.driftdetectors.clusterbased -## -- Module : drift_detector.py +## -- Module : movement.py ## ------------------------------------------------------------------------------------------------- ## -- History : ## -- yyyy-mm-dd Ver. Auth. Description @@ -9,23 +9,26 @@ ## -- 2023-09-12 1.0.0 SK Release ## -- 2024-04-10 1.1.0 DA/SK Refactoring ## -- 2024-05-28 1.2.0 SK Refactoring -## -- 2025-02-12 2.0.0 DA Relocation and refactoring +## -- 2025-02-12 2.0.0 DA Relocation, refactoring, renaming ## ------------------------------------------------------------------------------------------------- """ Ver. 2.0.0 (2025-02-12) -This module provides a cluster-based drift detector algorithm. +This module provides a cluster-based drift detector algorithm determining cluster movement. """ import time -from mlpro.oa.streams.basics import * -from mlpro.oa.streams.tasks.anomalydetectors.cb_detectors.basics import AnomalyDetectorCB -from mlpro.oa.streams.tasks.anomalydetectors.anomalies.clusterbased.drifts import ClusterDrift -from mlpro.oa.streams.tasks.clusteranalyzers.basics import ClusterAnalyzer -from mlpro.bf.streams import Instance, InstDict + +from mlpro.bf.various import Log +from mlpro.bf.streams import InstDict +from mlpro.bf.streams.tasks import StreamTask from mlpro.bf.math.properties import * + +from mlpro.oa.streams.tasks.driftdetectors.clusterbased import DriftDetectorCB +from mlpro.oa.streams.tasks.driftdetectors.drifts.clusterbased import DriftCBMovement +from mlpro.oa.streams.tasks.clusteranalyzers.basics import ClusterAnalyzer from mlpro.oa.streams.tasks.clusteranalyzers.clusters.properties.centroid import cprop_centroid2 @@ -33,53 +36,81 @@ ## ------------------------------------------------------------------------------------------------- ## ------------------------------------------------------------------------------------------------- -class ClusterDriftDetector(AnomalyDetectorCB): +class DriftDetectorCBMovement (DriftDetectorCB): """ This is the class for detecting change in velocity of clusters. + Parameters + ---------- + p_clusterer : ClusterAnalyzer + Related cluster analyzer providing its clusters as the basis for drift detection + p_instantaneous_velocity_change_detection : bool = True + Boolean switch for instantaneous velocity change detection (Default: True) + p_min_velocity_threshold : float = 0.01 + Threshold for minimum velocity (Default: 0.01) + p_state_change_detection : bool = False + Boolean switch for state change detection (Default: False) + p_min_acceleration_threshold : float = None + Threshold for minimum acceleration (Default: None) + p_name : str + Optional name of the task. Default is None. + p_range_max : int + Maximum range of asynchonicity. See class Range. Default is Range.C_RANGE_PROCESS. + p_ada : bool + Boolean switch for adaptivitiy. Default = True. + p_duplicate_data : bool + If True, instances will be duplicated before processing. Default = False. + p_visualize : bool + Boolean switch for visualisation. Default = False. + p_logging + Log level (see constants of class Log). Default: Log.C_LOG_ALL + p_kwargs : dict + Further optional named parameters. + """ + + C_TYPE = 'Cluster-based Drift Detector (Movement)' C_PROPERTY_DEFINITIONS : PropertyDefinitions = [cprop_centroid2] ## ------------------------------------------------------------------------------------------------- - def __init__(self, - p_clusterer : ClusterAnalyzer = None, - p_instantaneous_velocity_change_detection : bool = True, - p_min_velocity_threshold : float = 0.01, - p_state_change_detection : bool = False, - p_min_acceleration_threshold : float = False, - p_buffer_size = 5, - p_ema_alpha : float = 0.7, - p_with_time_calculation : bool = True, - p_initial_skip : int = 1, - p_name:str = None, - p_range_max = StreamTask.C_RANGE_THREAD, - p_ada : bool = True, - p_duplicate_data : bool = False, - p_visualize : bool = False, - p_logging=Log.C_LOG_ALL, - **p_kwargs): - - super().__init__(p_clusterer = p_clusterer, - p_name = p_name, - p_range_max = p_range_max, - p_ada = p_ada, - p_duplicate_data = p_duplicate_data, - p_visualize = p_visualize, - p_logging = p_logging, - **p_kwargs) + def __init__( self, + p_clusterer : ClusterAnalyzer, + p_instantaneous_velocity_change_detection : bool = True, + p_min_velocity_threshold : float = 0.01, + p_state_change_detection : bool = False, + p_min_acceleration_threshold : float = None, + p_buffer_size = 5, + p_ema_alpha : float = 0.7, + p_with_time_calculation : bool = True, + p_initial_skip : int = 1, + p_name:str = None, + p_range_max = StreamTask.C_RANGE_THREAD, + p_ada : bool = True, + p_duplicate_data : bool = False, + p_visualize : bool = False, + p_logging=Log.C_LOG_ALL, + **p_kwargs ): + + super().__init__( p_clusterer = p_clusterer, + p_name = p_name, + p_range_max = p_range_max, + p_ada = p_ada, + p_duplicate_data = p_duplicate_data, + p_visualize = p_visualize, + p_logging = p_logging, + **p_kwargs ) # Parameters for dynamic threshold, EMA smoothing, and time-based calculation - self._inst_change_det = p_instantaneous_velocity_change_detection - self._state_change_det = p_state_change_detection - self._min_vel_thresh = p_min_velocity_threshold - self._min_acc_thresh = p_min_acceleration_threshold - self._buffer_size = p_buffer_size - self._ema_alpha = p_ema_alpha - self._with_time_calculation = p_with_time_calculation - self._init_skip = p_initial_skip - self._visualize = p_visualize - self._count = 0 - self._count_change = {} + self._inst_change_det : bool = p_instantaneous_velocity_change_detection + self._state_change_det : bool = p_state_change_detection + self._min_vel_thresh : float = p_min_velocity_threshold + self._min_acc_thresh : float = p_min_acceleration_threshold + self._buffer_size = p_buffer_size + self._ema_alpha = p_ema_alpha + self._with_time_calculation : bool = p_with_time_calculation + self._init_skip : int = p_initial_skip + self._count : int = 0 + self._count_change = {} # Data structures for storing previous states and buffers self._centroids_history = {} @@ -148,13 +179,14 @@ def _run(self, p_inst : InstDict): # Raise Anomaly event if (self._count >= self._init_skip): if len(drifting_clusters) != 0: - anomaly = ClusterDrift(p_id = self._get_next_anomaly_id, - p_instances=new_instances, - p_clusters=drifting_clusters, - p_properties=properties, - p_det_time=str(inst.get_tstamp()), - p_visualize=self._visualize) - self._raise_anomaly_event(anomaly) + drift = DriftCBMovement( p_drift_status = True, + p_id = self._get_next_drift_id(), + p_instances=new_instances, + p_clusters=drifting_clusters, + p_properties=properties, + p_det_time=str(inst.get_tstamp()), + p_visualize=self._visualize ) + self._raise_drift_event( p_drift = drift ) if self._count < self._init_skip: self._count += 1 diff --git a/src/mlpro/oa/streams/tasks/driftdetectors/drifts/basics.py b/src/mlpro/oa/streams/tasks/driftdetectors/drifts/basics.py index 340c033dc..43c56c383 100644 --- a/src/mlpro/oa/streams/tasks/driftdetectors/drifts/basics.py +++ b/src/mlpro/oa/streams/tasks/driftdetectors/drifts/basics.py @@ -5,11 +5,12 @@ ## ------------------------------------------------------------------------------------------------- ## -- History : ## -- yyyy-mm-dd Ver. Auth. Description -## -- 2025-02-12 1.0.0 DA Creation +## -- 2025-02-12 0.1.0 DA Creation +## -- 2025-02-13 0.2.0 DA Class Drift: new attributes event_id, drift_status ## ------------------------------------------------------------------------------------------------- """ -Ver. 1.0.0 (2025-02-12) +Ver. 0.2.0 (2025-02-13) This module provides a template class for types of data drift to be used in drift detection algorithms. """ @@ -22,17 +23,17 @@ - - ## ------------------------------------------------------------------------------------------------- ## ------------------------------------------------------------------------------------------------- class Drift (Id, Event, Plottable): """ - This is the base class for drift events which can be raised by the drift detectors when a - drift is detected. + This is the base class for drift events which can be raised by drift detectors when the beginning + or end of a drift is detected. Parameters ---------- + p_drift_status : bool + Determines whether a new drift starts (True) or an existing drift ends (False). p_id : int Drift ID. Default value = 0. p_tstamp : datetime @@ -43,20 +44,49 @@ class Drift (Id, Event, Plottable): Reference of the object raised. Default = None. **p_kwargs Further optional keyword arguments. + + Attributes + ---------- + event_id : str + Event id to be used when raising a drift event object. It is a string consisting of the + class name and one of the postfixes '(ON)', '(OFF)' depending on the drift status. """ - C_TYPE = 'Drift' - C_PLOT_STANDALONE = False + C_TYPE = 'Drift' + C_PLOT_STANDALONE = False ## ------------------------------------------------------------------------------------------------- - def __init__(self, - p_id : int = 0, - p_tstamp : datetime = None, - p_visualize : bool = False, - p_raising_object : object = None, - **p_kwargs): + def __init__( self, + p_drift_status : bool, + p_id : int = 0, + p_tstamp : datetime = None, + p_visualize : bool = False, + p_raising_object : object = None, + **p_kwargs): Id.__init__( self, p_id = p_id ) Event.__init__( self, p_raising_object=p_raising_object, p_tstamp=p_tstamp, **p_kwargs) Plottable.__init__( self, p_visualize = p_visualize ) + + self._drift_status : bool = p_drift_status + + if p_drift_status: + self._event_id = type(self).__name__ + '(ON)' + else: + self._event_id = type(self).__name__ + '(OFF)' + + +## ------------------------------------------------------------------------------------------------- + def _get_drift_status(self) -> bool: + return self._drift_status + + +## ------------------------------------------------------------------------------------------------- + def _get_event_id(self) -> str: + return self._event_id + + +## ------------------------------------------------------------------------------------------------- + drift_status = property( fget = _get_drift_status ) + event_id = property( fget = _get_event_id ) diff --git a/src/mlpro/oa/streams/tasks/driftdetectors/drifts/clusterbased/__init__.py b/src/mlpro/oa/streams/tasks/driftdetectors/drifts/clusterbased/__init__.py index 5a486ce5b..620733649 100644 --- a/src/mlpro/oa/streams/tasks/driftdetectors/drifts/clusterbased/__init__.py +++ b/src/mlpro/oa/streams/tasks/driftdetectors/drifts/clusterbased/__init__.py @@ -1 +1,2 @@ -from mlpro.oa.streams.tasks.driftdetectors.drifts.clusterbased.basics import CBDrift \ No newline at end of file +from mlpro.oa.streams.tasks.driftdetectors.drifts.clusterbased.basics import DriftCB +from mlpro.oa.streams.tasks.driftdetectors.drifts.clusterbased.movement import DriftCBMovement \ No newline at end of file diff --git a/src/mlpro/oa/streams/tasks/driftdetectors/drifts/clusterbased/basics.py b/src/mlpro/oa/streams/tasks/driftdetectors/drifts/clusterbased/basics.py index 440654589..ba43fc553 100644 --- a/src/mlpro/oa/streams/tasks/driftdetectors/drifts/clusterbased/basics.py +++ b/src/mlpro/oa/streams/tasks/driftdetectors/drifts/clusterbased/basics.py @@ -9,7 +9,7 @@ ## ------------------------------------------------------------------------------------------------- """ -Ver. 1.0.0 (2025-02-12) +Ver. 0.1.0 (2025-02-12) This module provides a template class for cluster-based drifts to be used in cluster-based drift detection algorithms. @@ -28,11 +28,9 @@ class Figure : pass - - ## ------------------------------------------------------------------------------------------------- ## ------------------------------------------------------------------------------------------------- -class CBDrift (Drift): +class DriftCB (Drift): """ Sub-type for cluster-based drift events. @@ -59,6 +57,7 @@ class CBDrift (Drift): ## ------------------------------------------------------------------------------------------------- def __init__(self, + p_drift_status : bool, p_id : int = 0, p_tstamp : datetime = None, p_visualize : bool = False, @@ -67,7 +66,8 @@ def __init__(self, p_properties : dict = None, **p_kwargs): - super().__init__( p_id = p_id, + super().__init__( p_drift_status = p_drift_status, + p_id = p_id, p_tstamp = p_tstamp, p_visualize = p_visualize, p_raising_object = p_raising_object, @@ -110,7 +110,10 @@ def _init_plot_2d(self, p_figure: Figure, p_settings: PlotSettings): cluster : Cluster = None for cluster in self._clusters.values(): - cluster.color = "red" + if self.drift_status: + cluster.color = "red" + else: + raise NotImplementedError ## ------------------------------------------------------------------------------------------------- @@ -120,7 +123,7 @@ def _init_plot_3d(self, p_figure: Figure, p_settings: PlotSettings): cluster : Cluster = None for cluster in self._clusters.values(): - cluster.color = "red" - - - + if self.drift_status: + cluster.color = "red" + else: + raise NotImplementedError diff --git a/src/mlpro/oa/streams/tasks/driftdetectors/drifts/clusterbased/movement.py b/src/mlpro/oa/streams/tasks/driftdetectors/drifts/clusterbased/movement.py new file mode 100644 index 000000000..7d1021b18 --- /dev/null +++ b/src/mlpro/oa/streams/tasks/driftdetectors/drifts/clusterbased/movement.py @@ -0,0 +1,30 @@ +## ------------------------------------------------------------------------------------------------- +## -- Project : MLPro - The integrative middleware framework for standardized machine learning +## -- Package : mlpro.oa.tasks.driftdetectors.drifts.clusterbased +## -- Module : movement.py +## ------------------------------------------------------------------------------------------------- +## -- History : +## -- yyyy-mm-dd Ver. Auth. Description +## -- 2025-02-13 1.0.0 DA Creation +## ------------------------------------------------------------------------------------------------- + +""" +Ver. 1.0.0 (2025-02-13) + +This module provides a sub-typ of class DriftCB related to cluster movement. +""" + +from mlpro.oa.streams.tasks.driftdetectors.drifts.clusterbased.basics import DriftCB + + + + +## ------------------------------------------------------------------------------------------------- +## ------------------------------------------------------------------------------------------------- +class DriftCBMovement (DriftCB): + """ + Sub-type indicating the begin or end of a cluster movement. + """ + + C_NAME = 'Cluster-based Drift (Movement)' + C_PLOT_ACTIVE = True \ No newline at end of file diff --git a/test/howtos/oa/howto_oa_streams_cbap_001_KMeans_ClusterDriftDetector_InstantaneousDetection_2d.py.off b/test/howtos/oa/howto_oa_streams_cbap_001_KMeans_ClusterDriftDetector_InstantaneousDetection_2d.py.off deleted file mode 100644 index 9dad40ce2..000000000 --- a/test/howtos/oa/howto_oa_streams_cbap_001_KMeans_ClusterDriftDetector_InstantaneousDetection_2d.py.off +++ /dev/null @@ -1,199 +0,0 @@ -## ------------------------------------------------------------------------------------------------- -## -- Project : MLPro - The integrative middleware framework for standardized machine learning -## -- Package : test.howtos.oa -## -- Module : howto_oa_streams_cbap_001_KMeans_ClusterDriftDetector_InstantaneousDetection_2d.py -## ------------------------------------------------------------------------------------------------- -## -- History : -## -- yyyy-mm-dd Ver. Auth. Description -## -- 2024-08-14 0.0.0 DA Copied from howto_oa_streams_cbad_001_KMeans_....py -## ------------------------------------------------------------------------------------------------- - -""" -Ver. 0.0.0 (2024-08-14) - -This module is done as a part of the Master's Thesis named Online Adaptive Cluster-based Anomaly -Detection, authored by Syamraj Purushamparambil Satheesh, as a part of the course -"Systems Engineering and Engineering Management" in the Department of "Electrical Energy Engineering", -supervised by Dipl.-Info. Detlef Arend. - - -This module demonstrates cluster-based anomlay detection, on synthetic 2-dimensional data generated by -the StreamMLProClusterGenerator, using the ClusterDriftDetector anomaly detection algorithm employing -the KMeans clustering algorithm wrapped from River library, to detect ClusterDrift anomaly. - -You will learn: - -1. Generating synthetic data using the native StreamMLProClusterGenerator. - -2. Creating a workflow and tasks in MLPro-OA. - -3. Clustering the normalized streaming data using the WrRiverKMeans2MLPro, with normalizer as a predecessor. - -4. Detecting drift anomalies in the clustered data using the ClusterDriftDetector. - -In the visualization, the cross hair designating the cluster's centroid becomes'red' in colour when -an anomaly is detected linked to that specific cluster. An overview of the anomalies is displayed on -the screen following the run. - -""" -from mlpro.bf.math import Event -from mlpro.bf.mt import Event -from mlpro.bf.streams.streams import * -from mlpro.bf.various import Log -from mlpro.oa.streams import * -from mlpro_int_river.wrappers.clusteranalyzers.kmeans import WrRiverKMeans2MLPro -from mlpro.oa.streams.tasks.anomalydetectors.cb_detectors.drift_detector import ClusterDriftDetector -from mlpro.oa.streams.tasks.anomalypredictors.tsf.ad_based import AnomalyPredictorAD - - - - -class DevindisPredictor (AnomalyPredictorAD): - - def _adapt_on_event(self, p_event_id: str, p_event_object: Event) -> bool: - - # Set breakpoint here... - pass - - - - -## ------------------------------------------------------------------------------------------------- -## ------------------------------------------------------------------------------------------------- -# 1 Prepare a scenario -class MyScenario(OAStreamScenario): - C_NAME = 'ClusterDriftScenario' - - def _setup(self, p_mode, p_ada: bool, p_visualize: bool, p_logging): - - # 1.1 Get MLPro benchmark Clutser Generator - stream = StreamMLProClusterGenerator(p_num_dim=2, - p_num_instances=5000, - p_num_clusters=3, - p_radii=[100], - p_velocities=[0.0], - p_change_velocities=True, - p_changed_velocities=[0.5, 0.6], - p_points_of_change_velocities=[1000, 1200], - p_num_clusters_for_change_velocities=2, - p_seed=12, - p_logging=p_logging) - - - # 1.2 Set up a stream workflow - - # 1.2.1 Creation of a workflow - workflow = OAStreamWorkflow( p_name='Anomaly Detection', - p_range_max=OAStreamWorkflow.C_RANGE_NONE, - p_ada=p_ada, - p_visualize=p_visualize, - p_logging=p_logging ) - - - # 1.2.2 Creation of tasks and add them to the workflow - - # Cluster Analyzer - task_clusterer = WrRiverKMeans2MLPro( p_name='#1: KMeans@River', - p_n_clusters=3, - p_halflife=0.05, - p_sigma=3, - p_seed=42, - p_visualize=p_visualize, - p_logging=p_logging ) - - workflow.add_task(p_task = task_clusterer) - - # Anomaly Detector - task_anomaly_detector = ClusterDriftDetector( p_clusterer=task_clusterer, - p_with_time_calculation=False, - p_instantaneous_velocity_change_detection=True, - p_min_velocity_threshold=1, - p_initial_skip=400, - p_visualize=p_visualize, - p_logging=p_logging ) - - workflow.add_task(p_task=task_anomaly_detector, p_pred_tasks=[task_clusterer]) - - # Anomaly Predictor - task_anomaly_predictor = DevindisPredictor( p_visualize=p_visualize, - p_logging=p_logging) - - task_anomaly_detector.register_event_handler( p_event_id = 'Anomaly', - p_event_handler = task_anomaly_predictor.adapt_on_event ) - - # 1.3 Return stream and workflow - return stream, workflow - - - -# 2 Prepare for test -if __name__ == "__main__": - cycle_limit = 2000 - logging = Log.C_LOG_ALL - visualize = True - step_rate = 1 -else: - cycle_limit = 5 - logging = Log.C_LOG_NOTHING - visualize = False - step_rate = 1 - - -# 3 Instantiate the stream scenario -myscenario = MyScenario( p_mode=Mode.C_MODE_SIM, - p_cycle_limit=cycle_limit, - p_visualize=visualize, - p_logging=logging ) - -# 4 Reset and run own stream scenario -myscenario.reset() - -if __name__ == "__main__": - myscenario.init_plot( p_plot_settings=PlotSettings( p_view = PlotSettings.C_VIEW_2D, - p_step_rate = step_rate ) ) - input('\nPlease arrange all windows and press ENTER to start stream processing...') - - - -tp_before = datetime.now() -myscenario.run() -tp_after = datetime.now() -tp_delta = tp_after - tp_before -duraction_sec = ( tp_delta.seconds * 1000000 + tp_delta.microseconds + 1 ) / 1000000 -myscenario.log(Log.C_LOG_TYPE_W, 'Duration [sec]:', round(duraction_sec,2), ', Cycles/sec:', round(cycle_limit/duraction_sec,2)) - - - -# 5 Summary -anomalies = myscenario.get_workflow()._tasks[1].get_anomalies() -detected_anomalies= len(anomalies) - -myscenario.log(Log.C_LOG_TYPE_W, '-------------------------------------------------------') -myscenario.log(Log.C_LOG_TYPE_W, '-------------------------------------------------------') -myscenario.log(Log.C_LOG_TYPE_W, 'Here is the recap of the anomaly detector') -myscenario.log(Log.C_LOG_TYPE_W, 'Number of anomalies: ', detected_anomalies ) - -for anomaly in anomalies.values(): - anomaly_name = anomaly.C_NAME - anomaly_id = str(anomaly.id) - clusters_affected = {} - clusters = anomaly.get_clusters() - properties = anomaly.get_properties() - for x in clusters.keys(): - clusters_affected[x] = {} - clusters_affected[x]["velocity"] = properties[x]["velocity"] - clusters_affected[x]["acceleration"] = properties[x]["acceleration"] - - - inst = anomaly.get_instances()[-1].get_id() - myscenario.log(Log.C_LOG_TYPE_W, - 'Anomaly : ', anomaly_name, - '\n Anomaly ID : ', anomaly_id, - '\n Instance ID : ', inst, - '\n Clusters : ', clusters_affected) - -myscenario.log(Log.C_LOG_TYPE_W, '-------------------------------------------------------') -myscenario.log(Log.C_LOG_TYPE_W, '-------------------------------------------------------') - -if __name__ == "__main__": - input('Press ENTER to exit...') \ No newline at end of file diff --git a/test/howtos/oa/howto_oa_streams_pp_105_rearranger_window_bd_normminmax_2d_3d_nD_multithreading.py.off b/test/howtos/oa/howto_oa_streams_pp_105_rearranger_window_bd_normminmax_2d_3d_nD_multithreading.py.off deleted file mode 100644 index 756c2b248..000000000 --- a/test/howtos/oa/howto_oa_streams_pp_105_rearranger_window_bd_normminmax_2d_3d_nD_multithreading.py.off +++ /dev/null @@ -1,261 +0,0 @@ -## ------------------------------------------------------------------------------------------------- -## -- Project : MLPro - The integrative middleware framework for standardized machine learning -## -- Package : mlpro.oa.examples -## -- Module : howto_oa_pp_007_rearranger_window_bd_normminmax_2d_3d_nD_multithreading.py -## ------------------------------------------------------------------------------------------------- -## -- History : -## -- yyyy-mm-dd Ver. Auth. Description -## -- 2023-01-09 1.0.0 DA Creation -## -- 2023-04-10 1.1.0 DA Refactoring after changes on class OAScenario -## -- 2023-05-20 1.1.1 DA Registered handler of boundary detector to window -## ------------------------------------------------------------------------------------------------- - -""" -Ver. 1.1.1 (2023-05-20) - -This module is an example of adaptive normalization of streaming data using MinMax normalizer. To -this regard, an online-adadptive custom scenario is set up. It combines a native 10-dimensional -sample stream with an online-adaptive workflow. The latter one consists of four tasks: a rearranger -to reduce the stream data to 3 dimensions, a window that buffers the last 50 instances, a boundary -detector and finally the MinMax normalizer. - -You will learn: - -1. How to set up online-adaptive custom stream scenarios. - -2. How to set up online-adaptive workflows reusing various adaptive/non-adaptive MLPro stream tasks - -3. How to run and visualize your own custom stream scenario. -""" - - - -from mlpro.bf.streams import * -from mlpro.bf.streams.streams import * -from mlpro.bf.streams.tasks import RingBuffer, Rearranger -from mlpro.oa.streams import * - - - -## ------------------------------------------------------------------------------------------------- -## ------------------------------------------------------------------------------------------------- -class MyAdaptiveScenario (OAScenario): - - C_NAME = 'Dummy' - -## ------------------------------------------------------------------------------------------------- - def _setup(self, p_mode, p_ada: bool, p_visualize: bool, p_logging): - - # 1 Prepare a native stream from MLPro - mlpro = StreamProviderMLPro(p_logging=p_logging) - stream = mlpro.get_stream( p_name=StreamMLProRnd10D.C_NAME, - p_mode=p_mode, - p_visualize=p_visualize, - p_logging=p_logging ) - - - # 2 Set up a stream workflow based on a custom stream task - - # 2.1 Creation of a workflow - workflow = OAWorkflow( p_name='wf', - p_range_max=OAWorkflow.C_RANGE_THREAD, - p_ada=p_ada, - p_visualize=p_visualize, - p_logging=p_logging ) - - - # 2.2 Creation of a task chain 2D - - # 2.2.1 Rearranger to reduce the number of features - features = stream.get_feature_space().get_dims() - features_new = [ ( 'F', features[1:3] ) ] - - task_rearranger = Rearranger( p_name='Chain 2D, Task T1', - p_duplicate_data=True, - p_range_max=Task.C_RANGE_THREAD, - p_visualize=p_visualize, - p_logging=p_logging, - p_features_new=features_new ) - - workflow.add_task( p_task=task_rearranger ) - - # 2.2.2 Window to buffer some data - task_window = RingBuffer( p_buffer_size=50, - p_delay=True, - p_enable_statistics=True, - p_name='Chain 2D, Task T2', - p_duplicate_data=True, - p_visualize=p_visualize, - p_logging=p_logging ) - - workflow.add_task(p_task=task_window, p_pred_tasks=[task_rearranger]) - - # 2.2.3 Boundary detector - task_bd = BoundaryDetector( p_name='Chain 2D, Task T3', - p_ada=True, - p_visualize=True, - p_logging=p_logging ) - - task_window.register_event_handler( p_event_id=RingBuffer.C_EVENT_DATA_REMOVED, p_event_handler=task_bd.adapt_on_event ) - workflow.add_task(p_task = task_bd, p_pred_tasks=[task_window]) - - # # 2.2.4 MinMax-Normalizer - task_norm_minmax = NormalizerMinMax( p_name='Chain 2D, Task T4', - p_ada=True, - p_visualize=p_visualize, - p_logging=p_logging ) - - task_bd.register_event_handler( p_event_id=BoundaryDetector.C_EVENT_ADAPTED, p_event_handler=task_norm_minmax.adapt_on_event ) - - workflow.add_task(p_task = task_norm_minmax, p_pred_tasks=[task_bd]) - - - # 2.3 Creation of a task chain 3D - - # 2.3.1 Rearranger to reduce the number of features - features = stream.get_feature_space().get_dims() - features_new = [ ( 'F', features[1:4] ) ] - - task_rearranger = Rearranger( p_name='Chain 3D, Task T1', - p_range_max=Task.C_RANGE_THREAD, - p_duplicate_data=True, - p_visualize=p_visualize, - p_logging=p_logging, - p_features_new=features_new ) - - workflow.add_task( p_task=task_rearranger ) - - # 2.3.2 Window to buffer some data - task_window = Window( p_buffer_size=50, - p_delay=True, - p_enable_statistics=True, - p_name='Chain 3D, Task T2', - p_duplicate_data=True, - p_visualize=p_visualize, - p_logging=p_logging ) - - workflow.add_task(p_task=task_window, p_pred_tasks=[task_rearranger]) - - # 2.3.3 Boundary detector - task_bd = BoundaryDetector( p_name='Chain 3D, Task T3', - p_ada=True, - p_visualize=True, - p_logging=p_logging, - p_window=task_window ) - - workflow.add_task(p_task = task_bd, p_pred_tasks=[task_window]) - - # # 2.3.4 MinMax-Normalizer - task_norm_minmax = NormalizerMinMax( p_name='Chain 3D, Task T4', - p_ada=True, - p_visualize=p_visualize, - p_logging=p_logging ) - - task_bd.register_event_handler( p_event_id=BoundaryDetector.C_EVENT_ADAPTED, p_event_handler=task_norm_minmax.adapt_on_event ) - - workflow.add_task(p_task = task_norm_minmax, p_pred_tasks=[task_bd]) - - - - # 2.5 Creation of a task chain nD - - # 2.5.1 Rearranger to reduce the number of features - features = stream.get_feature_space().get_dims() - features_new = [ ( 'F', features[1:5] ) ] - - task_rearranger = Rearranger( p_name='Chain nD, Task T1', - p_range_max=Task.C_RANGE_THREAD, - p_duplicate_data=True, - p_visualize=p_visualize, - p_logging=p_logging, - p_features_new=features_new ) - - workflow.add_task( p_task=task_rearranger ) - - # 2.5.2 Window to buffer some data - task_window = Window( p_buffer_size=50, - p_delay=True, - p_enable_statistics=True, - p_name='Chain nD, Task T2', - p_duplicate_data=True, - p_visualize=p_visualize, - p_logging=p_logging ) - - workflow.add_task(p_task=task_window, p_pred_tasks=[task_rearranger]) - - # 2.5.3 Boundary detector - task_bd = BoundaryDetector( p_name='Chain nD, Task T3', - p_ada=True, - p_visualize=True, - p_logging=p_logging, - p_window=task_window ) - - workflow.add_task(p_task = task_bd, p_pred_tasks=[task_window]) - - # # 2.5.4 MinMax-Normalizer - task_norm_minmax = NormalizerMinMax( p_name='Chain nD, Task T4', - p_ada=True, - p_visualize=p_visualize, - p_logging=p_logging ) - - task_bd.register_event_handler( p_event_id=BoundaryDetector.C_EVENT_ADAPTED, p_event_handler=task_norm_minmax.adapt_on_event ) - - workflow.add_task(p_task = task_norm_minmax, p_pred_tasks=[task_bd]) - - - # 3 Return stream and workflow - return stream, workflow - - - - -# 1 Preparation of demo/unit test mode -if __name__ == "__main__": - # 1.1 Parameters for demo mode - logging = Log.C_LOG_ALL - visualize = True - - try: - cycle_limit = min(1000, max(1, int(input('\nPlease enter number of cycles (1 - 1000, default = 200): ')))) - except: - cycle_limit = 200 - - try: - step_rate = max(1, int(input('\nPlease enter update step rate for visualization (1 = update after every cycle): '))) - except: - step_rate = 1 - -else: - # 1.2 Parameters for internal unit test - cycle_limit = 2 - logging = Log.C_LOG_NOTHING - visualize = False - step_rate = 1 - - -# 2 Instantiate the stream scenario -myscenario = MyAdaptiveScenario(p_mode=Mode.C_MODE_REAL, - p_cycle_limit=cycle_limit, - p_visualize=visualize, - p_logging=logging) - - - - -# 3 Reset and run own stream scenario -myscenario.reset() - -if __name__ == '__main__': - myscenario.init_plot( p_plot_settings=PlotSettings( p_view = PlotSettings.C_VIEW_ND, - p_step_rate = step_rate ) ) - input('\nPlease arrange all windows and press ENTER to start stream processing...') - -tp_before = datetime.now() -myscenario.run() -tp_after = datetime.now() -tp_delta = tp_after - tp_before -duraction_sec = ( tp_delta.seconds * 1000000 + tp_delta.microseconds + 1 ) / 1000000 -myscenario.log(Log.C_LOG_TYPE_S, 'Duration [sec]:', round(duraction_sec,2), ', Cycles/sec:', round(cycle_limit/duraction_sec,2)) - -if __name__ == '__main__': - input('Press ENTER to exit...') \ No newline at end of file diff --git a/test/howtos/oa/streams/anomalydetection/.gitkeep b/test/howtos/oa/streams/anomalydetection/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/test/howtos/oa/streams/anomalyprediction/.gitkeep b/test/howtos/oa/streams/anomalyprediction/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/test/howtos/oa/howto_oa_streams_cbad_001_KMeans_ClusterDriftDetector_InstantaneousDetection_2d.py b/test/howtos/oa/streams/driftdetection/clusterbased/howto_oa_streams_cbdd_001_KMeans_ClusterDriftDetector_InstantaneousDetection_2d.py.off similarity index 78% rename from test/howtos/oa/howto_oa_streams_cbad_001_KMeans_ClusterDriftDetector_InstantaneousDetection_2d.py rename to test/howtos/oa/streams/driftdetection/clusterbased/howto_oa_streams_cbdd_001_KMeans_ClusterDriftDetector_InstantaneousDetection_2d.py.off index 90cc691b3..8e09f91fc 100644 --- a/test/howtos/oa/howto_oa_streams_cbad_001_KMeans_ClusterDriftDetector_InstantaneousDetection_2d.py +++ b/test/howtos/oa/streams/driftdetection/clusterbased/howto_oa_streams_cbdd_001_KMeans_ClusterDriftDetector_InstantaneousDetection_2d.py.off @@ -1,16 +1,17 @@ ## ------------------------------------------------------------------------------------------------- ## -- Project : MLPro - The integrative middleware framework for standardized machine learning ## -- Package : test.howtos.oa -## -- Module : howto_oa_streams_cbad_002_KMeans_ClusterDriftDetector_InstantaneousDetection_2d.py +## -- Module : howto_oa_streams_cbdd_001_KMeans_ClusterDriftDetector_InstantaneousDetection_2d.py ## ------------------------------------------------------------------------------------------------- ## -- History : ## -- yyyy-mm-dd Ver. Auth. Description ## -- 2024-08-04 1.0.0 SK Creation ## -- 2024-10-29 1.0.1 DA Refactoring +## -- 2025-02-13 2.0.0 DA Refactoring ## ------------------------------------------------------------------------------------------------- """ -Ver. 1.0.1 (2024-10-29) +Ver. 2.0.0 (2025-02-13) This module is done as a part of the Master's Thesis named Online Adaptive Cluster-based Anomaly Detection, authored by Syamraj Purushamparambil Satheesh, as a part of the course @@ -41,7 +42,7 @@ from mlpro.bf.various import Log from mlpro.oa.streams import * from mlpro_int_river.wrappers.clusteranalyzers import WrRiverKMeans2MLPro -from mlpro.oa.streams.tasks import ClusterDriftDetector +from mlpro.oa.streams.tasks.driftdetectors.clusterbased import DriftDetectorCBMovement @@ -55,23 +56,23 @@ class MyScenario(OAStreamScenario): def _setup(self, p_mode, p_ada: bool, p_visualize: bool, p_logging): # 1.1 Get MLPro benchmark Clutser Generator - stream = StreamMLProClusterGenerator(p_num_dim=2, - p_num_instances=5000, - p_num_clusters=3, - p_radii=[100], - p_velocities=[0.0], - p_change_velocities=True, - p_changed_velocities=[0.5, 0.6], - p_points_of_change_velocities=[1000, 1200], - p_num_clusters_for_change_velocities=2, - p_seed=12, - p_logging=p_logging) + stream = StreamMLProClusterGenerator( p_num_dim=2, + p_num_instances=5000, + p_num_clusters=3, + p_radii=[100], + p_velocities=[0.0], + p_change_velocities=True, + p_changed_velocities=[0.5, 0.6], + p_points_of_change_velocities=[1000, 1200], + p_num_clusters_for_change_velocities=2, + p_seed=12, + p_logging=p_logging ) # 1.2 Set up a stream workflow # 1.2.1 Creation of a workflow - workflow = OAStreamWorkflow( p_name='Anomaly Detection', + workflow = OAStreamWorkflow( p_name='Drift Detection', p_range_max=OAStreamWorkflow.C_RANGE_NONE, p_ada=p_ada, p_visualize=p_visualize, @@ -92,13 +93,13 @@ def _setup(self, p_mode, p_ada: bool, p_visualize: bool, p_logging): workflow.add_task(p_task = task_clusterer) # Anomaly Detector - task_anomaly_detector = ClusterDriftDetector(p_clusterer=task_clusterer, - p_with_time_calculation=False, - p_instantaneous_velocity_change_detection=True, - p_min_velocity_threshold=1, - p_initial_skip=400, - p_visualize=p_visualize, - p_logging=p_logging) + task_anomaly_detector = DriftDetectorCBMovement( p_clusterer=task_clusterer, + p_with_time_calculation=False, + p_instantaneous_velocity_change_detection=True, + p_min_velocity_threshold=1, + p_initial_skip=400, + p_visualize=p_visualize, + p_logging=p_logging ) workflow.add_task(p_task=task_anomaly_detector, p_pred_tasks=[task_clusterer]) diff --git a/test/howtos/oa/howto_oa_streams_cbad_002_KMeans_ClusterDriftDetector_InstantaneousDetection_normalization_2d.py b/test/howtos/oa/streams/driftdetection/clusterbased/howto_oa_streams_cbdd_002_KMeans_ClusterDriftDetector_InstantaneousDetection_normalization_2d.py.off similarity index 100% rename from test/howtos/oa/howto_oa_streams_cbad_002_KMeans_ClusterDriftDetector_InstantaneousDetection_normalization_2d.py rename to test/howtos/oa/streams/driftdetection/clusterbased/howto_oa_streams_cbdd_002_KMeans_ClusterDriftDetector_InstantaneousDetection_normalization_2d.py.off diff --git a/test/howtos/oa/howto_oa_streams_cbad_003_KMeans_ClusterDriftDetector_StateDetection_2d.py b/test/howtos/oa/streams/driftdetection/clusterbased/howto_oa_streams_cbdd_003_KMeans_ClusterDriftDetector_StateDetection_2d.py.off similarity index 100% rename from test/howtos/oa/howto_oa_streams_cbad_003_KMeans_ClusterDriftDetector_StateDetection_2d.py rename to test/howtos/oa/streams/driftdetection/clusterbased/howto_oa_streams_cbdd_003_KMeans_ClusterDriftDetector_StateDetection_2d.py.off diff --git a/test/howtos/oa/howto_oa_streams_cbad_004_KMeans_ClusterDriftDetector_StateDetection_normalization_2d.py b/test/howtos/oa/streams/driftdetection/clusterbased/howto_oa_streams_cbdd_004_KMeans_ClusterDriftDetector_StateDetection_normalization_2d.py.off similarity index 100% rename from test/howtos/oa/howto_oa_streams_cbad_004_KMeans_ClusterDriftDetector_StateDetection_normalization_2d.py rename to test/howtos/oa/streams/driftdetection/clusterbased/howto_oa_streams_cbdd_004_KMeans_ClusterDriftDetector_StateDetection_normalization_2d.py.off diff --git a/test/howtos/oa/howto_oa_streams_cbad_005_KMeans_ClusterDriftDetector_InstantaneousDetection_normalization_3d.py b/test/howtos/oa/streams/driftdetection/clusterbased/howto_oa_streams_cbdd_005_KMeans_ClusterDriftDetector_InstantaneousDetection_normalization_3d.py.off similarity index 100% rename from test/howtos/oa/howto_oa_streams_cbad_005_KMeans_ClusterDriftDetector_InstantaneousDetection_normalization_3d.py rename to test/howtos/oa/streams/driftdetection/clusterbased/howto_oa_streams_cbdd_005_KMeans_ClusterDriftDetector_InstantaneousDetection_normalization_3d.py.off diff --git a/test/howtos/oa/howto_oa_streams_cbad_006_KMeans_ClusterDriftDetector_InstantaneousDetection_normalization_3d.py b/test/howtos/oa/streams/driftdetection/clusterbased/howto_oa_streams_cbdd_006_KMeans_ClusterDriftDetector_InstantaneousDetection_normalization_3d.py.off similarity index 100% rename from test/howtos/oa/howto_oa_streams_cbad_006_KMeans_ClusterDriftDetector_InstantaneousDetection_normalization_3d.py rename to test/howtos/oa/streams/driftdetection/clusterbased/howto_oa_streams_cbdd_006_KMeans_ClusterDriftDetector_InstantaneousDetection_normalization_3d.py.off diff --git a/test/howtos/oa/howto_oa_streams_cbad_007_KMeans_ClusterDriftDetector_StateDetection_3d.py b/test/howtos/oa/streams/driftdetection/clusterbased/howto_oa_streams_cbdd_007_KMeans_ClusterDriftDetector_StateDetection_3d.py.off similarity index 100% rename from test/howtos/oa/howto_oa_streams_cbad_007_KMeans_ClusterDriftDetector_StateDetection_3d.py rename to test/howtos/oa/streams/driftdetection/clusterbased/howto_oa_streams_cbdd_007_KMeans_ClusterDriftDetector_StateDetection_3d.py.off diff --git a/test/howtos/oa/howto_oa_streams_cbad_008_KMeans_ClusterDriftDetector_StateDetection_normalization_3d.py b/test/howtos/oa/streams/driftdetection/clusterbased/howto_oa_streams_cbdd_008_KMeans_ClusterDriftDetector_StateDetection_normalization_3d.py.off similarity index 100% rename from test/howtos/oa/howto_oa_streams_cbad_008_KMeans_ClusterDriftDetector_StateDetection_normalization_3d.py rename to test/howtos/oa/streams/driftdetection/clusterbased/howto_oa_streams_cbdd_008_KMeans_ClusterDriftDetector_StateDetection_normalization_3d.py.off diff --git a/test/howtos/oa/howto_oa_streams_cbad_009_KMeans_ClusterDriftDetector_InstantaneousDetection_5d.py b/test/howtos/oa/streams/driftdetection/clusterbased/howto_oa_streams_cbdd_009_KMeans_ClusterDriftDetector_InstantaneousDetection_5d.py.off similarity index 100% rename from test/howtos/oa/howto_oa_streams_cbad_009_KMeans_ClusterDriftDetector_InstantaneousDetection_5d.py rename to test/howtos/oa/streams/driftdetection/clusterbased/howto_oa_streams_cbdd_009_KMeans_ClusterDriftDetector_InstantaneousDetection_5d.py.off diff --git a/test/howtos/oa/howto_oa_streams_cbad_010_KMeans_ClusterDriftDetector_InstantaneousDetection_normalization_5d.py b/test/howtos/oa/streams/driftdetection/clusterbased/howto_oa_streams_cbdd_010_KMeans_ClusterDriftDetector_InstantaneousDetection_normalization_5d.py.off similarity index 100% rename from test/howtos/oa/howto_oa_streams_cbad_010_KMeans_ClusterDriftDetector_InstantaneousDetection_normalization_5d.py rename to test/howtos/oa/streams/driftdetection/clusterbased/howto_oa_streams_cbdd_010_KMeans_ClusterDriftDetector_InstantaneousDetection_normalization_5d.py.off diff --git a/test/howtos/oa/howto_oa_streams_cbad_011_KMeans_ClusterDriftDetector_StateDetection_5d.py b/test/howtos/oa/streams/driftdetection/clusterbased/howto_oa_streams_cbdd_011_KMeans_ClusterDriftDetector_StateDetection_5d.py.off similarity index 100% rename from test/howtos/oa/howto_oa_streams_cbad_011_KMeans_ClusterDriftDetector_StateDetection_5d.py rename to test/howtos/oa/streams/driftdetection/clusterbased/howto_oa_streams_cbdd_011_KMeans_ClusterDriftDetector_StateDetection_5d.py.off diff --git a/test/howtos/oa/howto_oa_streams_cbad_012_KMeans_ClusterDriftDetector_StateDetection_normalization_5d.py b/test/howtos/oa/streams/driftdetection/clusterbased/howto_oa_streams_cbdd_012_KMeans_ClusterDriftDetector_StateDetection_normalization_5d.py.off similarity index 100% rename from test/howtos/oa/howto_oa_streams_cbad_012_KMeans_ClusterDriftDetector_StateDetection_normalization_5d.py rename to test/howtos/oa/streams/driftdetection/clusterbased/howto_oa_streams_cbdd_012_KMeans_ClusterDriftDetector_StateDetection_normalization_5d.py.off diff --git a/test/howtos/oa/howto_oa_streams_pp_121_complex_preprocessing.py b/test/howtos/oa/streams/hybrid/howto_oa_streams_pp_121_complex_preprocessing.py similarity index 100% rename from test/howtos/oa/howto_oa_streams_pp_121_complex_preprocessing.py rename to test/howtos/oa/streams/hybrid/howto_oa_streams_pp_121_complex_preprocessing.py diff --git a/test/howtos/oa/howto_oa_streams_pp_001_bd_normminmax_2d.py b/test/howtos/oa/streams/normalization/howto_oa_streams_pp_001_bd_normminmax_2d.py similarity index 100% rename from test/howtos/oa/howto_oa_streams_pp_001_bd_normminmax_2d.py rename to test/howtos/oa/streams/normalization/howto_oa_streams_pp_001_bd_normminmax_2d.py diff --git a/test/howtos/oa/howto_oa_streams_pp_002_bd_normminmax_3d.py b/test/howtos/oa/streams/normalization/howto_oa_streams_pp_002_bd_normminmax_3d.py similarity index 100% rename from test/howtos/oa/howto_oa_streams_pp_002_bd_normminmax_3d.py rename to test/howtos/oa/streams/normalization/howto_oa_streams_pp_002_bd_normminmax_3d.py diff --git a/test/howtos/oa/howto_oa_streams_pp_003_bd_normminmax_nd.py b/test/howtos/oa/streams/normalization/howto_oa_streams_pp_003_bd_normminmax_nd.py similarity index 100% rename from test/howtos/oa/howto_oa_streams_pp_003_bd_normminmax_nd.py rename to test/howtos/oa/streams/normalization/howto_oa_streams_pp_003_bd_normminmax_nd.py diff --git a/test/howtos/oa/howto_oa_streams_pp_006_normztrans_2d.py b/test/howtos/oa/streams/normalization/howto_oa_streams_pp_006_normztrans_2d.py similarity index 100% rename from test/howtos/oa/howto_oa_streams_pp_006_normztrans_2d.py rename to test/howtos/oa/streams/normalization/howto_oa_streams_pp_006_normztrans_2d.py diff --git a/test/howtos/oa/howto_oa_streams_pp_007_normztrans_3d.py b/test/howtos/oa/streams/normalization/howto_oa_streams_pp_007_normztrans_3d.py similarity index 100% rename from test/howtos/oa/howto_oa_streams_pp_007_normztrans_3d.py rename to test/howtos/oa/streams/normalization/howto_oa_streams_pp_007_normztrans_3d.py diff --git a/test/howtos/oa/howto_oa_streams_pp_008_normztrans_nd.py b/test/howtos/oa/streams/normalization/howto_oa_streams_pp_008_normztrans_nd.py similarity index 100% rename from test/howtos/oa/howto_oa_streams_pp_008_normztrans_nd.py rename to test/howtos/oa/streams/normalization/howto_oa_streams_pp_008_normztrans_nd.py diff --git a/test/howtos/oa/howto_oa_streams_pp_101_rearranger_window_bd_normminmax_2d.py b/test/howtos/oa/streams/normalization/howto_oa_streams_pp_101_rearranger_window_bd_normminmax_2d.py similarity index 100% rename from test/howtos/oa/howto_oa_streams_pp_101_rearranger_window_bd_normminmax_2d.py rename to test/howtos/oa/streams/normalization/howto_oa_streams_pp_101_rearranger_window_bd_normminmax_2d.py diff --git a/test/howtos/oa/howto_oa_streams_pp_102_rearranger_window_bd_normminmax_3d.py b/test/howtos/oa/streams/normalization/howto_oa_streams_pp_102_rearranger_window_bd_normminmax_3d.py similarity index 100% rename from test/howtos/oa/howto_oa_streams_pp_102_rearranger_window_bd_normminmax_3d.py rename to test/howtos/oa/streams/normalization/howto_oa_streams_pp_102_rearranger_window_bd_normminmax_3d.py diff --git a/test/howtos/oa/howto_oa_streams_pp_103_rearranger_window_bd_normminmax_nd.py b/test/howtos/oa/streams/normalization/howto_oa_streams_pp_103_rearranger_window_bd_normminmax_nd.py similarity index 100% rename from test/howtos/oa/howto_oa_streams_pp_103_rearranger_window_bd_normminmax_nd.py rename to test/howtos/oa/streams/normalization/howto_oa_streams_pp_103_rearranger_window_bd_normminmax_nd.py diff --git a/test/howtos/oa/howto_oa_streams_pp_104_rearranger_window_bd_normminmax_2d_3d_nD.py b/test/howtos/oa/streams/normalization/howto_oa_streams_pp_104_rearranger_window_bd_normminmax_2d_3d_nD.py similarity index 100% rename from test/howtos/oa/howto_oa_streams_pp_104_rearranger_window_bd_normminmax_2d_3d_nD.py rename to test/howtos/oa/streams/normalization/howto_oa_streams_pp_104_rearranger_window_bd_normminmax_2d_3d_nD.py diff --git a/test/howtos/oa/howto_oa_streams_pp_111_rearranger_deriver_normalizer.py.off b/test/howtos/oa/streams/normalization/howto_oa_streams_pp_111_rearranger_deriver_normalizer.py.off similarity index 100% rename from test/howtos/oa/howto_oa_streams_pp_111_rearranger_deriver_normalizer.py.off rename to test/howtos/oa/streams/normalization/howto_oa_streams_pp_111_rearranger_deriver_normalizer.py.off