예제 #1
0
        private void BuildTree(PointTree tree, List <string> aggDims, TimeSeriesPoint point, Object aggSymbol)
        {
            int    aggNum  = 0;
            string nextDim = null;

            foreach (string dim in aggDims)
            {
                if (IsAggregationDimension(point.Dimension[dim], aggSymbol))
                {
                    aggNum++;
                }
                else
                {
                    nextDim = dim;
                }
            }

            if (aggNum == aggDims.Count)
            {
                tree.ParentNode = point;
            }
            else if (aggNum == aggDims.Count - 1)
            {
                if (!tree.ChildrenNodes.ContainsKey(nextDim))
                {
                    tree.ChildrenNodes.Add(nextDim, new List <TimeSeriesPoint>());
                }
                tree.ChildrenNodes[nextDim].Add(point);
            }

            if (aggNum == 0)
            {
                tree.Leaves.Add(point);
            }
        }
예제 #2
0
        private Tuple <double, double> GetSurpriseAndExplanatoryScore(TimeSeriesPoint rootCausePoint, TimeSeriesPoint anomalyPoint)
        {
            double surprise = GetSurpriseScore(rootCausePoint, anomalyPoint);

            double ep = anomalyPoint.Value - anomalyPoint.ExpectedValue == 0 ? 0 : Math.Abs((rootCausePoint.Value - rootCausePoint.ExpectedValue) / (anomalyPoint.Value - anomalyPoint.ExpectedValue));

            return(new Tuple <double, double>(surprise, ep));
        }
예제 #3
0
        private void GetRootCauseDirectionAndScore(Dictionary <Dictionary <string, Object>, TimeSeriesPoint> dimPointMapping, Dictionary <string, Object> anomalyRoot, RootCause dst, double beta, PointTree pointTree, AggregateType aggType, Object aggSymbol)
        {
            TimeSeriesPoint anomalyPoint = GetPointByDimension(dimPointMapping, anomalyRoot, pointTree, aggType, aggSymbol);

            if (dst.Items.Count > 1)
            {
                //get surprise value and explanatory power value
                List <RootCauseScore> scoreList = new List <RootCauseScore>();

                foreach (RootCauseItem item in dst.Items)
                {
                    TimeSeriesPoint rootCausePoint = GetPointByDimension(dimPointMapping, item.Dimension, pointTree, aggType, aggSymbol);
                    if (anomalyPoint != null && rootCausePoint != null)
                    {
                        Tuple <double, double> scores = GetSurpriseAndExplanatoryScore(rootCausePoint, anomalyPoint);
                        scoreList.Add(new RootCauseScore(scores.Item1, scores.Item2));
                        item.Direction = GetRootCauseDirection(rootCausePoint);
                    }
                }

                //get final score
                for (int i = 0; i < scoreList.Count; i++)
                {
                    if (aggType.Equals(AggregateType.Max) || aggType.Equals(AggregateType.Min))
                    {
                        dst.Items[i].Score = 1;
                    }
                    else
                    {
                        dst.Items[i].Score = GetFinalScore(scoreList[i].Surprise, Math.Abs(scoreList[i].ExplanatoryScore), beta);
                    }
                }
            }
            else if (dst.Items.Count == 1)
            {
                TimeSeriesPoint rootCausePoint = GetPointByDimension(dimPointMapping, dst.Items[0].Dimension, pointTree, aggType, aggSymbol);
                if (anomalyPoint != null && rootCausePoint != null)
                {
                    Tuple <double, double> scores = GetSurpriseAndExplanatoryScore(rootCausePoint, anomalyPoint);
                    if (aggType.Equals(AggregateType.Max) || aggType.Equals(AggregateType.Min))
                    {
                        dst.Items[0].Score = 1;
                    }
                    else
                    {
                        dst.Items[0].Score = GetFinalScore(scores.Item1, scores.Item2, beta);
                    }
                    dst.Items[0].Direction = GetRootCauseDirection(rootCausePoint);
                }
            }
        }
예제 #4
0
 private AnomalyDirection GetRootCauseDirection(TimeSeriesPoint rootCausePoint)
 {
     if (rootCausePoint.ExpectedValue < rootCausePoint.Value)
     {
         return(AnomalyDirection.Up);
     }
     else if (rootCausePoint.ExpectedValue > rootCausePoint.Value)
     {
         return(AnomalyDirection.Down);
     }
     else
     {
         return(AnomalyDirection.Same);
     }
 }
예제 #5
0
        /// <summary>
        /// Calculate the surprise score according to root cause point and anomaly point
        /// </summary>
        /// <param name="rootCausePoint">A point which has been detected as root cause</param>
        /// <param name="anomalyPoint">The anomaly point</param>
        /// <remarks>
        /// <format type="text/markdown">
        ///  [!include[io](~/../docs/samples/docs/api-reference/time-series-root-cause-surprise-score.md)]
        /// </format>
        /// </remarks>
        /// <returns>Surprise score</returns>
        private double GetSurpriseScore(TimeSeriesPoint rootCausePoint, TimeSeriesPoint anomalyPoint)
        {
            double p;
            double q;

            if (anomalyPoint.ExpectedValue == 0)
            {
                p = 0;
            }
            else
            {
                p = rootCausePoint.ExpectedValue / anomalyPoint.ExpectedValue;
            }

            if (anomalyPoint.Value == 0)
            {
                q = 0;
            }
            else
            {
                q = rootCausePoint.Value / anomalyPoint.Value;
            }

            double surprise = 0;

            if (p == 0)
            {
                surprise = 0.5 * (q * Log2(2 * q / (p + q)));
            }
            else if (q == 0)
            {
                surprise = 0.5 * (p * Log2(2 * p / (p + q)));
            }
            else
            {
                surprise = 0.5 * (p * Log2(2 * p / (p + q)) + q * Log2(2 * q / (p + q)));
            }

            return(surprise);
        }
예제 #6
0
        private TimeSeriesPoint GetPointByDimension(Dictionary <Dictionary <string, Object>, TimeSeriesPoint> dimPointMapping, Dictionary <string, Object> dimension, PointTree pointTree, AggregateType aggType, Object aggSymbol)
        {
            if (dimPointMapping.ContainsKey(dimension))
            {
                return(dimPointMapping[dimension]);
            }

            int                         count         = 0;
            TimeSeriesPoint             p             = new TimeSeriesPoint(dimension);
            DimensionInfo               dimensionInfo = SeparateDimension(dimension, aggSymbol);
            Dictionary <string, Object> subDim        = GetSubDim(dimension, dimensionInfo.DetailDims);

            foreach (TimeSeriesPoint leave in pointTree.Leaves)
            {
                if (ContainsAll(leave.Dimension, subDim))
                {
                    count++;

                    p.Value         = +leave.Value;
                    p.ExpectedValue = +leave.ExpectedValue;
                    p.Delta         = +leave.Delta;
                }
            }
            if (aggType.Equals(AggregateType.Avg))
            {
                p.Value         = p.Value / count;
                p.ExpectedValue = p.ExpectedValue / count;
                p.Delta         = p.Delta / count;
            }

            if (count > 0)
            {
                return(p);
            }
            else
            {
                return(null);
            }
        }
예제 #7
0
        protected List <TimeSeriesPoint> GetTopAnomaly(List <TimeSeriesPoint> anomalyPoints, TimeSeriesPoint root, List <TimeSeriesPoint> totalPoints, string dimKey, bool isLeaveslevel = false)
        {
            Dictionary <string, int> pointDistribution = new Dictionary <string, int>();

            UpdateDistribution(pointDistribution, totalPoints, dimKey);

            anomalyPoints = anomalyPoints.OrderBy(x => x.Delta).ToList();

            if (root.Delta > 0)
            {
                anomalyPoints.Reverse();
            }
            else
            {
                anomalyPoints = anomalyPoints.FindAll(x => x.Delta < 0);
            }
            if (anomalyPoints.Count == 1)
            {
                return(anomalyPoints);
            }

            double delta    = 0;
            double preDelta = 0;
            List <TimeSeriesPoint> causeList = new List <TimeSeriesPoint>();

            foreach (TimeSeriesPoint anomaly in anomalyPoints)
            {
                if (StopAnomalyComparison(delta, root.Delta, anomaly.Delta, preDelta))
                {
                    break;
                }

                delta += anomaly.Delta;
                causeList.Add(anomaly);
                preDelta = anomaly.Delta;
            }

            int pointSize = isLeaveslevel ? pointDistribution.Count : GetTotalNumber(pointDistribution);

            if (ShouldSeparateAnomaly(delta, root.Delta, pointSize, causeList.Count))
            {
                return(causeList);
            }

            return(null);
        }