use of com.linkedin.thirdeye.anomalydetection.context.TimeSeries in project pinot by linkedin.
the class SeasonalAveragePredictionModel method train.
@Override
public void train(List<TimeSeries> baselineTimeSeries, AnomalyDetectionContext anomalyDetectionContext) {
expectedTimeSeries = new TimeSeries();
if (CollectionUtils.isNotEmpty(baselineTimeSeries)) {
TimeSeries baseTimeSeries = getLatestTimeSeries(baselineTimeSeries);
Interval baseInterval = baseTimeSeries.getTimeSeriesInterval();
long bucketSizeInMillis = anomalyDetectionContext.getBucketSizeInMS();
long baseStart = baseInterval.getStartMillis();
long baseEnd = baseInterval.getEndMillis();
int bucketCount = (int) ((baseEnd - baseStart) / bucketSizeInMillis);
expectedTimeSeries.setTimeSeriesInterval(baseInterval);
if (baselineTimeSeries.size() > 1) {
for (int i = 0; i < bucketCount; ++i) {
double sum = 0d;
int count = 0;
long timeOffset = i * bucketSizeInMillis;
for (TimeSeries ts : baselineTimeSeries) {
long timestamp = ts.getTimeSeriesInterval().getStartMillis() + timeOffset;
Double value = ts.get(timestamp);
if (value != null) {
sum += value;
++count;
}
}
if (count != 0) {
long timestamp = baseStart + timeOffset;
double avgValue = sum / (double) count;
expectedTimeSeries.set(timestamp, avgValue);
}
}
} else {
for (int i = 0; i < bucketCount; ++i) {
long timestamp = baseStart + i * bucketSizeInMillis;
Double value = baseTimeSeries.get(timestamp);
if (value != null) {
expectedTimeSeries.set(timestamp, value);
}
}
}
}
}
use of com.linkedin.thirdeye.anomalydetection.context.TimeSeries in project pinot by linkedin.
the class TotalCountThresholdRemovalFunction method transform.
/**
* Returns an empty time series if the sum of the total count metric does not exceed the
* threshold.
*
* @param timeSeries the time series that provides the data points to be
* transformed.
* @param anomalyDetectionContext the anomaly detection context that could provide additional
* information for the transformation. Specifically, the time
* series that provide the values to compute the total count. Note
* that this function simply sum up the values of the specified
* time series and hence the timestamp of that time series does not
* matter. Moreover, this metric has to be put in the set of
* current time series.
*
* @return the original time series the sum of the values in total count time series exceeds the
* threshold.
*/
@Override
public TimeSeries transform(TimeSeries timeSeries, AnomalyDetectionContext anomalyDetectionContext) {
String totalCountMetricName = getProperties().getProperty(TOTAL_COUNT_METRIC_NAME);
if (StringUtils.isBlank(totalCountMetricName)) {
return timeSeries;
}
double totalCountThreshold = Double.valueOf(getProperties().getProperty(TOTAL_COUNT_THRESHOLD, "0"));
TimeSeries totalCountTS = anomalyDetectionContext.getCurrent(totalCountMetricName);
double sum = 0d;
for (long timestamp : totalCountTS.timestampSet()) {
sum += totalCountTS.get(timestamp);
}
if (Double.compare(sum, totalCountThreshold) < 0) {
TimeSeries emptyTimeSeries = new TimeSeries();
emptyTimeSeries.setTimeSeriesInterval(timeSeries.getTimeSeriesInterval());
return emptyTimeSeries;
} else {
return timeSeries;
}
}
use of com.linkedin.thirdeye.anomalydetection.context.TimeSeries in project pinot by linkedin.
the class TestMinMaxThresholdFunction method recomputeMergedAnomalyWeight.
@Test(dataProvider = "timeSeriesDataProvider")
public void recomputeMergedAnomalyWeight(Properties properties, TimeSeriesKey timeSeriesKey, long bucketSizeInMs, TimeSeries observedTimeSeries) throws Exception {
AnomalyDetectionContext anomalyDetectionContext = new AnomalyDetectionContext();
anomalyDetectionContext.setBucketSizeInMS(bucketSizeInMs);
properties.put(MinMaxThresholdDetectionModel.MAX_VAL, "20");
properties.put(MinMaxThresholdDetectionModel.MIN_VAL, "12");
// Create anomaly function spec
AnomalyFunctionDTO functionSpec = new AnomalyFunctionDTO();
functionSpec.setMetric(mainMetric);
functionSpec.setProperties(TestWeekOverWeekRuleFunction.toString(properties));
AnomalyDetectionFunction function = new MinMaxThresholdFunction();
function.init(functionSpec);
anomalyDetectionContext.setAnomalyDetectionFunction(function);
anomalyDetectionContext.setCurrent(mainMetric, observedTimeSeries);
anomalyDetectionContext.setTimeSeriesKey(timeSeriesKey);
List<RawAnomalyResultDTO> expectedRawAnomalies = new ArrayList<>();
RawAnomalyResultDTO rawAnomaly1 = new RawAnomalyResultDTO();
rawAnomaly1.setStartTime(observedStartTime + bucketMillis * 3);
rawAnomaly1.setEndTime(observedStartTime + bucketMillis * 4);
rawAnomaly1.setWeight(0.1d);
rawAnomaly1.setScore(13.6d);
expectedRawAnomalies.add(rawAnomaly1);
RawAnomalyResultDTO rawAnomaly2 = new RawAnomalyResultDTO();
rawAnomaly2.setStartTime(observedStartTime + bucketMillis * 4);
rawAnomaly2.setEndTime(observedStartTime + bucketMillis * 5);
rawAnomaly2.setWeight(-0.33333d);
rawAnomaly2.setScore(13.6d);
expectedRawAnomalies.add(rawAnomaly2);
MergedAnomalyResultDTO mergedAnomaly = new MergedAnomalyResultDTO();
mergedAnomaly.setStartTime(expectedRawAnomalies.get(0).getStartTime());
mergedAnomaly.setEndTime(expectedRawAnomalies.get(1).getEndTime());
mergedAnomaly.setAnomalyResults(expectedRawAnomalies);
function.updateMergedAnomalyInfo(anomalyDetectionContext, mergedAnomaly);
double currentTotal = 0d;
double deviationFromThreshold = 0d;
Interval interval = new Interval(mergedAnomaly.getStartTime(), mergedAnomaly.getEndTime());
TimeSeries currentTS = anomalyDetectionContext.getTransformedCurrent(mainMetric);
for (long timestamp : currentTS.timestampSet()) {
if (interval.contains(timestamp)) {
double value = currentTS.get(timestamp);
currentTotal += value;
deviationFromThreshold += computeDeviationFromMinMax(value, 12d, 20d);
}
}
double score = currentTotal / 2d;
double weight = deviationFromThreshold / 2d;
Assert.assertEquals(mergedAnomaly.getScore(), score, EPSILON);
Assert.assertEquals(mergedAnomaly.getAvgCurrentVal(), score, EPSILON);
Assert.assertEquals(mergedAnomaly.getWeight(), weight, EPSILON);
}
use of com.linkedin.thirdeye.anomalydetection.context.TimeSeries in project pinot by linkedin.
the class TestMinMaxThresholdFunction method timeSeriesDataProvider.
@DataProvider(name = "timeSeriesDataProvider")
public Object[][] timeSeriesDataProvider() {
// The properties for the testing time series
Properties properties = new Properties();
long bucketSizeInMS = TimeUnit.SECONDS.toMillis(1);
// Set up time series key for the testing time series
TimeSeriesKey timeSeriesKey = new TimeSeriesKey();
String metric = mainMetric;
timeSeriesKey.setMetricName(metric);
DimensionMap dimensionMap = new DimensionMap();
dimensionMap.put("dimensionName1", "dimensionValue1");
dimensionMap.put("dimensionName2", "dimensionValue2");
timeSeriesKey.setDimensionMap(dimensionMap);
TimeSeries observedTimeSeries = new TimeSeries();
{
observedTimeSeries.set(observedStartTime, 10d);
observedTimeSeries.set(observedStartTime + bucketMillis, 15d);
observedTimeSeries.set(observedStartTime + bucketMillis * 2, 13d);
observedTimeSeries.set(observedStartTime + bucketMillis * 3, 22d);
observedTimeSeries.set(observedStartTime + bucketMillis * 4, 8d);
Interval observedTimeSeriesInterval = new Interval(observedStartTime, observedStartTime + bucketMillis * 5);
observedTimeSeries.setTimeSeriesInterval(observedTimeSeriesInterval);
}
return new Object[][] { { properties, timeSeriesKey, bucketSizeInMS, observedTimeSeries } };
}
Aggregations