예제 #1
0
        public void P2QuantileEstimatorTest(string testKey)
        {
            var    testData  = TestDataMap[testKey];
            double p         = testData.Probability;
            var    sample    = testData.Generate();
            var    estimator = new P2QuantileEstimator(p);

            foreach (double x in sample.Values)
            {
                estimator.AddValue(x);
            }

            double actual      = estimator.GetQuantile();
            double expected    = SimpleQuantileEstimator.Instance.GetQuantile(sample, p);
            double pDelta      = 0.1 + Math.Abs(p - 0.5) * 0.2 + 2.0 / testData.N;
            double expectedMin = SimpleQuantileEstimator.Instance.GetQuantile(sample, (p - pDelta).Clamp(0, 1));
            double expectedMax = SimpleQuantileEstimator.Instance.GetQuantile(sample, (p + pDelta).Clamp(0, 1));
            double mad         = MedianAbsoluteDeviation.CalcMad(sample);
            double error       = Math.Abs(actual - expected);
            double errorNorm   = error / mad;

            output.WriteLine($"ExpectedMin = {expectedMin:N5}");
            output.WriteLine($"Expected    = {expected:N5}");
            output.WriteLine($"ExpectedMax = {expectedMax:N5}");
            output.WriteLine($"Actual      = {actual:N5}");
            output.WriteLine($"Error       = {error:N5}");
            output.WriteLine($"ErrorNorm   = {errorNorm:N5}");

            Assert.True(expectedMin <= actual && actual <= expectedMax);
        }
예제 #2
0
        public override double GetValue(Sample a, Sample b, Probability probability)
        {
            Assertion.NotNull(nameof(a), a);
            Assertion.NotNull(nameof(b), b);

            try
            {
                double aMad = MedianAbsoluteDeviation.CalcMad(a);
                double bMad = MedianAbsoluteDeviation.CalcMad(b);
                if (aMad < Eps && bMad < Eps)
                {
                    double aMedian = QuantileEstimator.GetMedian(a);
                    double bMedian = QuantileEstimator.GetMedian(b);
                    if (Math.Abs(aMedian - bMedian) < Eps)
                    {
                        return(0);
                    }
                    return(aMedian < bMedian
                        ? double.PositiveInfinity
                        : double.NegativeInfinity);
                }

                double aQuantile = QuantileEstimator.GetQuantile(a, probability);
                double bQuantile = QuantileEstimator.GetQuantile(b, probability);
                double pooledMad = PooledMad(a.Count, b.Count, aMad, bMad);

                return((bQuantile - aQuantile) / pooledMad);
            }
            catch (Exception)
            {
                return(double.NaN);
            }
        }
예제 #3
0
        private MadOutlierDetector([NotNull] Sample sample, double k, double consistencyConstant,
                                   [CanBeNull] IQuantileEstimator quantileEstimator)
        {
            Assertion.NotNull(nameof(sample), sample);

            quantileEstimator ??= HarrellDavisQuantileEstimator.Instance;
            double median = quantileEstimator.GetMedian(sample);
            double mad    = MedianAbsoluteDeviation.CalcMad(sample, consistencyConstant, quantileEstimator);

            LowerFence = median - k * mad;
            UpperFence = median + k * mad;
        }
예제 #4
0
        public override double[] GetValues(Sample a, Sample b, IReadOnlyList <Probability> probabilities)
        {
            Assertion.NotNull(nameof(a), a);
            Assertion.NotNull(nameof(b), b);
            Assertion.NotNullOrEmpty(nameof(probabilities), probabilities);

            int k = probabilities.Count;

            try
            {
                double aMad = MedianAbsoluteDeviation.CalcMad(a);
                double bMad = MedianAbsoluteDeviation.CalcMad(b);
                if (aMad < Eps && bMad < Eps)
                {
                    double aMedian = QuantileEstimator.GetMedian(a);
                    double bMedian = QuantileEstimator.GetMedian(b);
                    if (Math.Abs(aMedian - bMedian) < Eps)
                    {
                        return(ConstantSequence.Zero.GenerateArray(k));
                    }
                    return(aMedian < bMedian
                        ? ConstantSequence.PositiveInfinity.GenerateArray(k)
                        : ConstantSequence.NegativeInfinity.GenerateArray(k));
                }

                double[] aQuantile = QuantileEstimator.GetQuantiles(a, probabilities);
                double[] bQuantile = QuantileEstimator.GetQuantiles(b, probabilities);

                double pooledMad = PooledMad(a.Count, b.Count, aMad, bMad);

                double[] values = new double[k];
                for (int i = 0; i < k; i++)
                {
                    values[i] = (bQuantile[i] - aQuantile[i]) / pooledMad;
                }

                return(values);
            }
            catch (Exception)
            {
                return(ConstantSequence.NaN.GenerateArray(k));
            }
        }