Рассчитать среднее значение, не будучи сброшенным на бездомных - PullRequest
5 голосов
/ 19 октября 2010

Я пытаюсь вычислить среднее значение, не отбрасывая его небольшим набором удаленных чисел (т. Е. 1,2,1,2,3,4,50), одиночное 50 скинет все среднее значение.

Если у меня есть список таких номеров:

19,20,21,21,22,30,60,60

среднее значение 31

Медиана: 30

Режим 21 и 60 (в среднем 40,5 )

Но любой может видеть, что большинство находится в диапазоне 19-22 (5 в, 3 из), и если вы получите среднее значение только для основного диапазона, это 20,6 (большая разница, чем любаяиз чисел выше)

Я думаю, что вы можете получить это так:

c + dr

Где c это количестводля чисел d - это отдельные значения, а r - диапазон.Затем вы можете применить это ко всем возможным диапазонам, и наивысший балл - это максимальный диапазон, от которого можно получить среднее значение.

Например, 19,20,21,21,22 будет 5 числами, 4 различными значениями, а диапазон равен 3(22 - 19).Если вы включите это в мое уравнение, вы получите 5 + 4-3 = 6

Если вы примените это ко всему списку номеров, это будет 8 + 6-41 = -27

Я думаю, что это работает довольно хорошо, но мне нужно создать огромный цикл для проверки всех возможных диапазонов.В моем небольшом примере есть 21 возможный диапазон:

19-19, 19-20, 19-21, 19-22, 19-30, 19-60, 20-20, 20-21, 20-22, 20-30, 20-60, 21-21, 21-22, 21-30, 21-60, 22-22, 22-30, 22-60, 30-30, 30-60,60-60

Мне интересно, есть ли более эффективный способ получить среднее значение, подобное этому.

Или если у кого-то есть лучший алгоритм все вместе?

Ответы [ 5 ]

2 голосов
/ 20 октября 2010

Вот довольно наивная реализация, которую вы можете исправить для своих собственных нужд.Я специально держал это довольно многословным.Он основан на сводке из пяти чисел, часто используемой для выяснения этих вещей.

function get_median($arr) {
    sort($arr);
    $c = count($arr) - 1;
    if ($c%2) {
        $b = round($c/2);
        $a = $b-1;
        return ($arr[$b] + $arr[$a]) / 2 ;
    } else {
        return $arr[($c/2)];
    }
}

function get_five_number_summary($arr) {
    sort($arr);
    $c = count($arr) - 1;
    $fns = array();
    if ($c%2) {
        $b = round($c/2);
        $a = $b-1;
        $lower_quartile = array_slice($arr, 1, $a-1);
        $upper_quartile = array_slice($arr, $b+1, count($lower_quartile));
        $fns = array($arr[0], get_median($lower_quartile), get_median($arr), get_median($upper_quartile), $arr[$c-1]);
        return $fns;
    }
    else {
        $b = round($c/2);
        $a = $b-1;
        $lower_quartile = array_slice($arr, 1, $a);
        $upper_quartile = array_slice($arr, $b+1, count($lower_quartile));
        $fns = array($arr[0], get_median($lower_quartile), get_median($arr), get_median($upper_quartile), $arr[$c-1]);
        return $fns;
    }
}

function find_outliers($arr) {
    $fns = get_five_number_summary($arr);
    $interquartile_range = $fns[3] - $fns[1];
    $low = $fns[1] - $interquartile_range;
    $high = $fns[3] + $interquartile_range;
    foreach ($arr as $v) {
        if ($v > $high || $v < $low)
            echo "$v is an outlier<br>";
    }
}

//$numbers = array( 19,20,21,21,22,30,60 ); // 60 is an outlier
$numbers = array( 1,230,239,331,340,800); // 1 is an outlier, 800 is an outlier
find_outliers($numbers);

Обратите внимание, что этот метод, хотя и намного проще для реализации, чем стандартное отклонение, не найдетдва 60 выбросов в вашем примере, но это работает довольно хорошо.Используйте код для чего угодно, надеюсь, он полезен!

Чтобы увидеть, как работает алгоритм и как я его реализовал, перейдите по ссылке: http://www.mathwords.com/o/outlier.htm

Это, конечно, не вычисляетокончательное среднее значение, но после запуска find_outliers(): P

это довольно тривиально
2 голосов
/ 19 октября 2010

Вы можете получить некоторую пользу от стандартного отклонения здесь, которое в основном измеряет, насколько сконцентрированы точки данных.Вы можете определить выброс как среднее значение, превышающее 1 стандартное отклонение (или любое другое подходящее вам число) от среднего значения, выбросить его и рассчитать новое среднее значение, которое не включает их.

1 голос
/ 20 октября 2010

Почему вы не используете медиану? Это не 30, это 21,5.

0 голосов
/ 20 октября 2010

Вы можете отсортировать свои числа, выбрать предпочитаемый поддиапазон (например, середина 90%) и взять среднее значение.

Нет единственно верного ответа на ваш вопрос, потому что всегда найдутся дистрибутивы, которые дадут вам забавный ответ (например, рассмотрим смещенный бимодальный дистрибутив). Вот почему статистические данные часто представляются с использованием диаграмм типа «квадрат и ус», показывающих среднее значение, медиану, квартили и выбросы.

0 голосов
/ 19 октября 2010

Вы можете поместить значения в массив, отсортировать массив, а затем найти медиана , которая обычно в любом случае лучше, чем среднее значение, поскольку она автоматически сбрасывает выбросы, давая им не больше веса, чем любой другой номер.

...