当前位置:首页 > PHP教程 > php高级应用 > 列表

基于PHP实现的多元线性回归模拟曲线算法

发布:smiling 来源: PHP粉丝网  添加日期:2021-09-01 16:05:33 浏览: 评论:0 

这篇文章主要介绍了基于PHP实现的多元线性回归模拟曲线算法,结合具体实例形式分析了多元线性回归模拟曲线算法的原理与相关php实现技巧,需要的朋友可以参考下

本文实例讲述了基于PHP实现的多元线性回归模拟曲线算法,分享给大家供大家参考,具体如下:

多元线性回归模型: y = b1x1 + b2x2 + b3x3 +...... +bnxn;

我们根据一组数据: 类似 arr_x = [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15]]; arr_y = [5, 10, 15]; 我们最后要求出的是一个数组,包含了从b1 到bn;

方法:利用最小二乘法

公式:我们只用公式的前半部分,也就是用矩阵来计算

式中的X就是arr_x,二维数组我们可以把它看成是一个矩阵,式中的y就是arr_y,也把它看成一个矩阵(5, 10, 15) ,不过应该是竖着写的。

然后可以根据公式我们会发现要用到矩阵的相乘,转置,求逆;所以下面的代码一一给出:

  1. public function get_complement($data, $i, $j) { 
  2.   /* x和y为矩阵data的行数和列数 */ 
  3.   $x = count($data); 
  4.   $y = count($data[0]); 
  5.   /* data2为所求剩余矩阵 */ 
  6.   $data2 =[]; 
  7.   for ($k = 0; $k < $x -1; $k++) { 
  8.     if ($k < $i) { 
  9.       for ($kk = 0; $kk < $y -1; $kk++) { 
  10.         if ($kk < $j) { 
  11.           $data2[$k][$kk] = $data[$k][$kk]; 
  12.         } else { 
  13.           $data2[$k][$kk] = $data[$k][$kk +1]; 
  14.         } 
  15.       } 
  16.     } else { 
  17.       for ($kk = 0; $kk < $y -1; $kk++) { 
  18.         if ($kk < $j) { 
  19.           $data2[$k][$kk] = $data[$k +1][$kk]; 
  20.         } else { 
  21.           $data2[$k][$kk] = $data[$k +1][$kk +1]; 
  22.         } 
  23.       } 
  24.     } 
  25.   } 
  26.   return $data2; 
  27. } 
  28. /* 计算矩阵行列式 */ 
  29. public function cal_det($data) { 
  30.   $ans = 0; 
  31.   if (count($data[0]) === 2) { 
  32.     $ans = $data[0][0] * $data[1][1] - $data[0][1] * $data[1][0]; 
  33.   } else { 
  34.     for ($i = 0; $i < count($data[0]); $i++) { 
  35.       $data_temp = $this->get_complement($data, 0, $i); 
  36.       if ($i % 2 === 0) { 
  37.         $ans = $ans + $data[0][$i] * ($this->cal_det($data_temp)); 
  38.       } else { 
  39.         $ans = $ans - $data[0][$i] * ($this->cal_det($data_temp)); 
  40.       } 
  41.     } 
  42.   } 
  43.   return $ans; 
  44. } 
  45. /*计算矩阵的伴随矩阵*/ 
  46. public function ajoint($data) { 
  47.   $m = count($data); 
  48.   $n = count($data[0]); 
  49.   $data2 =[]; 
  50.   for ($i = 0; $i < $m; $i++) { 
  51.     for ($j = 0; $j < $n; $j++) { 
  52.       if (($i + $j) % 2 === 0) { 
  53.         $data2[$i][$j] = $this->cal_det($this->get_complement($data, $i, $j)); 
  54.       } else { 
  55.         $data2[$i][$j] = - $this->cal_det($this->get_complement($data, $i, $j)); 
  56.       } 
  57.     } 
  58.   } 
  59.   return $this->trans($data2); 
  60. } 
  61. /*转置矩阵*/ 
  62. public function trans($data) { 
  63.   $i = count($data); 
  64.   $j = count($data[0]); 
  65.   $data2 =[]; 
  66.   for ($k2 = 0; $k2 < $j; $k2++) { 
  67.     for ($k1 = 0; $k1 < $i; $k1++) { 
  68.       $data2[$k2][$k1] = $data[$k1][$k2]; 
  69.     } 
  70.   } 
  71.   /*将矩阵转置便可得到伴随矩阵*/ 
  72.   return $data2; 
  73. } 
  74. /*求矩阵的逆,输入参数为原矩阵*/ 
  75. public function inv($data) { 
  76.   $m = count($data); 
  77.   $n = count($data[0]); 
  78.   $data2 =[]; 
  79.   $det_val = $this->cal_det($data); 
  80.   $data2 = $this->ajoint($data); 
  81.   for ($i = 0; $i < $m; $i++) { 
  82.     for ($j = 0; $j < $n; $j++) { 
  83.       $data2[$i][$j] = $data2[$i][$j] / $det_val; 
  84.     } 
  85.   } 
  86.   return $data2; 
  87. } 
  88. /*求两矩阵的乘积*/ 
  89. public function getProduct($data1, $data2) { 
  90.   /*$data1 为左乘矩阵*/ 
  91.   $m1 = count($data1); 
  92.   $n1 = count($data1[0]); 
  93.   $m2 = count($data2); 
  94.   $n2 = count($data2[0]); 
  95.   $data_new =[]; 
  96.   if ($n1 !== $m2) { 
  97.     return false; 
  98.   } else { 
  99.     for ($i = 0; $i <= $m1 -1; $i++) { 
  100.       for ($k = 0; $k <= $n2 -1; $k++) { 
  101.         $data_new[$i][$k] = 0; 
  102.         for ($j = 0; $j <= $n1 -1; $j++) { 
  103.           $data_new[$i][$k] += $data1[$i][$j] * $data2[$j][$k]; 
  104.         } 
  105.       } 
  106.     } 
  107.   } 
  108.   return $data_new; 
  109. } 
  110. /*多元线性方程*/ 
  111. public function getParams($arr_x, $arr_y) { 
  112.   $final =[]; 
  113.   $arr_x_t = $this->trans($arr_x); 
  114.   $result = $this->getProduct($this->getProduct($this->inv($this->getProduct($arr_x_t, $arr_x)), $arr_x_t), $arr_y); 
  115.   foreach ($result as $key => $val) { 
  116.     foreach ($val as $_k => $_v) { 
  117.       $final[] = $_v; 
  118.     } 
  119.   } 
  120.   return $final; 
  121. } 

最后的getParams()方法就是最后求b参数数组的方法,传入一个二维数组arr_x, 和一个一维数组arr_y就可以了。

Tags: PHP多元线性 PHP模拟曲线

分享到: