Как обнаружить выбросы в массиве двойников? - PullRequest
0 голосов
/ 26 мая 2018

Я пытаюсь определить, есть ли выбросы данных в списке двойников.В основном, если что-то ниже 10 процентов от пределов или выше 90 процентов.У меня работает следующий код, но он не работает должным образом с отрицательными числами, и я не вижу, что не так.Есть ли лучший способ приблизиться, или в коде или математике есть что-то вопиющее?

public bool DataHasOutliers(IEnumerable<double> results, Limits limits)
{
    foreach (double result in results)
    {
        //detect if any result values are in the low or high regions of the acceptable limits
        double deltaAbsolute = (limits.High - limits.Low) < 0 ? (limits.High - limits.Low) * -1 : limits.High - limits.Low;
        double absoluteResult = result < 0 ? result * -1 : result;
        double lowLimitAbsolute = limits.Low < 0 ? limits.Low * -1 : limits.Low;
        double upperThreshold = 0.9 * deltaAbsolute + limits.Low;
        double lowerThreshold = 0.1 * deltaAbsolute + limits.Low;
        if (absoluteResult >= upperThreshold)
        {
            "".Dump("Upper threshold violated");
            return true;
        }
        if (absoluteResult <= lowerThreshold)
        {
            "".Dump("Lower threshold violated");
            return true;
        }
    }
    return false;
}

public class Limits
{
    public double High { get; set; }
    public double Low { get; set; }
    public string Error { get; set; }
}

Ответы [ 2 ]

0 голосов
/ 26 мая 2018

Почему вы пересчитываете пределы в цикле.
Если Высокий> Низкий, то вам не нужны никакие абсолютные вещи.

public bool DataHasOutliers(IEnumerable<double> results, Limits limits)
{
    if(limits.High < limits.Low) 
    {
         throw new ArgumentOutOfRangeException();
    }
    double delta = limits.High - limits.Low;
    double upperThreshold = 0.9 * delta + limits.Low;
    double lowerThreshold = 0.1 * delta + limits.Low;
    foreach (double result in results)
    {
        //detect if any result values are in the low or high regions of the acceptable limits
        if (result >= upperThreshold)
        {
            "".Dump("Upper threshold violated");
            return true;
        }
        if (result <= lowerThreshold)
        {
            "".Dump("Lower threshold violated");
            return true;
        }
    }
    return false;
}
0 голосов
/ 26 мая 2018

Если пределы [-10, 0], а результат - -5, с текущим кодом вы будете эффективно проверять, находится ли 5 в [11, 19], что неверно.

Iпредложите сохранить знак увеличения / уменьшения их границ на 1/10 диапазона, а затем сравнить исходное значение результата с этим уменьшенным диапазоном:

double deltaAbsolute = Math.Abs(limits.High - limits.Low);
double lowerThreshold = limits.Low + 0.1 * deltaAbsolute;
double upperThreshold = limits.High - 0.1 * deltaAbsolute;
if (result >= upperThreshold)
{
    "".Dump("Upper threshold violated");
    return true;
}
if (result <= lowerThreshold)
{
    "".Dump("Lower threshold violated");
    return true;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...