PHP實現正態分布的累積概率函數


在實際項目中,遇到需要正態分布算法去計算一個數值在整體的分布區間,例如:

 100,90,80,70,60,50,40,30,20,10共10個數,按從高到低的順序排序,總數的10%分布區域為極高頻,總數的30%分布區域為高頻,總數的40%分布區域為中頻,總數的20%分布區域為低頻,比如我新增一個數字88,我如何快速得到新增數字位於那個頻段?以及其他數字有那些數字頻段發生了變化??? 
 
代碼實現(計算數值在整體分布的累計概率):
 1 <?php
 2 /** 
 3  * php 實現excel的normdist函數
 4  *
 5  * 使用方法:
 6     $list = array(1.09,1.50,1.31,1.44);
 7     $normdist = new normdist($list);
 8     echo $normdist->getCdf($list[0]);
 9  */
10 class normdist {
11     
12     public $list = array();
13     public $mu;
14     public $sigma;
15     
16     public function __construct($list)
17     {
18         $this->list  = $list;
19         $this->mu    = $this->getMu($list); // 獲取平均值
20         $this->sigma = $this->getSigma($list); // 獲取標准偏差
21     }
22     
23     /**
24      * @name 正態分布的累積概率函數
25      * @param string|integer $value
26      * @return number
27      */
28     public function getCdf($value)
29     {
30         $mu = $this->mu;
31         $sigma = $this->sigma;
32         $t = $value - $mu;
33         $y = 0.5 * $this->erfcc(-$t / ($sigma * sqrt(2.0)));
34         if ($y > 1.0) $y = 1.0;
35         
36         return $y;
37     }
38      
39     private function erfcc($x) 
40     {
41         $z = abs($x);
42         $t = 1. / (1. + 0.5 * $z);
43         $r = 
44             $t * exp(-$z*$z-1.26551223+
45             $t*(1.00002368+
46             $t*(.37409196+
47             $t*(.09678418+
48             $t*(-.18628806+
49             $t*(.27886807+
50             $t*(-1.13520398+
51             $t*(1.48851587+
52             $t*(-.82215223+
53             $t*.17087277)))))))));
54         if ($x >= 0.)
55             return $r;
56         else
57             return 2 - $r;
58     }
59 
60     /**
61      * @name 獲取平均值
62      * @param array $list
63      * @return number
64      */
65     private function getMu($list)
66     {
67         return array_sum($list) / count($list);
68     }
69 
70     /**
71      * @name 獲取標准差
72      * @param array $list
73      * @return number
74      * @beizhu 標准差  = 方差的平方根
75      */
76     private function getSigma($list)
77     {
78         $total_var = 0;
79         foreach ($list as $v) {
80             $total_var += pow( ($v - $this->getMu($list)), 2);
81         }
82         
83         return sqrt( $total_var / (count($list) - 1 )); // 這里為什么數組元素個數要減去1
84     }
85 }
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM