当前位置:首页 > 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. public function cal_det($data) { 
  29.   $ans = 0; 
  30.   if (count($data[0]) === 2) { 
  31.     $ans = $data[0][0] * $data[1][1] - $data[0][1] * $data[1][0]; 
  32.   } else { 
  33.     for ($i = 0; $i < count($data[0]); $i++) { 
  34.       $data_temp = $this->get_complement($data, 0, $i); 
  35.       if ($i % 2 === 0) { 
  36.         $ans = $ans + $data[0][$i] * ($this->cal_det($data_temp)); 
  37.       } else { 
  38.         $ans = $ans - $data[0][$i] * ($this->cal_det($data_temp)); 
  39.       } 
  40.     } 
  41.   } 
  42.   return $ans
  43. /*计算矩阵的伴随矩阵*/ 
  44. public function ajoint($data) { 
  45.   $m = count($data); 
  46.   $n = count($data[0]); 
  47.   $data2 =[]; 
  48.   for ($i = 0; $i < $m$i++) { 
  49.     for ($j = 0; $j < $n$j++) { 
  50.       if (($i + $j) % 2 === 0) { 
  51.         $data2[$i][$j] = $this->cal_det($this->get_complement($data$i$j)); 
  52.       } else { 
  53.         $data2[$i][$j] = - $this->cal_det($this->get_complement($data$i$j)); 
  54.       } 
  55.     } 
  56.   } 
  57.   return $this->trans($data2); 
  58. /*转置矩阵*/ 
  59. public function trans($data) { 
  60.   $i = count($data); 
  61.   $j = count($data[0]); 
  62.   $data2 =[]; 
  63.   for ($k2 = 0; $k2 < $j$k2++) { 
  64.     for ($k1 = 0; $k1 < $i$k1++) { 
  65.       $data2[$k2][$k1] = $data[$k1][$k2]; 
  66.     } 
  67.   } 
  68.   /*将矩阵转置便可得到伴随矩阵*/ 
  69.   return $data2
  70. /*求矩阵的逆,输入参数为原矩阵*/ 
  71. public function inv($data) { 
  72.   $m = count($data); 
  73.   $n = count($data[0]); 
  74.   $data2 =[]; 
  75.   $det_val = $this->cal_det($data); 
  76.   $data2 = $this->ajoint($data); 
  77.   for ($i = 0; $i < $m$i++) { 
  78.     for ($j = 0; $j < $n$j++) { 
  79.       $data2[$i][$j] = $data2[$i][$j] / $det_val
  80.     } 
  81.   } 
  82.   return $data2
  83. /*求两矩阵的乘积*/ 
  84. public function getProduct($data1$data2) { 
  85.   /*$data1 为左乘矩阵*/ 
  86.   $m1 = count($data1); 
  87.   $n1 = count($data1[0]); 
  88.   $m2 = count($data2); 
  89.   $n2 = count($data2[0]); 
  90.   $data_new =[]; 
  91.   if ($n1 !== $m2) { 
  92.     return false; 
  93.   } else { 
  94.     for ($i = 0; $i <= $m1 -1; $i++) { 
  95.       for ($k = 0; $k <= $n2 -1; $k++) { 
  96.         $data_new[$i][$k] = 0; 
  97.         for ($j = 0; $j <= $n1 -1; $j++) { 
  98.           $data_new[$i][$k] += $data1[$i][$j] * $data2[$j][$k]; 
  99.         } 
  100.       } 
  101.     } 
  102.   } 
  103.   return $data_new
  104. /*多元线性方程*/ 
  105. public function getParams($arr_x$arr_y) { 
  106.   $final =[]; 
  107.   $arr_x_t = $this->trans($arr_x); 
  108.   $result = $this->getProduct($this->getProduct($this->inv($this->getProduct($arr_x_t$arr_x)), $arr_x_t), $arr_y); 
  109.   foreach ($result as $key => $val) { 
  110.     foreach ($val as $_k => $_v) { 
  111.       $final[] = $_v
  112.     } 
  113.   } 
  114.   return $final

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

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

分享到: