Предположим, что я беру выборку записей базы данных, которые возвращают следующие номера:
20.50, 80.30, 70.95, 15.25, 99.97, 85.56, 69.77
Есть ли алгоритм, который можно эффективно реализовать в PHP, чтобы найти выбросы (если они есть) из массива поплавков, исходя из того, насколько они отклоняются от среднего?
Итак, давайте предположим, что у вас есть свои точки данных в массиве:
<?php $dataset = array(20.50, 80.30, 70.95, 15.25, 99.97, 85.56, 69.77); ?>
Затем вы можете использовать следующую функцию (см. Комментарии для того, что происходит), чтобы удалить все числа, которые выходят за пределы среднего +/- стандартного времени отклонения от установленной вами величины (по умолчанию 1):
<?php function remove_outliers($dataset, $magnitude = 1) { $count = count($dataset); $mean = array_sum($dataset) / $count; // Calculate the mean $deviation = sqrt(array_sum(array_map("sd_square", $dataset, array_fill(0, $count, $mean))) / $count) * $magnitude; // Calculate standard deviation and times by magnitude return array_filter($dataset, function($x) use ($mean, $deviation) { return ($x <= $mean + $deviation && $x >= $mean - $deviation); }); // Return filtered array of values that lie within $mean +- $deviation. } function sd_square($x, $mean) { return pow($x - $mean, 2); } ?>
Для вашего примера эта функция возвращает следующее с величиной 1:
Array ( [1] => 80.3 [2] => 70.95 [5] => 85.56 [6] => 69.77 )
Для нормально распределенного набора данных удаляет значения более 3 стандартных отклонений от среднего значения.
<?php function remove_outliers($array) { if(count($array) == 0) { return $array; } $ret = array(); $mean = array_sum($array)/count($array); $stddev = stats_standard_deviation($array); $outlier = 3 * $stddev; foreach($array as $a) { if(!abs($a - $mean) > $outlier) { $ret[] = $a; } } return $ret; }