基于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 相关文章推荐
简单的过滤字符串中的HTML标记
Dec 25 PHP
php 日期时间处理函数小结
Dec 18 PHP
用PHP+MySQL搭建聊天室功能实例代码
Aug 20 PHP
php排序算法(冒泡排序,快速排序)
Oct 09 PHP
PHP 异步执行方法,模拟多线程的应用分析
Jun 03 PHP
解析MySql与Java的时间类型
Jun 22 PHP
使用php验证复选框有效性的示例
Nov 13 PHP
ThinkPHP权限认证Auth实例详解
Jul 22 PHP
php比较相似字符串的方法
Jun 05 PHP
php验证码生成器
May 24 PHP
php取出数组单个值的方法
Mar 12 PHP
PHP扩展Swoole实现实时异步任务队列示例
Apr 13 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
如何开始收听短波广播
2021/03/01 无线电
解析Linux下Varnish缓存的配置优化
2013/06/20 PHP
PHP中关键字interface和implements详解
2017/06/14 PHP
laravel如何开启跨域功能示例详解
2017/08/31 PHP
Laravel使用swoole实现websocket主动消息推送的方法介绍
2019/10/20 PHP
Yii框架getter与setter方法功能与用法分析
2019/10/22 PHP
详解new function(){}和function(){}() 区别分析
2008/03/22 Javascript
JavaScript 常用函数库详解
2009/10/21 Javascript
jquery库或JS文件在eclipse下报错问题解决方法
2014/04/17 Javascript
jQuery中attr()方法用法实例
2015/01/05 Javascript
js clearInterval()方法的定义和用法
2015/11/11 Javascript
详解Bootstrap的aria-label和aria-labelledby应用
2016/01/04 Javascript
BootStrap智能表单实战系列(九)表单图片上传的支持
2016/06/13 Javascript
JavaScript浏览器对象模型BOM(BrowserObjectModel)实例详解
2016/11/29 Javascript
Vue.js原理分析之observer模块详解
2017/02/17 Javascript
详解JavaScript对数组操作(添加/删除/截取/排序/倒序)
2019/04/28 Javascript
解决 viewer.js 动态更新图片导致无法预览的问题
2019/05/14 Javascript
Vue项目中使用WebUploader实现文件上传的方法
2019/07/21 Javascript
关于layui flow loading占位图的实现方法
2019/09/21 Javascript
vue2.x 对象劫持的原理实现
2020/04/19 Javascript
Python基于matplotlib绘制栈式直方图的方法示例
2017/08/09 Python
python 实现在txt指定行追加文本的方法
2018/04/29 Python
python3.4爬虫demo
2019/01/22 Python
使用Python操作FTP实现上传和下载的方法
2019/04/01 Python
python自动循环定时开关机(非重启)测试
2019/08/26 Python
Python socket非阻塞模块应用示例
2019/09/12 Python
解决Windows下python和pip命令无法使用的问题
2020/08/31 Python
Python 排序最长英文单词链(列表中前一个单词末字母是下一个单词的首字母)
2020/12/14 Python
汤米巴哈马官方网站:Tommy Bahama
2017/05/13 全球购物
专题组织生活会方案
2014/06/15 职场文书
2014年预算员工作总结
2014/12/05 职场文书
师范生小学见习总结
2015/06/23 职场文书
感恩老师主题班会
2015/08/12 职场文书
写一个Python脚本自动爬取Bilibili小视频
2021/04/24 Python
Java实战之用Swing实现通讯录管理系统
2021/06/13 Java/Android
python如何为list实现find方法
2022/05/30 Python