use of com.amazon.randomcutforest.tree.IBoundingBoxView in project random-cut-forest-by-aws by aws.
the class AnomalyScoreVisitorTest method testAcceptEqualsLeafPoint.
@Test
public void testAcceptEqualsLeafPoint() {
float[] pointToScore = { 0.0f, 0.0f };
int sampleSize = 50;
AnomalyScoreVisitor visitor = new AnomalyScoreVisitor(pointToScore, sampleSize);
float[] point = Arrays.copyOf(pointToScore, pointToScore.length);
INodeView node = mock(NodeView.class);
when(node.getLeafPoint()).thenReturn(point);
when(node.getBoundingBox()).thenReturn(new BoundingBox(point, point));
int depth = 2;
visitor.acceptLeaf(node, depth);
double expectedScore = CommonUtils.defaultDampFunction(node.getMass(), sampleSize) / (depth + Math.log(node.getMass() + 1) / Math.log(2));
assertThat(visitor.getResult(), closeTo(CommonUtils.defaultScalarNormalizerFunction(expectedScore, sampleSize), EPSILON));
depth--;
IBoundingBoxView boundingBox = node.getBoundingBox().getMergedBox(new float[] { 1.0f, 1.0f });
node = new NodeView(null, null, Null);
visitor.accept(node, depth);
assertThat(visitor.getResult(), closeTo(CommonUtils.defaultScalarNormalizerFunction(expectedScore, sampleSize), EPSILON));
depth--;
boundingBox = boundingBox.getMergedBox(new float[] { -1.0f, -1.0f });
node = new NodeView(null, null, Null);
visitor.accept(node, depth);
assertThat(visitor.getResult(), closeTo(CommonUtils.defaultScalarNormalizerFunction(expectedScore, sampleSize), EPSILON));
}
use of com.amazon.randomcutforest.tree.IBoundingBoxView in project random-cut-forest-by-aws by aws.
the class AnomalyScoreVisitorTest method testAccept.
@Test
public void testAccept() {
float[] pointToScore = new float[] { 0.0f, 0.0f };
int sampleSize = 50;
AnomalyScoreVisitor visitor = new AnomalyScoreVisitor(pointToScore, sampleSize);
NodeView node = mock(NodeView.class);
float[] otherPoint = new float[] { 1.0f, 1.0f };
when(node.getLeafPoint()).thenReturn(otherPoint);
when(node.getBoundingBox()).thenReturn(new BoundingBox(otherPoint, otherPoint));
int depth = 4;
visitor.acceptLeaf(node, depth);
double expectedScore = 1.0 / (depth + 1);
assertThat(visitor.getResult(), closeTo(CommonUtils.defaultScalarNormalizerFunction(expectedScore, sampleSize), EPSILON));
depth--;
IBoundingBoxView boundingBox = node.getBoundingBox().getMergedBox(new float[] { 2.0f, 0.0f });
when(node.getBoundingBox()).thenReturn(boundingBox);
when(node.probailityOfSeparation(any())).thenReturn(1.0 / 3);
visitor.accept(node, depth);
double p = visitor.getProbabilityOfSeparation(boundingBox);
expectedScore = p * (1.0 / (depth + 1)) + (1 - p) * expectedScore;
assertThat(visitor.getResult(), closeTo(CommonUtils.defaultScalarNormalizerFunction(expectedScore, sampleSize), EPSILON));
depth--;
boundingBox = boundingBox.getMergedBox(new float[] { -1.0f, 0.0f });
when(node.getBoundingBox()).thenReturn(boundingBox);
when(node.probailityOfSeparation(any())).thenReturn(0.0);
visitor.accept(node, depth);
p = visitor.getProbabilityOfSeparation(boundingBox);
expectedScore = p * (1.0 / (depth + 1)) + (1 - p) * expectedScore;
assertThat(visitor.getResult(), closeTo(CommonUtils.defaultScalarNormalizerFunction(expectedScore, sampleSize), EPSILON));
depth--;
boundingBox = boundingBox.getMergedBox(new float[] { -1.0f, -1.0f });
when(node.probailityOfSeparation(any())).thenReturn(0.0);
visitor.accept(node, depth);
p = visitor.getProbabilityOfSeparation(boundingBox);
assertThat(visitor.getResult(), closeTo(CommonUtils.defaultScalarNormalizerFunction(expectedScore, sampleSize), EPSILON));
assertTrue(visitor.pointInsideBox);
}
use of com.amazon.randomcutforest.tree.IBoundingBoxView in project random-cut-forest-by-aws by aws.
the class ImputeVisitorTest method testAccept.
@Test
public void testAccept() {
float[] point = { queryPoint[0], 2.0f, -111.11f };
INodeView node = mock(NodeView.class);
when(node.getLeafPoint()).thenReturn(point);
when(node.getLiftedLeafPoint()).thenReturn(point);
when(node.getBoundingBox()).thenReturn(new BoundingBox(point, point));
int depth = 100;
int leafMass = 10;
when(node.getMass()).thenReturn(leafMass);
visitor.acceptLeaf(node, depth);
float[] expected = new float[] { -1.0f, 2.0f, 3.0f };
assertArrayEquals(expected, visitor.getResult().leafPoint);
assertEquals(defaultScoreUnseenFunction(depth, leafMass), visitor.getAnomalyRank());
depth--;
IBoundingBoxView boundingBox = node.getBoundingBox().getMergedBox(new float[] { 99.0f, 4.0f, -19.0f });
when(node.getBoundingBox()).thenReturn(boundingBox);
when(node.probailityOfSeparation(any())).thenReturn(CommonUtils.getProbabilityOfSeparation(boundingBox, expected));
when(node.getMass()).thenReturn(leafMass + 2);
double oldRank = visitor.getAnomalyRank();
visitor.accept(node, depth);
assertArrayEquals(expected, visitor.getResult().leafPoint);
double p = CommonUtils.getProbabilityOfSeparation(boundingBox, expected);
double expectedRank = p * defaultScoreUnseenFunction(depth, node.getMass()) + (1 - p) * oldRank;
assertEquals(expectedRank, visitor.getAnomalyRank(), EPSILON);
}
use of com.amazon.randomcutforest.tree.IBoundingBoxView in project random-cut-forest-by-aws by aws.
the class RandomCutForest method getDynamicSimulatedScore.
/**
* Similar to above but now the scoring takes in a function of Bounding Box to
* probabilities (vector over the dimensions); and produces a score af-if the
* tree were built using that function (when in reality the tree is an RCF).
* Changing the defaultRCFgVec function to some other function f() will provide
* a mechanism of dynamic scoring for trees that are built using f() which is
* the purpose of TransductiveScalarScore visitor. Note that the answer is an
* MCMC simulation and is not normalized (because the scoring functions are
* flexible and unknown) and over a small number of trees the errors can be
* large specially if vecSep is very far from defaultRCFgVec
*
* Given the large number of possible sources of distortion, ignoreLeafThreshold
* is not supported.
*
* @param point point to be scored
* @param seen the score function for seen point
* @param unseen score function for unseen points
* @param damp dampening the score for duplicates
* @param vecSep the function of (BoundingBox) -> array of probabilities
* @return the simuated score
*/
public double getDynamicSimulatedScore(float[] point, BiFunction<Double, Double, Double> seen, BiFunction<Double, Double, Double> unseen, BiFunction<Double, Double, Double> damp, Function<IBoundingBoxView, double[]> vecSep) {
if (!isOutputReady()) {
return 0.0;
}
VisitorFactory<Double> visitorFactory = new VisitorFactory<>((tree, y) -> new SimulatedTransductiveScalarScoreVisitor(tree.projectToTree(y), tree.getMass(), seen, unseen, damp, CommonUtils::defaultRCFgVecFunction, vecSep));
BinaryOperator<Double> accumulator = Double::sum;
Function<Double, Double> finisher = sum -> sum / numberOfTrees;
return traverseForest(transformToShingledPoint(point), visitorFactory, accumulator, finisher);
}
use of com.amazon.randomcutforest.tree.IBoundingBoxView in project random-cut-forest-by-aws by aws.
the class SimpleInterpolationVisitor method accept.
@Override
public void accept(INodeView node, int depthOfNode) {
if (pointInsideBox) {
return;
}
IBoundingBoxView largeBox;
IBoundingBoxView smallBox;
if (pointEqualsLeaf) {
largeBox = node.getBoundingBox();
theShadowBox = theShadowBox == null ? node.getSiblingBoundingBox(pointToScore) : theShadowBox.getMergedBox(node.getSiblingBoundingBox(pointToScore));
smallBox = theShadowBox;
} else {
smallBox = node.getBoundingBox();
largeBox = smallBox.getMergedBox(pointToScore);
}
updateForCompute(smallBox, largeBox);
double probOfCut = sumOfDifferenceInRange / sumOfNewRange;
if (probOfCut <= 0) {
pointInsideBox = true;
} else {
double fieldVal = fieldExt(node, centerOfMass, savedMass, pointToScore);
double influenceVal = influenceExt(node, centerOfMass, savedMass, pointToScore);
// otherwise the center of mass is the 0 vector
for (int i = 0; i < pointToScore.length; i++) {
double prob = differenceInRangeVector[2 * i] / sumOfNewRange;
stored.probMass.high[i] = prob * influenceVal + (1 - probOfCut) * stored.probMass.high[i];
stored.measure.high[i] = prob * fieldVal + (1 - probOfCut) * stored.measure.high[i];
stored.distances.high[i] = prob * directionalDistanceVector[2 * i] * influenceVal + (1 - probOfCut) * stored.distances.high[i];
}
for (int i = 0; i < pointToScore.length; i++) {
double prob = differenceInRangeVector[2 * i + 1] / sumOfNewRange;
stored.probMass.low[i] = prob * influenceVal + (1 - probOfCut) * stored.probMass.low[i];
stored.measure.low[i] = prob * fieldVal + (1 - probOfCut) * stored.measure.low[i];
stored.distances.low[i] = prob * directionalDistanceVector[2 * i + 1] * influenceVal + (1 - probOfCut) * stored.distances.low[i];
}
}
}
Aggregations