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);
            }
        }
Пример #2
0
 private BestDimension GetBestDimension(BestDimension best, KeyValuePair <BestDimension, double> dimension, Dictionary <BestDimension, Double> valueRatioMap)
 {
     if (valueRatioMap[best].CompareTo(dimension.Value) == 0)
     {
         if (dimension.Key.AnomalyDis.Count != dimension.Key.PointDis.Count)
         {
             best = dimension.Key;
         }
     }
     else
     {
         best = dimension.Key;
     }
     return(best);
 }
Пример #3
0
        public int CompareTo(object obj)
        {
            if (obj == null)
            {
                return(1);
            }

            BestDimension other = obj as BestDimension;

            if (other != null)
            {
                return(DimensionKey.CompareTo(other.DimensionKey));
            }
            else
            {
                throw new ArgumentException("Object is not a BestDimension");
            }
        }
        /// <summary>
        ///  Use children point information to select best dimension
        /// </summary>
        private BestDimension SelectBestDimension(Dictionary <string, List <TimeSeriesPoint> > pointChildren, Dictionary <string, List <TimeSeriesPoint> > anomalyChildren, List <string> aggDim)
        {
            SortedDictionary <BestDimension, double> entropyMap      = new SortedDictionary <BestDimension, double>();
            Dictionary <BestDimension, double>       entropyRatioMap = new Dictionary <BestDimension, double>();
            double sumGain = 0;

            foreach (string dimKey in aggDim)
            {
                BestDimension dimension = new BestDimension();
                dimension.DimensionKey = dimKey;

                if (pointChildren.ContainsKey(dimKey))
                {
                    UpdateDistribution(dimension.PointDis, pointChildren[dimKey], dimKey);
                }
                if (anomalyChildren.ContainsKey(dimKey))
                {
                    UpdateDistribution(dimension.AnomalyDis, anomalyChildren[dimKey], dimKey);
                }

                double entropy = GetEntropy(dimension.PointDis.Count, dimension.AnomalyDis.Count);
                if (Double.IsNaN(entropy))
                {
                    entropy = Double.MaxValue;
                }
                entropyMap.Add(dimension, entropy);

                double gainRatio = entropy / GetDimensionIntrinsicValue(dimension.PointDis);

                if (Double.IsInfinity(gainRatio))
                {
                    gainRatio = 0;
                }
                entropyRatioMap.Add(dimension, gainRatio);

                sumGain += entropy;
            }

            double meanGain = sumGain / aggDim.Count;

            BestDimension best = FindBestDimension(entropyMap, entropyRatioMap, meanGain, false);

            return(best);
        }
        private BestDimension FindBestDimension(SortedDictionary <BestDimension, double> valueMap, Dictionary <BestDimension, double> valueRatioMap, double meanGain, bool isLeavesLevel = true)
        {
            BestDimension best = null;

            foreach (KeyValuePair <BestDimension, double> dimension in valueMap)
            {
                if (dimension.Key.AnomalyDis.Count == 1 || (isLeavesLevel ? dimension.Value >= meanGain : dimension.Value <= meanGain))
                {
                    if (best == null)
                    {
                        best = dimension.Key;
                    }
                    else
                    {
                        bool isRatioNan = Double.IsNaN(valueRatioMap[best]);
                        if (dimension.Key.AnomalyDis.Count > 1)
                        {
                            if (best.AnomalyDis.Count != 1 && !isRatioNan && (isLeavesLevel ? valueRatioMap[best].CompareTo(dimension.Value) <= 0 : valueRatioMap[best].CompareTo(dimension.Value) >= 0))
                            {
                                best = GetBestDimension(best, dimension, valueRatioMap);
                            }
                        }
                        else if (dimension.Key.AnomalyDis.Count == 1)
                        {
                            if (best.AnomalyDis.Count > 1)
                            {
                                best = dimension.Key;
                            }
                            else if (best.AnomalyDis.Count == 1)
                            {
                                if (!isRatioNan && (isLeavesLevel ? valueRatioMap[best].CompareTo(dimension.Value) <= 0 : valueRatioMap[best].CompareTo(dimension.Value) >= 0))
                                {
                                    best = GetBestDimension(best, dimension, valueRatioMap);
                                }
                            }
                        }
                    }
                }
            }

            return(best);
        }
Пример #6
0
        /// <summary>
        ///  Use leaves point information to select ordered dimensions
        /// </summary>
        protected IEnumerable <BestDimension> SelectOrderedDimension(List <TimeSeriesPoint> totalPoints, List <TimeSeriesPoint> anomalyPoints, List <string> aggDim)
        {
            double totalEntropy = GetEntropy(totalPoints.Count, anomalyPoints.Count);
            SortedDictionary <BestDimension, double> entropyGainMap     = new SortedDictionary <BestDimension, double>();
            Dictionary <BestDimension, double>       entroyGainRatioMap = new Dictionary <BestDimension, double>();
            double sumGain = 0;

            foreach (string dimKey in aggDim)
            {
                BestDimension dimension = new BestDimension();
                dimension.DimensionKey = dimKey;

                UpdateDistribution(dimension.PointDis, totalPoints, dimKey);
                UpdateDistribution(dimension.AnomalyDis, anomalyPoints, dimKey);

                double relativeEntropy = GetDimensionEntropy(dimension.PointDis, dimension.AnomalyDis);
                double gain            = totalEntropy - relativeEntropy;
                if (Double.IsNaN(gain))
                {
                    gain = 0;
                }
                entropyGainMap.Add(dimension, gain);
                dimension.Gain = gain;

                double gainRatio = gain / GetDimensionIntrinsicValue(dimension.PointDis);
                if (Double.IsInfinity(gainRatio))
                {
                    gainRatio = 0;
                }
                entroyGainRatioMap.Add(dimension, gainRatio);
                dimension.GainRatio = gainRatio;

                sumGain += gain;
            }

            double meanGain = sumGain / aggDim.Count();

            return(OrderDimensions(entropyGainMap, entroyGainRatioMap, meanGain));
        }