本文實例講述了基于PHP實現(xiàn)的多元線性回歸模擬曲線算法。分享給大家供大家參考,具體如下:
多元線性回歸模型: y = b1x1 + b2x2 + b3x3 +...... +bnxn;
我們根據(jù)一組數(shù)據(jù): 類似 arr_x = [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15]]; arr_y = [5, 10, 15]; 我們最后要求出的是一個數(shù)組,包含了從b1 到bn;
方法:利用最小二乘法
公式:我們只用公式的前半部分,也就是用矩陣來計算
式中的X就是arr_x,二維數(shù)組我們可以把它看成是一個矩陣,式中的y就是arr_y,也把它看成一個矩陣(5, 10, 15) ,不過應該是豎著寫的。
然后可以根據(jù)公式我們會發(fā)現(xiàn)要用到矩陣的相乘,轉置,求逆;所以下面的代碼一一給出:
public function get_complement($data, $i, $j) {
/* x和y為矩陣data的行數(shù)和列數(shù) */
$x = count($data);
$y = count($data[0]);
/* data2為所求剩余矩陣 */
$data2 =[];
for ($k = 0; $k $x -1; $k++) {
if ($k $i) {
for ($kk = 0; $kk $y -1; $kk++) {
if ($kk $j) {
$data2[$k][$kk] = $data[$k][$kk];
} else {
$data2[$k][$kk] = $data[$k][$kk +1];
}
}
} else {
for ($kk = 0; $kk $y -1; $kk++) {
if ($kk $j) {
$data2[$k][$kk] = $data[$k +1][$kk];
} else {
$data2[$k][$kk] = $data[$k +1][$kk +1];
}
}
}
}
return $data2;
}
/* 計算矩陣行列式 */
public function cal_det($data) {
$ans = 0;
if (count($data[0]) === 2) {
$ans = $data[0][0] * $data[1][1] - $data[0][1] * $data[1][0];
} else {
for ($i = 0; $i count($data[0]); $i++) {
$data_temp = $this->get_complement($data, 0, $i);
if ($i % 2 === 0) {
$ans = $ans + $data[0][$i] * ($this->cal_det($data_temp));
} else {
$ans = $ans - $data[0][$i] * ($this->cal_det($data_temp));
}
}
}
return $ans;
}
/*計算矩陣的伴隨矩陣*/
public function ajoint($data) {
$m = count($data);
$n = count($data[0]);
$data2 =[];
for ($i = 0; $i $m; $i++) {
for ($j = 0; $j $n; $j++) {
if (($i + $j) % 2 === 0) {
$data2[$i][$j] = $this->cal_det($this->get_complement($data, $i, $j));
} else {
$data2[$i][$j] = - $this->cal_det($this->get_complement($data, $i, $j));
}
}
}
return $this->trans($data2);
}
/*轉置矩陣*/
public function trans($data) {
$i = count($data);
$j = count($data[0]);
$data2 =[];
for ($k2 = 0; $k2 $j; $k2++) {
for ($k1 = 0; $k1 $i; $k1++) {
$data2[$k2][$k1] = $data[$k1][$k2];
}
}
/*將矩陣轉置便可得到伴隨矩陣*/
return $data2;
}
/*求矩陣的逆,輸入?yún)?shù)為原矩陣*/
public function inv($data) {
$m = count($data);
$n = count($data[0]);
$data2 =[];
$det_val = $this->cal_det($data);
$data2 = $this->ajoint($data);
for ($i = 0; $i $m; $i++) {
for ($j = 0; $j $n; $j++) {
$data2[$i][$j] = $data2[$i][$j] / $det_val;
}
}
return $data2;
}
/*求兩矩陣的乘積*/
public function getProduct($data1, $data2) {
/*$data1 為左乘矩陣*/
$m1 = count($data1);
$n1 = count($data1[0]);
$m2 = count($data2);
$n2 = count($data2[0]);
$data_new =[];
if ($n1 !== $m2) {
return false;
} else {
for ($i = 0; $i = $m1 -1; $i++) {
for ($k = 0; $k = $n2 -1; $k++) {
$data_new[$i][$k] = 0;
for ($j = 0; $j = $n1 -1; $j++) {
$data_new[$i][$k] += $data1[$i][$j] * $data2[$j][$k];
}
}
}
}
return $data_new;
}
/*多元線性方程*/
public function getParams($arr_x, $arr_y) {
$final =[];
$arr_x_t = $this->trans($arr_x);
$result = $this->getProduct($this->getProduct($this->inv($this->getProduct($arr_x_t, $arr_x)), $arr_x_t), $arr_y);
foreach ($result as $key => $val) {
foreach ($val as $_k => $_v) {
$final[] = $_v;
}
}
return $final;
}
最后的getParams()
方法就是最后求b參數(shù)數(shù)組的方法,傳入一個二維數(shù)組arr_x, 和一個一維數(shù)組arr_y就可以了。
這一般用于大數(shù)據(jù)分析,根據(jù)大數(shù)據(jù)來模擬和預測下面的發(fā)展和走勢。
PS:這里為大家推薦兩款相關模擬曲線工具供大家參考:
在線多項式曲線及曲線函數(shù)擬合工具:
http://tools.jb51.net/jisuanqi/create_fun
在線繪制多項式/函數(shù)曲線圖形工具:
http://tools.jb51.net/jisuanqi/fun_draw
更多關于PHP相關內容感興趣的讀者可查看本站專題:《PHP數(shù)據(jù)結構與算法教程》、《php程序設計算法總結》、《php字符串(string)用法總結》、《PHP數(shù)組(Array)操作技巧大全》、《PHP常用遍歷算法與技巧總結》及《PHP數(shù)學運算技巧總結》
希望本文所述對大家PHP程序設計有所幫助。
您可能感興趣的文章:- php 大數(shù)據(jù)量及海量數(shù)據(jù)處理算法總結
- php中最簡單的字符串匹配算法
- PHP經(jīng)典算法集錦【經(jīng)典收藏】
- 關于PHP遞歸算法和應用方法介紹
- PHP面試常用算法(推薦)
- php經(jīng)典算法集錦
- PHP常用算法和數(shù)據(jù)結構示例(必看篇)
- php使用高斯算法實現(xiàn)圖片的模糊處理功能示例
- php實現(xiàn)的常見排序算法匯總
- PHP實現(xiàn)深度優(yōu)先搜索算法(DFS,Depth First Search)詳解
- PHP實現(xiàn)廣度優(yōu)先搜索算法(BFS,Broad First Search)詳解