def test__detect_anoms_no_num_obs_per_period(self): with self.assertRaises(AssertionError): _detect_anoms(self.data1, k=0.02, alpha=0.05, num_obs_per_period=None, use_decomp=False, use_esd=False, direction='both')
def test__detect_anoms(data): shesd = detts._detect_anoms(data, k=0.02, alpha=0.05, num_obs_per_period=1440, use_decomp=True, use_esd=False, direction='both', verbose=False)
def test__detect_anoms_use_esd_true(self): shesd = _detect_anoms(self.data1, k=0.02, alpha=0.05, num_obs_per_period=1440, use_decomp=True, use_esd=True, direction='both') self.assertEquals(133, len(shesd['anoms']))
def test__detect_anoms_neg(self): shesd = _detect_anoms(self.data1, k=0.02, alpha=0.05, num_obs_per_period=1440, use_decomp=True, use_esd=False, direction='neg') self.assertEquals(85, len(shesd['anoms']))
def test__detect_anoms_use_decomp_false(self): shesd = _detect_anoms(self.data1, k=0.02, alpha=0.05, num_obs_per_period=1440, use_decomp=False, use_esd=False, direction='both', verbose=False) self.assertEquals(133, len(shesd['anoms']))
def test__detect_anoms_pos_multithreaded(self): shesd = _detect_anoms(self.data1, k=0.02, alpha=0.05, num_obs_per_period=1440, use_decomp=True, use_esd=False, direction='pos', verbose=False, multithreaded=True) self.assertEquals(50, len(shesd['anoms']))
def anomaly_detect_vec(x, max_anoms=0.1, direction="pos", alpha=0.05, period=None, only_last=False, threshold=None, e_value=False, longterm_period=None, plot=False, y_log=False, xlabel="", ylabel="count", title="", verbose=False): assert isinstance(x, pd.Series), 'x must be pandas series' assert max_anoms < 0.5, 'max_anoms must be < 0.5' assert direction in ['pos', 'neg', 'both'], 'direction should be one of "pos", "neg", "both"' assert period, "Period must be set to the number of data points in a single period" __verbose_if((alpha < 0.01 or alpha > 0.1) and verbose, "Warning: alpha is the statistical significance, and is usually between 0.01 and 0.1") max_anoms = 1.0 / x.size if max_anoms < 1.0 / x.size else max_anoms step = int(np.ceil(x.size / longterm_period) ) if longterm_period else x.size all_data = [x.iloc[i:i + step] for i in range(0, x.size, step)] one_tail = True if direction in ['pos', 'neg'] else False upper_tail = True if direction in ['pos', 'both'] else False all_anoms = pd.Series() seasonal_plus_trend = pd.Series() for ts in all_data: tmp = _detect_anoms( ts, k=max_anoms, alpha=alpha, num_obs_per_period=period, use_decomp=True, use_esd=False, direction=direction, verbose=verbose) s_h_esd_timestamps = tmp['anoms'].keys() data_decomp = tmp['stl'] anoms = ts.loc[s_h_esd_timestamps] if threshold: end = longterm_period - 1 if longterm_period else x.size - 1 periodic_maxs = [ts.iloc[i: i + period].max() for i in range(0, end, period)] if threshold == "med_max": thresh = periodic_maxs.median() elif threshold == "p95": thresh = periodic_maxs.quantile(0.95) elif threshold == "p99": thresh = periodic_maxs.quantile(0.99) anoms = anoms[anoms >= thresh] all_anoms.append(anoms) seasonal_plus_trend.append(data_decomp) all_anoms.drop_duplicates(inplace=True) seasonal_plus_trend.drop_duplicates(inplace=True) return anoms