public static void Example()
        {
            // Create a new ML context, for ML.NET operations. It can be used for
            // exception tracking and logging, as well as the source of randomness.
            var mlContext = new MLContext();

            // Create an root cause localization input instance.
            DateTime timestamp = GetTimestamp();
            var      data      = new RootCauseLocalizationInput(timestamp, GetAnomalyDimension(), new List <MetricSlice>()
            {
                new MetricSlice(timestamp, GetPoints())
            }, AggregateType.Sum, AGG_SYMBOL);

            // Get the root cause localization result.
            RootCause prediction = mlContext.AnomalyDetection.LocalizeRootCause(data);

            // Print the localization result.
            int count = 0;

            foreach (RootCauseItem item in prediction.Items)
            {
                count++;
                Console.WriteLine($"Root cause item #{count} ...");
                Console.WriteLine($"Score: {item.Score}, Path: {String.Join(" ",item.Path)}, Direction: {item.Direction}, Dimension:{String.Join(" ", item.Dimension)}");
            }

            //Item #1 ...
            //Score: 0.26670448876705927, Path: DataCenter, Direction: Up, Dimension:[Country, UK] [DeviceType, ##SUM##] [DataCenter, DC1]
        }
        public void RootCauseLocalization()
        {
            // Create an root cause localizatiom input
            var rootCauseLocalizationInput = new RootCauseLocalizationInput(GetRootCauseTimestamp(), GetRootCauseAnomalyDimension(), new List <MetricSlice>()
            {
                new MetricSlice(GetRootCauseTimestamp(), GetRootCauseLocalizationPoints())
            }, AggregateType.Sum, _rootCauseAggSymbol);

            var       ml        = new MLContext(1);
            RootCause rootCause = ml.AnomalyDetection.LocalizeRootCause(rootCauseLocalizationInput);

            Assert.NotNull(rootCause);
            Assert.Equal(1, (int)rootCause.Items.Count);
            Assert.Equal(3, (int)rootCause.Items[0].Dimension.Count);
            Assert.Equal(AnomalyDirection.Up, rootCause.Items[0].Direction);
            Assert.Equal(1, (int)rootCause.Items[0].Path.Count);
            Assert.Equal("DataCenter", rootCause.Items[0].Path[0]);

            Dictionary <string, Object> expectedDim = new Dictionary <string, Object>();

            expectedDim.Add("Country", "UK");
            expectedDim.Add("DeviceType", _rootCauseAggSymbol);
            expectedDim.Add("DataCenter", "DC1");

            foreach (KeyValuePair <string, object> pair in rootCause.Items[0].Dimension)
            {
                Assert.Equal(expectedDim[pair.Key], pair.Value);
            }
        }
Example #3
0
        /// <summary>
        /// Create <see cref="RootCause"/>, which localizes root causes using decision tree algorithm.
        /// </summary>
        /// <param name="catalog">The anomaly detection catalog.</param>
        /// <param name="src">Root cause's input. The data is an instance of <see cref="Microsoft.ML.TimeSeries.RootCauseLocalizationInput"/>.</param>
        /// <param name="beta">Beta is a weight parameter for user to choose. It is used when score is calculated for each root cause item. The range of beta should be in [0,1]. For a larger beta, root cause point which has a large difference between value and expected value will get a high score. On the contrary, for a small beta, root cause items which has a high relative change will get a high score.</param>
        /// <param name="anomalyDeltaThreshold">A threshold to determine whether the point should be root cause. If the point's delta is equal to or larger than anomalyDeltaThreshold multiplies anomaly dimension point's delta, this point is treated as a root cause. Different threshold will turn out different result. Users can choose the delta according to their data and requirment. </param>
        /// <example>
        /// <format type="text/markdown">
        /// <![CDATA[
        /// [!code-csharp[LocalizeRootCause](~/../docs/samples/docs/samples/Microsoft.ML.Samples/Dynamic/Transforms/TimeSeries/LocalizeRootCause.cs)]
        /// ]]>
        /// </format>
        /// </example>
        public static RootCause LocalizeRootCause(this AnomalyDetectionCatalog catalog, RootCauseLocalizationInput src, double beta = 0.5, double anomalyDeltaThreshold = 0.95)
        {
            IHostEnvironment host = CatalogUtils.GetEnvironment(catalog);

            //check the root cause input
            CheckRootCauseInput(host, src);

            //check beta
            host.CheckUserArg(beta >= 0 && beta <= 1, nameof(beta), "Must be in [0,1]");

            //find out the root cause
            RootCauseAnalyzer analyzer = new RootCauseAnalyzer(src, beta, anomalyDeltaThreshold);
            RootCause         dst      = analyzer.Analyze();

            return(dst);
        }
Example #4
0
        /// <inheritdoc/>
        public string ToDelimitedString()
        {
            CultureInfo culture = CultureInfo.CurrentCulture;

            return(string.Format(
                       culture,
                       StringHelper.StringFormatSequence(0, 34, Configuration.FieldSeparator),
                       Id,
                       SetIdObx.HasValue ? SetIdObx.Value.ToString(culture) : null,
                       ValueType,
                       ObservationIdentifier?.ToDelimitedString(),
                       ObservationSubId?.ToDelimitedString(),
                       ObservationValue != null ? string.Join(Configuration.FieldRepeatSeparator, ObservationValue) : null,
                       Units?.ToDelimitedString(),
                       ReferencesRange,
                       InterpretationCodes != null ? string.Join(Configuration.FieldRepeatSeparator, InterpretationCodes.Select(x => x.ToDelimitedString())) : null,
                       Probability.HasValue ? Probability.Value.ToString(Consts.NumericFormat, culture) : null,
                       NatureOfAbnormalTest != null ? string.Join(Configuration.FieldRepeatSeparator, NatureOfAbnormalTest) : null,
                       ObservationResultStatus,
                       EffectiveDateOfReferenceRange.HasValue ? EffectiveDateOfReferenceRange.Value.ToString(Consts.DateTimeFormatPrecisionSecond, culture) : null,
                       UserDefinedAccessChecks,
                       DateTimeOfTheObservation.HasValue ? DateTimeOfTheObservation.Value.ToString(Consts.DateTimeFormatPrecisionSecond, culture) : null,
                       ProducersId?.ToDelimitedString(),
                       ResponsibleObserver != null ? string.Join(Configuration.FieldRepeatSeparator, ResponsibleObserver.Select(x => x.ToDelimitedString())) : null,
                       ObservationMethod != null ? string.Join(Configuration.FieldRepeatSeparator, ObservationMethod.Select(x => x.ToDelimitedString())) : null,
                       EquipmentInstanceIdentifier != null ? string.Join(Configuration.FieldRepeatSeparator, EquipmentInstanceIdentifier.Select(x => x.ToDelimitedString())) : null,
                       DateTimeOfTheAnalysis.HasValue ? DateTimeOfTheAnalysis.Value.ToString(Consts.DateTimeFormatPrecisionSecond, culture) : null,
                       ObservationSite != null ? string.Join(Configuration.FieldRepeatSeparator, ObservationSite.Select(x => x.ToDelimitedString())) : null,
                       ObservationInstanceIdentifier?.ToDelimitedString(),
                       MoodCode?.ToDelimitedString(),
                       PerformingOrganizationName?.ToDelimitedString(),
                       PerformingOrganizationAddress?.ToDelimitedString(),
                       PerformingOrganizationMedicalDirector?.ToDelimitedString(),
                       PatientResultsReleaseCategory,
                       RootCause?.ToDelimitedString(),
                       LocalProcessControl != null ? string.Join(Configuration.FieldRepeatSeparator, LocalProcessControl.Select(x => x.ToDelimitedString())) : null,
                       ObservationType,
                       ObservationSubType,
                       ActionCode,
                       ObservationValueAbsentReason != null ? string.Join(Configuration.FieldRepeatSeparator, ObservationValueAbsentReason.Select(x => x.ToDelimitedString())) : null,
                       ObservationRelatedSpecimenIdentifier != null ? string.Join(Configuration.FieldRepeatSeparator, ObservationRelatedSpecimenIdentifier.Select(x => x.ToDelimitedString())) : null
                       ).TrimEnd(Configuration.FieldSeparator.ToCharArray()));
        }