예제 #1
0
 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
예제 #2
0
 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
예제 #3
0
    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)
예제 #4
0
    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)
예제 #5
0
    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)