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


Posted in PHP onJanuary 30, 2018

本文实例讲述了基于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;

方法:利用最小二乘法

公式:基于PHP实现的多元线性回归模拟曲线算法我们只用公式的前半部分,也就是用矩阵来计算

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

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

public function get_complement($data, $i, $j) {
  /* x和y为矩阵data的行数和列数 */
  $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;
}
/*求矩阵的逆,输入参数为原矩阵*/
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参数数组的方法,传入一个二维数组arr_x, 和一个一维数组arr_y就可以了。

这一般用于大数据分析,根据大数据来模拟和预测下面的发展和走势。

PHP 相关文章推荐
NT IIS下用ODBC连接数据库
Oct 09 PHP
php+dojo 的数据库保存拖动布局的一个方法dojo 这里下载
Mar 07 PHP
如何提高MYSQL数据库的查询统计速度 select 索引应用
Apr 11 PHP
PHP Token(令牌)设计
Mar 15 PHP
php中的常用魔术方法总结
Aug 02 PHP
php实现excel中rank函数功能的方法
Jan 20 PHP
php生成图片缩略图的方法
Apr 07 PHP
PHP中使用array函数新建一个数组
Nov 19 PHP
浅谈PHP的反射API
Feb 26 PHP
利用laravel+ajax实现文件上传功能方法示例
Aug 13 PHP
浅析PHP类的反射来实现依赖注入过程
Feb 06 PHP
PHP的mysqli_set_charset()函数讲解
Jan 23 PHP
PHP 记录访客的浏览信息方法
Jan 29 #PHP
laravel ORM 只开启created_at的几种方法总结
Jan 29 #PHP
PHP+Redis 消息队列 实现高并发下注册人数统计的实例
Jan 29 #PHP
PHP 使用二进制保存用户状态的实例
Jan 29 #PHP
thinkphp3.2.0 setInc方法 源码全面解析
Jan 29 #PHP
Ubuntu上安装yaf扩展的方法
Jan 29 #PHP
PHP实现的防止跨站和xss攻击代码【来自阿里云】
Jan 29 #PHP
You might like
mysql From_unixtime及UNIX_TIMESTAMP及DATE_FORMAT日期函数
2010/03/21 PHP
调整优化您的LAMP应用程序的5种简单方法
2011/06/26 PHP
php中获得视频时间总长度的另一种方法
2011/09/15 PHP
php实现xml与json之间的相互转换功能实例
2016/07/07 PHP
windows下的WAMP环境搭建图文教程(推荐)
2017/07/27 PHP
JavaScript中的方法重载实例
2015/03/16 Javascript
每天一篇javascript学习小结(面向对象编程)
2015/11/20 Javascript
jQuery实现图像旋转动画效果
2016/05/29 Javascript
在微信、支付宝、百度钱包实现点击返回按钮关闭当前页面和窗口的方法
2016/08/05 Javascript
AngularJS HTML DOM详解及示例代码
2016/08/17 Javascript
详解为Angular.js内置$http服务添加拦截器的方法
2016/12/20 Javascript
JavaScript中最常见的三个面试题解析
2017/03/04 Javascript
浅谈Angular4实现热加载开发旅程
2017/09/08 Javascript
深入理解React高阶组件
2017/09/28 Javascript
jquery在启动页面时,自动加载数据的实例
2018/01/22 jQuery
nodejs实现范围请求的实现代码
2018/10/12 NodeJs
使用Typescript开发微信小程序的步骤详解
2021/01/12 Javascript
[01:06:12]VP vs NIP 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/17 DOTA
python使用urllib2实现发送带cookie的请求
2015/04/28 Python
简单介绍Python中用于求最小值的min()方法
2015/05/15 Python
Python multiprocess pool模块报错pickling error问题解决方法分析
2019/03/20 Python
Python安装与基本数据类型教程详解
2019/05/29 Python
matplotlib绘制多个子图(subplot)的方法
2019/12/03 Python
Django 解决新建表删除后无法重新创建等问题
2020/05/21 Python
python实现银行账户系统
2021/02/22 Python
Html5页面获取微信公众号的openid的方法
2020/05/12 HTML / CSS
Guess美国官网:美国知名服装品牌
2019/04/08 全球购物
Java中实现多态的机制
2015/08/09 面试题
有个性的自我评价范文
2013/11/15 职场文书
导购员的岗位职责
2014/02/08 职场文书
自荐信如何制作?
2014/02/21 职场文书
2014年公务员思想汇报范文:全心全意为人民服务
2014/03/06 职场文书
求职信怎么写范文
2014/05/26 职场文书
合作意向书
2014/07/30 职场文书
三下乡活动心得体会
2016/01/23 职场文书
使用python向MongoDB插入时间字段的操作
2021/05/18 Python