1# coding=utf-8
2"""
3© 2014 LinkedIn Corp. All rights reserved.
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at  http://www.apache.org/licenses/LICENSE-2.0
7
8Unless required by applicable law or agreed to in writing, software
9distributed under the License is distributed on an "AS IS" BASIS,
10WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11"""
12from luminol.constants import *
13
14__all__ = ['bitmap_detector', 'derivative_detector', 'exp_avg_detector', 'default_detector', 'absolute_threshold',
15           'diff_percent_threshold']
16
17
18class AnomalyDetectorAlgorithm(object):
19
20  """
21  Base Class for AnomalyDetector algorithm.
22  """
23  def __init__(self, class_name, time_series, baseline_time_series=None):
24    """
25    Initializer
26    :param str class_name: extended class name.
27    :param TimeSeries time_series: a TimeSeries object.
28    :param TimeSeries baseline_time_series: baseline TimeSeries.
29    """
30    self.class_name = class_name
31    self.time_series = time_series
32    self.time_series_length = len(time_series)
33    self.baseline_time_series = baseline_time_series
34
35  def run(self):
36    """
37    Run the algorithm to get anomalies.
38    return list: a list of Anomaly objects.
39    """
40    self._set_scores()
41    return self.anom_scores
42
43  def _denoise_scores(self, scores):
44    """
45    Denoise anomaly scores.
46    Low anomaly scores could be noisy. The following two series will have good correlation result with out denoise:
47    [0.08, 4.6, 4.6, 4.6, 1.0, 1.0]
48    [0.0010, 0.0012, 0.0012, 0.0008, 0.0008]
49    while the second series is pretty flat(suppose it has a max score of 100).
50    param dict scores: the scores to be denoised.
51    """
52    if scores:
53      maximal = max(scores.values())
54      if maximal:
55        for key in scores:
56          if scores[key] < DEFAULT_NOISE_PCT_THRESHOLD * maximal:
57            scores[key] = 0
58    return scores
59
60  # Need to be extended.
61  def _set_scores(self):
62    """
63    Compute anomaly scores for the time series.
64    """
65    raise NotImplementedError
66
67  def get_scores(self):
68    """
69    Get anomaly scores for the time series.
70    :return TimeSeries: a TimeSeries representation of the anomaly scores.
71    """
72    return self.anom_scores
73