/// <summary>
        ///  This is a function for analyze one layer for root cause, we select one dimension with values who contributes the most to the anomaly.
        /// </summary>
        private RootCause AnalyzeOneLayer(RootCauseLocalizationInput src)
        {
            RootCause dst = new RootCause();

            dst.Items = new List <RootCauseItem>();

            DimensionInfo dimensionInfo = SeparateDimension(src.AnomalyDimension, src.AggregateSymbol);
            Tuple <PointTree, PointTree, Dictionary <Dictionary <string, object>, TimeSeriesPoint> > pointInfo = GetPointsInfo(src, dimensionInfo);
            PointTree pointTree   = pointInfo.Item1;
            PointTree anomalyTree = pointInfo.Item2;
            Dictionary <Dictionary <string, Object>, TimeSeriesPoint> dimPointMapping = pointInfo.Item3;

            //which means there is no anomaly point with the anomaly dimension or no point under anomaly dimension
            if (anomalyTree.ParentNode == null || dimPointMapping.Count == 0)
            {
                return(dst);
            }

            dst.Items.AddRange(LocalizeRootCauseByDimension(anomalyTree, pointTree, src.AnomalyDimension, dimensionInfo.AggDims));
            GetRootCauseDirectionAndScore(dimPointMapping, src.AnomalyDimension, dst, _beta, pointTree, src.AggregateType, src.AggregateSymbol);

            return(dst);
        }
Beispiel #2
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);
                }
            }
        }
Beispiel #3
0
        private void LocalizeRootCausesByDimension(PointTree anomalyTree, PointTree pointTree, Dictionary <string, Object> anomalyDimension, List <string> aggDims)
        {
            IEnumerable <BestDimension> best;

            if (anomalyTree.ChildrenNodes.Count == 0)
            {
                //has no children node information, should use the leaves node (whose point has no aggregated dimensions) information
                best = SelectOrderedDimension(pointTree.Leaves, anomalyTree.Leaves, aggDims);
            }
            else
            {
                //has no leaves information, should calculate the entropy information according to the children nodes
                best = SelectOrderedDimensions(pointTree.ChildrenNodes, anomalyTree.ChildrenNodes, aggDims);
            }

            if (best == null)
            {
                _preparedCauses.Add(new RootCause {
                    Items = new List <RootCauseItem>()
                    {
                        new RootCauseItem(anomalyDimension)
                    }
                });
            }

            bool rootAsAnomaly = false;

            foreach (var dimension in best)
            {
                RootCause rootCause = new RootCause {
                    Items = new List <RootCauseItem>()
                };

                rootCause.GainRatio = dimension.GainRatio;
                List <TimeSeriesPoint> children = null;
                if (anomalyTree.ChildrenNodes.ContainsKey(dimension.DimensionKey))
                {
                    //Use children node information to get top anomalies
                    children = GetTopAnomaly(anomalyTree.ChildrenNodes[dimension.DimensionKey], anomalyTree.ParentNode, pointTree.ChildrenNodes[dimension.DimensionKey].Count > 0 ? pointTree.ChildrenNodes[dimension.DimensionKey] : pointTree.Leaves, dimension.DimensionKey, !(pointTree.ChildrenNodes[dimension.DimensionKey].Count > 0));
                }
                else
                {
                    //Use leaves node informatin to get top anomalies
                    children = GetTopAnomaly(anomalyTree.Leaves, anomalyTree.ParentNode, pointTree.Leaves, dimension.DimensionKey, true);
                }

                if (children == null)
                {
                    //As the cause couldn't be found, the root cause should be itself
                    if (!rootAsAnomaly)
                    {
                        rootAsAnomaly = true;
                        rootCause.Items.Add(new RootCauseItem(anomalyDimension));
                    }
                }
                else
                {
                    rootCause.Items.AddRange(children.Select(anomaly =>
                                                             new RootCauseItem(UpdateDimensionValue(anomalyDimension, dimension.DimensionKey, anomaly.Dimension[dimension.DimensionKey]), new List <string>()
                    {
                        dimension.DimensionKey
                    })));
                }

                _preparedCauses.Add(rootCause);
            }
        }