use of org.opensearch.ad.ml.ThresholdingResult in project anomaly-detection by opensearch-project.
the class AnomalyDetectorRunner method parsePreviewResult.
private List<AnomalyResult> parsePreviewResult(AnomalyDetector detector, Features features, List<ThresholdingResult> results, Entity entity) {
// unprocessedFeatures[][], each row is for one date range.
// For example, unprocessedFeatures[0][2] is for the first time range, the third feature
double[][] unprocessedFeatures = features.getUnprocessedFeatures();
List<Map.Entry<Long, Long>> timeRanges = features.getTimeRanges();
List<Feature> featureAttributes = detector.getFeatureAttributes().stream().filter(Feature::getEnabled).collect(Collectors.toList());
List<AnomalyResult> anomalyResults = new ArrayList<>();
if (timeRanges != null && timeRanges.size() > 0) {
for (int i = 0; i < timeRanges.size(); i++) {
Map.Entry<Long, Long> timeRange = timeRanges.get(i);
List<FeatureData> featureDatas = new ArrayList<>();
int featureSize = featureAttributes.size();
for (int j = 0; j < featureSize; j++) {
double value = unprocessedFeatures[i][j];
Feature feature = featureAttributes.get(j);
FeatureData data = new FeatureData(feature.getId(), feature.getName(), value);
featureDatas.add(data);
}
AnomalyResult result;
if (results != null && results.size() > i) {
ThresholdingResult thresholdingResult = results.get(i);
result = thresholdingResult.toAnomalyResult(detector, Instant.ofEpochMilli(timeRange.getKey()), Instant.ofEpochMilli(timeRange.getValue()), null, null, featureDatas, entity, CommonValue.NO_SCHEMA_VERSION, null, null, null);
} else {
result = new AnomalyResult(detector.getDetectorId(), null, featureDatas, Instant.ofEpochMilli(timeRange.getKey()), Instant.ofEpochMilli(timeRange.getValue()), null, null, null, entity, detector.getUser(), CommonValue.NO_SCHEMA_VERSION, null);
}
anomalyResults.add(result);
}
}
return anomalyResults;
}
use of org.opensearch.ad.ml.ThresholdingResult in project anomaly-detection by opensearch-project.
the class AnomalyDetectorRunner method executeDetector.
/**
* run anomaly detector and return anomaly result.
*
* @param detector anomaly detector instance
* @param startTime detection period start time
* @param endTime detection period end time
* @param context stored thread context
* @param listener handle anomaly result
* @throws IOException - if a user gives wrong query input when defining a detector
*/
public void executeDetector(AnomalyDetector detector, Instant startTime, Instant endTime, ThreadContext.StoredContext context, ActionListener<List<AnomalyResult>> listener) throws IOException {
context.restore();
List<String> categoryField = detector.getCategoryField();
if (categoryField != null && !categoryField.isEmpty()) {
featureManager.getPreviewEntities(detector, startTime.toEpochMilli(), endTime.toEpochMilli(), ActionListener.wrap(entities -> {
if (entities == null || entities.isEmpty()) {
// TODO return exception like IllegalArgumentException to explain data is not enough for preview
// This also requires front-end change to handle error message correspondingly
// We return empty list for now to avoid breaking front-end
listener.onResponse(Collections.emptyList());
return;
}
ActionListener<EntityAnomalyResult> entityAnomalyResultListener = ActionListener.wrap(entityAnomalyResult -> {
listener.onResponse(entityAnomalyResult.getAnomalyResults());
}, e -> onFailure(e, listener, detector.getDetectorId()));
MultiResponsesDelegateActionListener<EntityAnomalyResult> multiEntitiesResponseListener = new MultiResponsesDelegateActionListener<EntityAnomalyResult>(entityAnomalyResultListener, entities.size(), String.format(Locale.ROOT, "Fail to get preview result for multi entity detector %s", detector.getDetectorId()), true);
for (Entity entity : entities) {
featureManager.getPreviewFeaturesForEntity(detector, entity, startTime.toEpochMilli(), endTime.toEpochMilli(), ActionListener.wrap(features -> {
List<ThresholdingResult> entityResults = modelManager.getPreviewResults(features.getProcessedFeatures(), detector.getShingleSize());
List<AnomalyResult> sampledEntityResults = sample(parsePreviewResult(detector, features, entityResults, entity), maxPreviewResults);
multiEntitiesResponseListener.onResponse(new EntityAnomalyResult(sampledEntityResults));
}, e -> multiEntitiesResponseListener.onFailure(e)));
}
}, e -> onFailure(e, listener, detector.getDetectorId())));
} else {
featureManager.getPreviewFeatures(detector, startTime.toEpochMilli(), endTime.toEpochMilli(), ActionListener.wrap(features -> {
try {
List<ThresholdingResult> results = modelManager.getPreviewResults(features.getProcessedFeatures(), detector.getShingleSize());
listener.onResponse(sample(parsePreviewResult(detector, features, results, null), maxPreviewResults));
} catch (Exception e) {
onFailure(e, listener, detector.getDetectorId());
}
}, e -> onFailure(e, listener, detector.getDetectorId())));
}
}
Aggregations