Example #1
0
        private Tuple <PointTree, PointTree, Dictionary <Dictionary <string, object>, TimeSeriesPoint> > GetPointsInfo(RootCauseLocalizationInput src, DimensionInfo dimensionInfo)
        {
            PointTree         pointTree   = new PointTree();
            PointTree         anomalyTree = new PointTree();
            DimensionComparer dc          = new DimensionComparer();
            Dictionary <Dictionary <string, object>, TimeSeriesPoint> dimPointMapping = new Dictionary <Dictionary <string, object>, TimeSeriesPoint>(dc);

            List <TimeSeriesPoint>      totalPoints = GetTotalPointsForAnomalyTimestamp(src);
            Dictionary <string, Object> subDim      = GetSubDim(src.AnomalyDimension, dimensionInfo.DetailDims);

            foreach (TimeSeriesPoint point in totalPoints)
            {
                if (ContainsAll(point.Dimension, subDim))
                {
                    if (!dimPointMapping.ContainsKey(point.Dimension))
                    {
                        dimPointMapping.Add(point.Dimension, point);
                        bool isValidPoint = point.IsAnomaly == true;
                        if (ContainsAll(point.Dimension, subDim))
                        {
                            BuildTree(pointTree, dimensionInfo.AggDims, point, src.AggregateSymbol);

                            if (isValidPoint)
                            {
                                BuildTree(anomalyTree, dimensionInfo.AggDims, point, src.AggregateSymbol);
                            }
                        }
                    }
                }
            }

            return(new Tuple <PointTree, PointTree, Dictionary <Dictionary <string, Object>, TimeSeriesPoint> >(pointTree, anomalyTree, dimPointMapping));
        }
Example #2
0
        /// <summary>
        ///  This is a function for analyzing one layer for root cause. We rank dimensions according to their likelihood of containing the root case.
        ///  For each dimension, we select one dimension with values who contributes the most to the anomaly.
        /// </summary>
        private List <RootCause> AnalyzeOneLayer(RootCauseLocalizationInput src)
        {
            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)
            {
                _preparedCauses.Add(new RootCause()
                {
                    Items = new List <RootCauseItem>()
                });
                return(_preparedCauses);
            }

            LocalizeRootCausesByDimension(anomalyTree, pointTree, src.AnomalyDimension, dimensionInfo.AggDims);
            foreach (var dst in _preparedCauses)
            {
                GetRootCauseDirectionAndScore(dimPointMapping, src.AnomalyDimension, dst, _beta, pointTree, src.AggregateType, src.AggregateSymbol);
            }

            return(_preparedCauses);
        }
Example #3
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);
            }
        }
        private List <RootCauseItem> LocalizeRootCauseByDimension(PointTree anomalyTree, PointTree pointTree, Dictionary <string, Object> anomalyDimension, List <string> aggDims)
        {
            BestDimension best = null;

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

            if (best == null)
            {
                return(new List <RootCauseItem>()
                {
                    new RootCauseItem(anomalyDimension)
                });
            }

            List <TimeSeriesPoint> children = null;

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

            if (children == null)
            {
                //As the cause couldn't be found, the root cause should be itself
                return(new List <RootCauseItem>()
                {
                    new RootCauseItem(anomalyDimension)
                });
            }
            else
            {
                List <RootCauseItem> causes = new List <RootCauseItem>();
                // For the found causes, we return the result
                foreach (TimeSeriesPoint anomaly in children)
                {
                    causes.Add(new RootCauseItem(UpdateDimensionValue(anomalyDimension, best.DimensionKey, anomaly.Dimension[best.DimensionKey]), new List <string>()
                    {
                        best.DimensionKey
                    }));
                }
                return(causes);
            }
        }
Example #5
0
        /// <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 <string, TimeSeriesPoint> > pointInfo = GetPointsInfo(src, dimensionInfo);
            PointTree pointTree   = pointInfo.Item1;
            PointTree anomalyTree = pointInfo.Item2;
            Dictionary <string, 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);
        }
Example #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);
            }
        }
Example #7
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);
                }
            }
        }
Example #8
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);
            }
        }