def detect(self, dataframe: pd.DataFrame, cache: Optional[ModelCache]) -> DetectionResult: logger.debug('Unit {} got {} data points for detection'.format( self.analytic_unit_id, len(dataframe))) # TODO: split and sleep (https://github.com/hastic/hastic-server/pull/124#discussion_r214085643) if cache is None: msg = f'{self.analytic_unit_id} detection got invalid cache, skip detection' logger.error(msg) raise ValueError(msg) self.model.state = self.model.get_state(cache) window_size = self.model.state.window_size if window_size is None: message = '{} got cache without window_size for detection'.format( self.analytic_unit_id) logger.error(message) raise ValueError(message) if len(dataframe) < window_size * 2: message = f'{self.analytic_unit_id} skip detection: dataset length {len(dataframe)} points less than minimal length {window_size * 2} points' logger.error(message) raise ValueError(message) detected = self.model.detect(dataframe, self.analytic_unit_id) segments = [ Segment(segment[0], segment[1]) for segment in detected['segments'] ] new_cache = detected['cache'].to_json() last_dataframe_time = dataframe.iloc[-1]['timestamp'] last_detection_time = convert_pd_timestamp_to_ms(last_dataframe_time) return DetectionResult(new_cache, segments, last_detection_time)
def concat_detection_results( self, detections: List[DetectionResult]) -> DetectionResult: result = DetectionResult() for detection in detections: result.segments.extend(detection.segments) result.last_detection_time = detection.last_detection_time result.cache = detection.cache return result
def concat_detection_results(self, detections: List[DetectionResult]) -> DetectionResult: result = DetectionResult() time_step = detections[0].cache['timeStep'] for detection in detections: result.segments.extend(detection.segments) result.last_detection_time = detection.last_detection_time result.cache = detection.cache result.segments = utils.merge_intersecting_segments(result.segments, time_step) return result
def detect(self, dataframe: pd.DataFrame, cache: Optional[ModelCache]) -> DetectionResult: if cache == None: raise f'Analytic unit {self.analytic_unit_id} got empty cache' data = dataframe['value'] cache = AnomalyCache.from_json(cache) segments = cache.segments enabled_bounds = cache.get_enabled_bounds() smoothed_data = utils.exponential_smoothing(data, cache.alpha) lower_bound = smoothed_data - cache.confidence upper_bound = smoothed_data + cache.confidence if len(segments) > 0: data_start_time = utils.convert_pd_timestamp_to_ms( dataframe['timestamp'][0]) for segment in segments: seasonality_index = cache.seasonality // cache.time_step seasonality_offset = self.get_seasonality_offset( segment.from_timestamp, cache.seasonality, data_start_time, cache.time_step) segment_data = pd.Series(segment.data) lower_bound = self.add_season_to_data(lower_bound, segment_data, seasonality_offset, seasonality_index, Bound.LOWER) upper_bound = self.add_season_to_data(upper_bound, segment_data, seasonality_offset, seasonality_index, Bound.UPPER) detected_segments = list( self.detections_generator(dataframe, upper_bound, lower_bound, enabled_bounds)) last_dataframe_time = dataframe.iloc[-1]['timestamp'] last_detection_time = utils.convert_pd_timestamp_to_ms( last_dataframe_time) return DetectionResult(cache.to_json(), detected_segments, last_detection_time)
def detect(self, dataframe: pd.DataFrame, cache: ModelCache) -> DetectionResult: if cache is None or cache == {}: raise ValueError('Threshold detector error: cannot detect before learning') if len(dataframe) == 0: return None value = cache['value'] condition = cache['condition'] segments = [] for index, row in dataframe.iterrows(): current_value = row['value'] current_timestamp = utils.convert_pd_timestamp_to_ms(row['timestamp']) segment = Segment(current_timestamp, current_timestamp) # TODO: merge segments if pd.isnull(current_value): if condition == 'NO_DATA': segment.message = 'NO_DATA detected' segments.append(segment) continue comparators = { '>': operator.gt, '<': operator.lt, '=': operator.eq, '>=': operator.ge, '<=': operator.le } assert condition in comparators.keys(), f'condition {condition} not allowed' if comparators[condition](current_value, value): segment.message = f"{current_value} {condition} threshold's value {value}" segments.append(segment) last_entry = dataframe.iloc[-1] last_detection_time = utils.convert_pd_timestamp_to_ms(last_entry['timestamp']) return DetectionResult(cache, segments, last_detection_time)