基于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 相关文章推荐
ADODB类使用
Nov 25 PHP
php 高效率写法 推荐
Feb 21 PHP
PHP下打开URL地址的几种方法小结
May 16 PHP
php实现用户在线时间统计详解
Oct 08 PHP
CURL状态码列表(详细)
Jun 27 PHP
win7 64位系统 配置php最新版开发环境(php+Apache+mysql)
Aug 15 PHP
php上传图片客户端和服务器端实现方法
Mar 30 PHP
PHP的Yii框架的常用日志操作总结
Dec 08 PHP
Laravel 5.3 学习笔记之 配置
Aug 28 PHP
php实现的中文分词类完整实例
Feb 06 PHP
浅谈Yii乐观锁的使用及原理
Jul 25 PHP
Laravel如何实现适合Api的异常处理响应格式
Jun 14 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
php二分法在IP地址查询中的应用
2008/08/12 PHP
php获取网站百度快照日期的方法
2015/07/29 PHP
php metaphone()函数的定义和用法
2016/05/15 PHP
javascript下数值型比较难点说明
2010/06/07 Javascript
javascript结合CSS实现苹果开关按钮特效
2015/04/07 Javascript
vue-cli构建项目使用 less的方法
2017/10/04 Javascript
利用three.js画一个3D立体的正方体示例代码
2017/11/19 Javascript
原生js实现简单的焦点图效果实例
2017/12/14 Javascript
Bootstrap标签页(Tab)插件切换echarts不显示问题的解决
2018/07/13 Javascript
微信小程序MUI侧滑导航菜单示例(Popup弹出式,左侧不动,右侧滑动)
2019/01/23 Javascript
Vue编程式跳转的实例代码详解
2019/07/10 Javascript
JavaScript 实现同时选取多个时间段的方法
2019/10/17 Javascript
微信小程序 wx.getUserInfo引导用户授权问题实例分析
2020/03/09 Javascript
vue中keep-alive内置组件缓存的实例代码
2020/04/16 Javascript
JS canvas实现画板和签字板功能
2021/02/23 Javascript
[40:57]TI4 循环赛第二日 iG vs EG
2014/07/11 DOTA
Python中还原JavaScript的escape函数编码后字符串的方法
2014/08/22 Python
举例区分Python中的浅复制与深复制
2015/07/02 Python
Python win32com 操作Exce的l简单方法(必看)
2017/05/25 Python
python 脚本生成随机 字母 + 数字密码功能
2018/05/26 Python
Django项目中包含多个应用时对url的配置方法
2018/05/30 Python
Python提取频域特征知识点浅析
2019/03/04 Python
Python判断对象是否为文件对象(file object)的三种方法示例
2019/04/26 Python
详解Python sys.argv使用方法
2019/05/10 Python
PyCharm+Qt Designer+PyUIC安装配置教程详解
2019/06/13 Python
如何运行带参数的python脚本
2019/11/15 Python
改变 Python 中线程执行顺序的方法
2020/09/24 Python
python Yaml、Json、Dict之间的转化
2020/10/19 Python
有影响力的人、名人和艺术家的官方商品:Represent
2019/11/26 全球购物
个人自我鉴定写法
2013/11/30 职场文书
初中军训感想300字
2014/03/05 职场文书
质量提升方案
2014/06/16 职场文书
四大名著读书笔记
2015/06/25 职场文书
五星级酒店宣传口号
2015/12/25 职场文书
CSS中实现动画效果-附案例
2022/02/28 HTML / CSS
索尼ICF-5900W收音机测评
2022/04/24 无线电