use of com.amazon.randomcutforest.returntypes.DiVector in project random-cut-forest-by-aws by aws.
the class Preprocessor method addRelevantAttribution.
/**
* adds information of expected point to the result descriptor (provided it is
* marked anomalous) Note that is uses relativeIndex; that is, it can determine
* that the anomaly occurred in the past (but within the shingle) and not at the
* current point -- even though the detection has triggered now While this may
* appear to be improper, information theoretically we may have a situation
* where an anomaly is only discoverable after the "horse has bolted" -- suppose
* that we see a random mixture of the triples { 1, 2, 3} and {2, 4, 5}
* corresponding to "slow weeks" and "busy weeks". For example 1, 2, 3, 1, 2, 3,
* 2, 4, 5, 1, 2, 3, 2, 4, 5, ... etc. If we see { 2, 2, X } (at positions 0 and
* 1 (mod 3)) and are yet to see X, then we can infer that the pattern is
* anomalous -- but we cannot determine which of the 2's are to blame. If it
* were the first 2, then the detection is late. If X = 3 then we know it is the
* first 2 in that unfinished triple; and if X = 5 then it is the second 2. In a
* sense we are only truly wiser once the bolted horse has returned! But if we
* were to say that the anomaly was always at the second 2 then that appears to
* be suboptimal -- one natural path can be based on the ratio of the triples {
* 1, 2, 3} and {2, 4, 5} seen before. Even better, we can attempt to estimate a
* dynamic time dependent ratio -- and that is what RCF would do.
*
* @param result the description of the current point
*/
protected void addRelevantAttribution(AnomalyDescriptor result) {
int base = dimension / shingleSize;
double[] reference = result.getCurrentInput();
double[] point = result.getRCFPoint();
double[] newPoint = result.getExpectedRCFPoint();
int index = result.getRelativeIndex();
if (newPoint != null) {
if (index < 0 && result.isStartOfAnomaly()) {
reference = getShingledInput(shingleSize + index);
result.setPastValues(reference);
result.setPastTimeStamp(getTimeStamp(shingleSize - 1 + index));
}
if (mode == ForestMode.TIME_AUGMENTED) {
int endPosition = (shingleSize - 1 + index + 1) * dimension / shingleSize;
double timeGap = (newPoint[endPosition - 1] - point[endPosition - 1]);
long expectedTimestamp = (timeGap == 0) ? getTimeStamp(shingleSize - 1 + index) : inverseMapTime(timeGap, index);
result.setExpectedTimeStamp(expectedTimestamp);
}
double[] values = getExpectedValue(index, reference, point, newPoint);
result.setExpectedValues(0, values, 1.0);
}
int startPosition = (shingleSize - 1 + result.getRelativeIndex()) * base;
DiVector attribution = result.getAttribution();
if (mode == ForestMode.TIME_AUGMENTED) {
--base;
}
double[] flattenedAttribution = new double[base];
for (int i = 0; i < base; i++) {
flattenedAttribution[i] = attribution.getHighLowSum(startPosition + i);
}
result.setRelevantAttribution(flattenedAttribution);
if (mode == ForestMode.TIME_AUGMENTED) {
result.setTimeAttribution(attribution.getHighLowSum(startPosition + base));
}
}
use of com.amazon.randomcutforest.returntypes.DiVector in project random-cut-forest-by-aws by aws.
the class AnomalyAttributionRunnerTest method testAnomalyAttributionTransformer.
@Test
public void testAnomalyAttributionTransformer() {
RandomCutForest forest = mock(RandomCutForest.class);
when(forest.getDimensions()).thenReturn(2);
AnomalyAttributionRunner.AnomalyAttributionTransformer transformer = new AnomalyAttributionRunner.AnomalyAttributionTransformer(forest);
DiVector vector = new DiVector(2);
vector.low[0] = 1.1;
vector.high[1] = 2.2;
when(forest.getAnomalyAttribution(new double[] { 1.0, 2.0 })).thenReturn(vector);
assertEquals(Arrays.asList("1.1", "0.0", "0.0", "2.2"), transformer.getResultValues(1.0, 2.0));
assertEquals(Arrays.asList("anomaly_low_0", "anomaly_high_0", "anomaly_low_1", "anomaly_high_1"), transformer.getResultColumnNames());
assertEquals(Arrays.asList("NA", "NA", "NA", "NA"), transformer.getEmptyResultValue());
}
use of com.amazon.randomcutforest.returntypes.DiVector in project random-cut-forest-by-aws by aws.
the class AnomalyAttributionVisitorTest method testNew.
@Test
public void testNew() {
float[] point = new float[] { 1.1f, -2.2f, 3.3f };
int treeMass = 99;
AnomalyAttributionVisitor visitor = new AnomalyAttributionVisitor(point, treeMass);
assertFalse(visitor.pointInsideBox);
for (int i = 0; i < point.length; i++) {
assertFalse(visitor.coordInsideBox[i]);
}
assertFalse(visitor.ignoreLeaf);
assertEquals(0, visitor.ignoreLeafMassThreshold);
DiVector result = visitor.getResult();
double[] zero = new double[point.length];
assertArrayEquals(zero, result.high);
assertArrayEquals(zero, result.low);
}
use of com.amazon.randomcutforest.returntypes.DiVector in project random-cut-forest-by-aws by aws.
the class AnomalyAttributionVisitorTest method testAcceptLeafNotEquals.
@Test
public void testAcceptLeafNotEquals() {
float[] point = new float[] { 1.1f, -2.2f, 3.3f };
float[] anotherPoint = new float[] { -4.0f, 5.0f, 6.0f };
INodeView leafNode = mock(NodeView.class);
when(leafNode.getLeafPoint()).thenReturn(anotherPoint);
when(leafNode.getBoundingBox()).thenReturn(new BoundingBox(anotherPoint, anotherPoint));
int leafDepth = 100;
int leafMass = 4;
when(leafNode.getMass()).thenReturn(leafMass);
int treeMass = 21;
AnomalyAttributionVisitor visitor = new AnomalyAttributionVisitor(point, treeMass, 0);
visitor.acceptLeaf(leafNode, leafDepth);
double expectedScoreSum = defaultScoreUnseenFunction(leafDepth, leafMass);
double sumOfNewRange = (1.1 - (-4.0)) + (5.0 - (-2.2)) + (6.0 - 3.3);
DiVector result = visitor.getResult();
assertEquals(defaultScalarNormalizerFunction(expectedScoreSum * (1.1 - (-4.0)) / sumOfNewRange, treeMass), result.high[0], EPSILON);
assertEquals(0.0, result.low[0]);
assertEquals(0.0, result.high[1]);
assertEquals(defaultScalarNormalizerFunction(expectedScoreSum * (5.0 - (-2.2)) / sumOfNewRange, treeMass), result.low[1], EPSILON);
assertEquals(0.0, result.high[2]);
assertEquals(defaultScalarNormalizerFunction(expectedScoreSum * (6.0 - 3.3) / sumOfNewRange, treeMass), result.low[2], EPSILON);
visitor = new AnomalyAttributionVisitor(point, treeMass, 3);
visitor.acceptLeaf(leafNode, leafDepth);
result = visitor.getResult();
assertEquals(defaultScalarNormalizerFunction(expectedScoreSum * (1.1 - (-4.0)) / sumOfNewRange, treeMass), result.high[0], EPSILON);
assertEquals(0.0, result.low[0]);
assertEquals(0.0, result.high[1]);
assertEquals(defaultScalarNormalizerFunction(expectedScoreSum * (5.0 - (-2.2)) / sumOfNewRange, treeMass), result.low[1], EPSILON);
assertEquals(0.0, result.high[2]);
assertEquals(defaultScalarNormalizerFunction(expectedScoreSum * (6.0 - 3.3) / sumOfNewRange, treeMass), result.low[2], EPSILON);
visitor = new AnomalyAttributionVisitor(point, treeMass, 4);
visitor.acceptLeaf(leafNode, leafDepth);
double expectedScore = expectedScoreSum / (2 * point.length);
result = visitor.getResult();
for (int i = 0; i < point.length; i++) {
assertEquals(defaultScalarNormalizerFunction(expectedScore, treeMass), result.low[i], EPSILON);
assertEquals(defaultScalarNormalizerFunction(expectedScore, treeMass), result.high[i], EPSILON);
}
}
Aggregations