次の数値を返すデータベース レコードの選択をサンプリングするとします。
20.50, 80.30, 70.95, 15.25, 99.97, 85.56, 69.77
PHP で効率的に実装して、平均値からの偏差に基づいて float の配列から外れ値 (存在する場合) を見つけることができるアルゴリズムはありますか?
さて、あなたが次のような配列にデータポイントを持っていると仮定しましょう:
<?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;
}