基于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 相关文章推荐
基于Zookeeper的使用详解
May 02 PHP
解析thinkphp的左右值无限分类
Jun 20 PHP
解析php中var_dump,var_export,print_r三个函数的区别
Jun 21 PHP
学习php中的正则表达式
Aug 17 PHP
php查询mysql大量数据造成内存不足的解决方法
Mar 04 PHP
PHP curl伪造IP地址和header信息代码实例
Apr 27 PHP
php cookie用户登录的详解及实例代码
Jan 03 PHP
php 5.4 全新的代码复用Trait详解
Jan 05 PHP
php基于SQLite实现的分页功能示例
Jun 21 PHP
PHP文件管理之实现网盘及压缩包的功能操作
Sep 20 PHP
php JWT在web端中的使用方法教程
Sep 06 PHP
PHP命名空间与自动加载机制的基础介绍
Aug 25 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
基于数据库的在线人数,日访问量等统计
2006/10/09 PHP
php使用GeoIP库实例
2014/06/27 PHP
分享php邮件管理器源码
2016/01/06 PHP
php使用escapeshellarg时中文被过滤的解决方法
2016/07/10 PHP
lnmp安装多版本PHP共存的方法详解
2018/08/02 PHP
利用PHP计算有多少小于当前数字的数字方法示例
2020/08/26 PHP
thinkphp诸多限制条件下如何getshell详解
2020/12/09 PHP
使用jQuery全局事件ajaxStart为特定请求实现提示效果的代码
2010/12/30 Javascript
基于jquery的下拉框改变动态添加和删除表格实现代码
2020/09/12 Javascript
JavaScript中的noscript元素属性位置及作用介绍
2013/04/11 Javascript
jquery查找父元素、子元素(个人经验总结)
2014/04/09 Javascript
关注jquery技巧提高jquery技能(前端开发必学)
2015/11/02 Javascript
vue.js入门教程之基础语法小结
2016/09/01 Javascript
JS简单实现浮动窗口效果示例
2016/09/07 Javascript
js数组去重的hash方法
2016/12/22 Javascript
bootstrap提示标签、提示框实现代码
2016/12/28 Javascript
浅谈vue的props,data,computed变化对组件更新的影响
2018/01/16 Javascript
深入理解Vue router的部分高级用法
2018/08/15 Javascript
解决vue2.0路由跳转未匹配相应用路由避免出现空白页面的问题
2018/08/24 Javascript
vue 实现一个简单的全局调用弹窗案例
2020/09/10 Javascript
[03:57]DOTA2英雄梦之声_第03期_幻影刺客
2014/06/21 DOTA
Python实现树的先序、中序、后序排序算法示例
2017/06/23 Python
pandas 数据实现行间计算的方法
2018/06/08 Python
Python Flask框架扩展操作示例
2019/05/03 Python
Django实现从数据库中获取到的数据转换为dict
2020/03/27 Python
解决Python中报错TypeError: must be str, not bytes问题
2020/04/07 Python
浅谈Keras的Sequential与PyTorch的Sequential的区别
2020/06/17 Python
windows+vscode安装paddleOCR运行环境的步骤
2020/11/11 Python
CSS3绘制超炫的上下起伏波动进度加载动画
2016/04/21 HTML / CSS
Canvas在超级玛丽游戏中的应用详解
2021/02/06 HTML / CSS
Foot Locker加拿大官网:美国知名运动产品零售商
2019/07/21 全球购物
物业工作计划书
2014/01/10 职场文书
个人债务授权委托书范本
2014/10/05 职场文书
房屋租赁合同解除协议书
2014/10/11 职场文书
2015年保安个人工作总结
2015/04/02 职场文书
会议新闻稿
2015/07/17 职场文书