diff --git a/src/mlpro/oa/streams/tasks/anomalydetectors/anomalies/instancebased/group.py b/src/mlpro/oa/streams/tasks/anomalydetectors/anomalies/instancebased/group.py index 975f35592..31564f895 100644 --- a/src/mlpro/oa/streams/tasks/anomalydetectors/anomalies/instancebased/group.py +++ b/src/mlpro/oa/streams/tasks/anomalydetectors/anomalies/instancebased/group.py @@ -14,12 +14,13 @@ ## -- 2024-05-22 1.3.0 SK Refactoring ## -- 2024-11-27 1.3.1 DA Bugfix in method GroupAnomaly.__init__() ## -- 2024-12-11 1.3.2 DA Pseudo classes if matplotlib is not installed +## -- 2025-03-05 1.4.0 DA Code optimization ## ------------------------------------------------------------------------------------------------- """ -Ver. 1.3.2 (2024-12-11) +Ver. 1.4.0 (2025-03-05) -This module provides a template class for group anomaly to be used in anomaly detection algorithms. +This module provides a class for group anomalies to be used in anomaly detection algorithms. """ from datetime import datetime @@ -133,27 +134,23 @@ def _update_plot_nd(self, p_settings: PlotSettings, **p_kwargs): color (str): Color of the shaded region. alpha (float): Transparency of the shaded region (default is 0.5). """ + if not self.plot_update: return - x1 = self.instances[0] - x2 = self.instances[-1] + x1 = self.instances[0].tstamp + x2 = self.instances[-1].tstamp - x1 = x1.id - x2 = x2.id - a=[] - b=[] + y_values = [] for instance in self.instances: - a.append(instance.get_feature_data().get_values()) + y_values.extend(instance.get_feature_data().get_values()) - for x in a: - b.extend(x) - - y1 = min(b) - y2 = max(b) + + y1 = min(y_values) + y2 = max(y_values) if self._rect is None: - label = 'G' + label = 'GA(' + str(self.id) + ')' self._rect = patches.Rectangle((x1, y1), x2 - x1, y2 - y1, linewidth=1, edgecolor='black', facecolor='yellow', alpha=0.5) self._plot_rectangle = p_settings.axes.add_patch(self._rect) self._plot_rectangle_t = p_settings.axes.text((x1+x2)/2, 0, label, color='b' ) diff --git a/src/mlpro/oa/streams/tasks/anomalydetectors/anomalies/instancebased/point.py b/src/mlpro/oa/streams/tasks/anomalydetectors/anomalies/instancebased/point.py index 4f48de558..7f4d3549f 100644 --- a/src/mlpro/oa/streams/tasks/anomalydetectors/anomalies/instancebased/point.py +++ b/src/mlpro/oa/streams/tasks/anomalydetectors/anomalies/instancebased/point.py @@ -90,7 +90,7 @@ def _update_plot_2d(self, p_settings: PlotSettings, p_axlimits_changed: bool, p_ line_y2_ypos = [ feature_values[1], feature_values[1] ] if self._plot_line_x1 is None: - label = 'PO(' + str(self.get_id()) + ')' + label = 'PA(' + str(self.id) + ')' self._plot_line_x1 = p_settings.axes.plot(line_x1_xpos, line_x1_ypos, color='r', linestyle='dashed', lw=1)[0] self._plot_line_x2 = p_settings.axes.plot(line_x2_xpos, line_x2_ypos, color='r', linestyle='dashed', lw=1)[0] self._plot_line_y1 = p_settings.axes.plot(line_y1_xpos, line_y1_ypos, color='r', linestyle='dashed', lw=1)[0] @@ -146,7 +146,7 @@ def _update_plot_3d(self, p_settings: PlotSettings, p_axlimits_changed: bool, p_ line_z2_zpos = [ feature_values[2] - offset_z, feature_values[2] - len_z ] if self._plot_line_x1 is None: - label = 'PO(' + str(self.get_id()) + ')' + label = 'PA(' + str(self.id) + ')' self._plot_line_x1 = p_settings.axes.plot( line_x1_xpos, line_x1_ypos, line_x1_zpos, color='r', linestyle='dashed', lw=1 )[0] self._plot_line_x2 = p_settings.axes.plot( line_x2_xpos, line_x2_ypos, line_x2_zpos, color='r', linestyle='dashed', lw=1 )[0] self._plot_line_y1 = p_settings.axes.plot( line_y1_xpos, line_y1_ypos, line_y1_zpos, color='r', linestyle='dashed', lw=1 )[0] @@ -173,11 +173,11 @@ def _update_plot_nd(self, p_settings: PlotSettings, p_axlimits_changed: bool, p_ inst = self.instances[-1] - inst_id = inst.get_id() + inst_id = inst.id xpos = [inst_id, inst_id] if self._plot_line is None: - label = 'PO(' + str(self.get_id()) + ')' + label = 'PA(' + str(self.id) + ')' self._plot_line = p_settings.axes.plot(xpos, p_ylim, color='r', linestyle='dashed', lw=1)[0] self._plot_label = p_settings.axes.text(inst_id, p_ylim[1], label, color='r' ) diff --git a/src/mlpro/oa/streams/tasks/anomalydetectors/instancebased/detectors_point_group.py b/src/mlpro/oa/streams/tasks/anomalydetectors/instancebased/detectors_point_group.py index 1b7a82f3c..0ca78eff2 100644 --- a/src/mlpro/oa/streams/tasks/anomalydetectors/instancebased/detectors_point_group.py +++ b/src/mlpro/oa/streams/tasks/anomalydetectors/instancebased/detectors_point_group.py @@ -14,11 +14,11 @@ ## -- 2024-08-12 1.3.0 DA Review and adjustments on documentation ## -- 2025-02-14 1.4.0 DA Refactoring ## -- 2025-02-17 1.5.0 DA Review and generalization -## -- 2025-02-28 1.6.0 DA Refactoring and simplification +## -- 2025-03-05 1.6.0 DA Refactoring and simplification ## ------------------------------------------------------------------------------------------------- """ -Ver. 1.6.0 (2025-02-28) +Ver. 1.6.0 (2025-03-05) This module provides an extended template for instance-based anomaly detectors that supports an optional group anomaly detection based on point anomalies. @@ -59,6 +59,8 @@ class AnomalyDetectorIBPG (AnomalyDetectorIB): Boolean switch for visualisation. Default = False. p_logging Log level (see constants of class Log). Default: Log.C_LOG_ALL + p_anomaly_buffer_size : int = 100 + Size of the internal anomaly buffer self.anomalies. Default = 100. p_kwargs : dict Further optional named parameters. """ @@ -74,6 +76,7 @@ def __init__( self, p_duplicate_data : bool = False, p_visualize : bool = False, p_logging = Log.C_LOG_ALL, + p_anomaly_buffer_size : int = 100, **p_kwargs ): super().__init__( p_name = p_name, @@ -82,6 +85,7 @@ def __init__( self, p_duplicate_data = p_duplicate_data, p_visualize = p_visualize, p_logging = p_logging, + p_anomaly_buffer_size = p_anomaly_buffer_size, **p_kwargs ) self._group_anomalies : list[Anomaly] = [] @@ -90,7 +94,7 @@ def __init__( self, ## ------------------------------------------------------------------------------------------------- - def _buffer_anomaly(self, p_anomaly): + def _buffer_anomaly(self, p_anomaly : Anomaly): """ Method to be used to add a new anomaly. Please use as part of your algorithm. @@ -124,11 +128,13 @@ def _buffer_anomaly(self, p_anomaly): self._ano_id -= 2 groupanomaly = GroupAnomaly( p_instances = self._group_anomalies_instances, - p_visualize=self._visualize, + p_visualize=self.get_visualization(), p_raising_object = self, p_tstampt = inst_2.tstamp ) + + self._raise_anomaly_event( p_anomaly = groupanomaly ) - super()._buffer_anomaly( p_anomaly = groupanomaly ) + # super()._buffer_anomaly( p_anomaly = groupanomaly ) self._group_anomalies = [] self._group_anomalies.append(groupanomaly)