Exemple #1
0
        /**
         * Given a list of anomaly scores return a list of averaged records.
         * anomalyScores is assumed to be a list of records of the form:
         * <pre>
         *      Sample:
         *           dt = Tuple(2013, 8, 10, 23, 0) --> Date Fields
         *           sample = (double) 6.0
         *           metric(avg) = (double) 1.0
         * </pre>
         *
         * @param anomalyScores     List of {@link Sample} objects (described contents above)
         * @param windowSize        Count of historical items over which to compute the average
         *
         * @return Each record in the returned list contains [datetime field, value, averaged score]
         */
        public AveragedAnomalyRecordList AnomalyScoreMovingAverage(List <Sample> anomalyScores, int windowSize)
        {
            List <double> historicalValues   = new List <double>();
            double        total              = 0.0;
            List <Sample> averagedRecordList = new List <Sample>();

            foreach (Sample record in anomalyScores)
            {
                ////////////////////////////////////////////////////////////////////////////////////////////
                // Python version has check for malformed records here, but can't happen in java version. //
                ////////////////////////////////////////////////////////////////////////////////////////////

                MovingAverage.Calculation calc = MovingAverage.Compute(historicalValues, total, record.score, windowSize);

                Sample avgRecord = new Sample(
                    record.date,
                    record.value,
                    calc.GetAverage());
                averagedRecordList.Add(avgRecord);
                total = calc.GetTotal();

                if (LOG.IsDebugEnabled)
                {
                    LOG.Debug(string.Format("Aggregating input record: {0}, Result: {1}", record, averagedRecordList[averagedRecordList.Count - 1]));
                }
            }

            return(new AveragedAnomalyRecordList(averagedRecordList, historicalValues, total));
        }
Exemple #2
0
        /**
         * Compute updated probabilities for anomalyScores using the given params.
         *
         * @param anomalyScores     a list of records. Each record is a list with a {@link Sample} containing the
         *                          following three elements: [timestamp, value, score]
         * @param params            Associative <see cref="NamedTuple"/> returned by the {@link AnomalyLikelihoodMetrics} from
         *                          {@link #estimateAnomalyLikelihoods(List, int, int)}
         * @return
         */
        public AnomalyLikelihoodMetrics UpdateAnomalyLikelihoods(List <Sample> anomalyScores, AnomalyParams @params)
        {
            int anomalySize = anomalyScores.Count;

            if (LOG.IsDebugEnabled)
            {
                LOG.Debug("in updateAnomalyLikelihoods");
                LOG.Debug(string.Format("Number of anomaly scores: {0}", anomalySize));
                LOG.Debug(string.Format("First 20: {0}", anomalyScores.SubList(0, Math.Min(20, anomalySize))));
                LOG.Debug(string.Format("Params: {0}", @params));
            }

            if (anomalyScores.Count == 0)
            {
                throw new ArgumentException("Must have at least one anomaly score.");
            }

            if (!IsValidEstimatorParams(@params))
            {
                throw new ArgumentException("\"params\" is not a valid parameter structure");
            }



            double[] histLikelihoods;
            if ((histLikelihoods = @params.HistoricalLikelihoods()) == null || histLikelihoods.Length == 0)
            {
                Parameters anomalyParameters = Parameters.Empty();
                anomalyParameters.SetParameterByKey(Parameters.KEY.ANOMALY_KEY_DIST, @params.Distribution());
                anomalyParameters.SetParameterByKey(Parameters.KEY.ANOMALY_KEY_MVG_AVG, @params.MovingAverage());
                anomalyParameters.SetParameterByKey(Parameters.KEY.ANOMALY_KEY_HIST_LIKE, histLikelihoods = new double[] { 1 });

                @params = new AnomalyParams(anomalyParameters);

                //@params = new NamedTuple(
                //    new string[] { "distribution", "movingAverage", "historicalLikelihoods" },
                //        @params.Distribution(),
                //        @params.MovingAverage(),
                //        histLikelihoods = new double[] { 1 });
            }

            // Compute moving averages of these new scores using the previous values
            // as well as likelihood for these scores using the old estimator
            MovingAverage mvgAvg           = (MovingAverage)@params.MovingAverage();
            List <double> historicalValues = mvgAvg.GetSlidingWindow();
            double        total            = mvgAvg.GetTotal();
            int           windowSize       = mvgAvg.GetWindowSize();

            List <Sample> aggRecordList = new List <Sample>(anomalySize);

            double[] likelihoods = new double[anomalySize];
            int      i           = 0;

            foreach (Sample sample in anomalyScores)
            {
                MovingAverage.Calculation calc = MovingAverage.Compute(historicalValues, total, sample.score, windowSize);
                aggRecordList.Add(
                    new Sample(
                        sample.date,
                        sample.value,
                        calc.GetAverage()));
                total            = calc.GetTotal();
                likelihoods[i++] = NormalProbability(calc.GetAverage(), (Statistic)@params.Distribution());
            }

            // Filter the likelihood values. First we prepend the historical likelihoods
            // to the current set. Then we filter the values.  We peel off the likelihoods
            // to return and the last windowSize values to store for later.
            double[] likelihoods2        = ArrayUtils.Concat(histLikelihoods, likelihoods);
            double[] filteredLikelihoods = FilterLikelihoods(likelihoods2);
            likelihoods = Arrays.CopyOfRange(filteredLikelihoods, filteredLikelihoods.Length - likelihoods.Length, filteredLikelihoods.Length);
            double[] historicalLikelihoods = Arrays.CopyOf(likelihoods2, likelihoods2.Length - Math.Min(windowSize, likelihoods2.Length));

            // Update the estimator
            Parameters newAnomalyParameters = Parameters.Empty();

            newAnomalyParameters.SetParameterByKey(Parameters.KEY.ANOMALY_KEY_DIST, @params.Distribution());
            newAnomalyParameters.SetParameterByKey(Parameters.KEY.ANOMALY_KEY_MVG_AVG, new MovingAverage(historicalValues, total, windowSize));
            newAnomalyParameters.SetParameterByKey(Parameters.KEY.ANOMALY_KEY_HIST_LIKE, historicalLikelihoods);

            AnomalyParams newParams = new AnomalyParams(newAnomalyParameters);

            //AnomalyParams newParams = new AnomalyParams(
            //    new string[] { "distribution", "movingAverage", "historicalLikelihoods" },
            //        @params.Distribution(),
            //        new MovingAverage(historicalValues, total, windowSize),
            //        historicalLikelihoods);

            return(new AnomalyLikelihoodMetrics(
                       likelihoods,
                       new AveragedAnomalyRecordList(aggRecordList, historicalValues, total),
                       newParams));
        }