概要
閲覧数:1396
投稿日:2014-05-07
更新日:2014-05-07
PHPでExcelの統計関数を実装
関数名一覧
s_average
・単純平均を取得
s_harmean
・調和平均を取得
s_varp
・分散を取得
(引数を母集団全体であると仮定して、母集団の分散を返す)
s_stdevp
・標準偏差を取得
s_devp
・偏差値を取得
s_correl
・相関係数を取得
s_intercept
・回帰直線のy切片を求める
([y = a * x + b]の[b]を求める)
s_slope
・回帰直線の傾きを求める
([y = a * x + b]の[a]を求める)
s_forecast
・回帰直線上でxに対応するyを求める
コード
/** * 単純平均を取得する */ function s_average($list) { $sum = NULL; if(count($list) < 2 || !is_array($list)){ return false; } $count = count($list); for ($i = 0; $i < $count; $i++) { $sum += $list[$i]; } return $sum / $count; } /** * 調和平均を取得する */ function s_harmean($list) { $sum = NULL; if(count($list) < 2 || !is_array($list)){ return false; } $count = count($list); for ($i = 0; $i < $count; $i++) { $sum += 1 / $list[$i]; } return $count / $sum; } /** * 分散を取得する * (引数を母集団全体であると仮定して、母集団の分散を返す) */ function s_varp($list) { if(count($list) < 2 || !is_array($list)){ return false; } $avg = s_average($list); $dec = 0; $count = count($list); for($i = 0; $i < $count; $i++){ $dec += pow($avg - $list[$i], 2); } return $dec / $count; } /** * 標準偏差を取得する */ function s_stdevp($list) { if(count($list) < 2 || !is_array($list)){ return false; } return sqrt(s_varp($list)); } /** * 偏差値を取得する */ function s_devp($list, $val) { if(count($list) < 2 || !is_array($list)){ return false; } return 10 * ($val - s_average($list)) / s_stdevp($list) + 50; } /** * 相関係数を取得する */ function s_correl($list_y, $list_x){ if(count($list_x) < 2 || count($list_y) < 2 || count($list_x) != count($list_y)){ return false; } $avg_x = s_average($list_x); $stdevp_x = s_stdevp($list_x); $avg_y = s_average($list_y); $stdevp_y = s_stdevp($list_y); $count = count($list_x); for($i = 0; $i < $count; $i++){ $x = $list_x[$i] - $avg_x; $y = $list_y[$i] - $avg_y; $devsum[$i] = $x * $y; } $avg_devsum = s_average($devsum); return $avg_devsum / ($stdevp_x * $stdevp_y); } /** * 回帰直線のy切片を求める * ([y = a * x + b]の[b]を求める) */ function s_intercept($list_y, $list_x){ $x_sum = NULL; $y_sum = NULL; $xx_sum = NULL; $xy_sum = NULL; if(count($list_x) < 2 || count($list_y) < 2 || count($list_x) != count($list_y)){ return false; } $count = count($list_x); for ($i = 0; $i < $count; $i++) { $x = $list_x[$i]; $y = $list_y[$i]; $x_sum += $x; $y_sum += $y; $xx_sum += $x * $x; $xy_sum += $x * $y; } $a = ($count * $xy_sum - $x_sum * $y_sum)/($count * $xx_sum - $x_sum * $x_sum); $b = ($y_sum - $a * $x_sum)/$count; return $b; } /** * 回帰直線の傾きを求める * ([y = a * x + b]の[a]を求める) */ function s_slope($list_y, $list_x){ $x_sum = NULL; $y_sum = NULL; $xx_sum = NULL; $xy_sum = NULL; if(count($list_x) < 2 || count($list_y) < 2 || count($list_x) != count($list_y)){ return false; } $count = count($list_x); for ($i = 0; $i < $count; $i++) { $x = $list_x[$i]; $y = $list_y[$i]; $x_sum += $x; $y_sum += $y; $xx_sum += $x * $x; $xy_sum += $x * $y; } $a = ($count * $xy_sum - $x_sum * $y_sum)/($count * $xx_sum - $x_sum * $x_sum); $b = ($y_sum - $a * $x_sum)/$count; return $a; } /** * 回帰直線上でxに対応するyを求める */ function s_forecast($target_x, $list_y, $list_x){ if(count($list_x) < 2 || count($list_y) < 2 || count($list_x) != count($list_y)){ return false; } $a = s_slope($list_y, $list_x); $b = s_intercept($list_y, $list_x); return $a * $target_x + $b; } /** * 回帰直線上の上昇率を求める */ function s_rate($list_y, $list_x){ if(count($list_x) < 2 || count($list_y) < 2 || count($list_x) != count($list_y)){ return false; } $a = s_slope($list_y, $list_x); $b = s_intercept($list_y, $list_x); return ($a * $list_x[count($list_x) - 1] + $b) / ($a * $list_x[count($list_x) - 2] + $b); } $data = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); $target = 47; for ($i=0; $i<=100; $i++) { $ary1[] = rand(0, 100); $ary2[] = rand(0, 100); } echo "単純平均: ".s_average($data)."\n"; echo "調和平均: ".s_harmean($data)."\n"; echo "分散: ".s_varp($data)."\n"; echo "標準偏差: ".s_stdevp($data)."\n"; echo "偏差値: ".s_devp($data,$target)."\n"; echo "相関係数: ".s_correl($ary2,$ary1)."\n"; echo "回帰直線のy切片: ".s_intercept($ary2,$ary1)."\n"; echo "回帰直線の傾き: ".s_slope($ary2,$ary1)."\n"; echo "回帰直線上でxに対応するy: ".s_forecast($target,$ary2,$ary1)."\n"; echo "回帰直線上の上昇率: ".s_rate($ary2,$ary1)."\n";
結果
単純平均: 5.5 調和平均: 3.4141715214741 分散: 8.25 標準偏差: 2.872281323269 偏差値: 194.48445444323 相関係数: 0.043400299696919 回帰直線のy切片: 49.860824372578 回帰直線の傾き: 0.044513636792814 回帰直線上でxに対応するy: 51.95296530184 回帰直線上の上昇率: 1.0077046568278