@@ -45,6 +45,7 @@ def __init__(self, period = 1000):
4545 self .mean = 1.0
4646 self .var = 0.0003
4747 self .std = math .sqrt (self .var )
48+ self .prev = 0.0
4849
4950 def compute (self , anomaly ):
5051 """ Returns the probability that an anomaly has occurred.
@@ -53,9 +54,11 @@ def compute(self, anomaly):
5354 score is greater than a historical distribution of anomaly scores. Then
5455 updates the historical distribution to include the given anomaly score.
5556 """
56- p = self .get_log_likelihood (anomaly )
57+ likelihood = self .get_likelihood (anomaly )
5758 self .add_record (anomaly )
58- return p
59+ combined = 1 - (1 - likelihood ) * (1 - self .prev )
60+ self .prev = likelihood
61+ return self .get_log_likelihood (combined )
5962
6063 def add_record (self , anomaly ):
6164 """
@@ -87,14 +90,13 @@ def get_likelihood(self, anomaly):
8790 except ZeroDivisionError : z = float ('inf' )
8891 return 1.0 - 0.5 * math .erfc (z / 1.4142 )
8992
90- def get_log_likelihood (self , anomaly ):
93+ def get_log_likelihood (self , likelihood ):
9194 """
9295 Compute a log scale representation of the likelihood value. Since the
9396 likelihood computations return low probabilities that often go into four 9's
9497 or five 9's, a log value is more useful for visualization, thresholding,
9598 etc.
9699 """
97- likelihood = self .get_likelihood (anomaly )
98100 # The log formula is:
99101 # Math.log(1.0000000001 - likelihood) / Math.log(1.0 - 0.9999999999)
100102 return math .log (1.0000000001 - likelihood ) / - 23.02585084720009
0 commit comments