如何在PHP中计算趋势线? [英] How can I calculate a trend line in PHP?

查看:90
本文介绍了如何在PHP中计算趋势线?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我已经阅读了有关计算图形趋势线的两个相关问题,但是我仍然迷失了方向.

我有一个xy坐标数组,我想提出另一个xy坐标数组(可以减少坐标),这些数组代表使用PHP的对数趋势线.

我将这些数组传递给javascript以在客户端绘制图.

解决方案

对数最小二乘

由于我们可以通过取x值的log将对数函数转换为一行,因此我们可以执行线性最小二乘曲线拟合.实际上,这项工作已经为我们完成,并且在数学世界中提供了解决方案. >

简而言之,我们给了$X$Y值,它们来自像y = a + b * log(x)这样的分布.最小二乘方法将提供一些值aFitbFit,这些值将最小化参数曲线到给定数据点的距离.

以下是PHP中的示例实现:

首先,我将生成一些随机数据,这些随机数据具有$a$b

给出的已知基础分布

  // True parameter valaues
  $a = 10;
  $b = 5;

  // Range of x values to generate
  $x_min = 1;
  $x_max = 10;
  $nPoints = 50;

  // Generate some random points on y = a * log(x) + b
  $X = array();
  $Y = array();
  for($p = 0; $p < $nPoints; $p++){
    $x = $p / $nPoints * ($x_max - $x_min) + $x_min;
    $y = $a + $b * log($x);

    $X[] = $x + rand(0, 200) / ($nPoints * $x_max);
    $Y[] = $y + rand(0, 200) / ($nPoints * $x_max);

  }

现在,这是使用给定的方程式估算$a$b的方法.

  // Now convert to log-scale for X
  $logX = array_map('log', $X);

  // Now estimate $a and $b using equations from Math World
  $n = count($X);
  $square = create_function('$x', 'return pow($x,2);');
  $x_squared = array_sum(array_map($square, $logX));
  $xy = array_sum(array_map(create_function('$x,$y', 'return $x*$y;'), $logX, $Y));

  $bFit = ($n * $xy - array_sum($Y) * array_sum($logX)) /
          ($n * $x_squared - pow(array_sum($logX), 2));

  $aFit = (array_sum($Y) - $bFit * array_sum($logX)) / $n;

然后,您可以根据需要密集地为Javascript生成点:

  $Yfit = array();
  foreach($X as $x) {
    $Yfit[] = $aFit + $bFit * log($x);
  }

在这种情况下,代码估算bFit = 5.17aFit = 9.7,这对于50数据点而言非常接近.

对于以下注释中给出的示例数据,对数函数不太适合.

最小二乘解是y = -514.734835478 + 2180.51562281 * log(x),本质上是该域中的线.

So I've read the two related questions for calculating a trend line for a graph, but I'm still lost.

I have an array of xy coordinates, and I want to come up with another array of xy coordinates (can be fewer coordinates) that represent a logarithmic trend line using PHP.

I'm passing these arrays to javascript to plot graphs on the client side.

解决方案

Logarithmic Least Squares

Since we can convert a logarithmic function into a line by taking the log of the x values, we can perform a linear least squares curve fitting. In fact, the work has been done for us and a solution is presented at Math World.

In brief, we're given $X and $Y values that are from a distribution like y = a + b * log(x). The least squares method will give some values aFit and bFit that minimize the distance from the parametric curve to the data points given.

Here is an example implementation in PHP:

First I'll generate some random data with known underlying distribution given by $a and $b

  // True parameter valaues
  $a = 10;
  $b = 5;

  // Range of x values to generate
  $x_min = 1;
  $x_max = 10;
  $nPoints = 50;

  // Generate some random points on y = a * log(x) + b
  $X = array();
  $Y = array();
  for($p = 0; $p < $nPoints; $p++){
    $x = $p / $nPoints * ($x_max - $x_min) + $x_min;
    $y = $a + $b * log($x);

    $X[] = $x + rand(0, 200) / ($nPoints * $x_max);
    $Y[] = $y + rand(0, 200) / ($nPoints * $x_max);

  }

Now, here's how to use the equations given to estimate $a and $b.

  // Now convert to log-scale for X
  $logX = array_map('log', $X);

  // Now estimate $a and $b using equations from Math World
  $n = count($X);
  $square = create_function('$x', 'return pow($x,2);');
  $x_squared = array_sum(array_map($square, $logX));
  $xy = array_sum(array_map(create_function('$x,$y', 'return $x*$y;'), $logX, $Y));

  $bFit = ($n * $xy - array_sum($Y) * array_sum($logX)) /
          ($n * $x_squared - pow(array_sum($logX), 2));

  $aFit = (array_sum($Y) - $bFit * array_sum($logX)) / $n;

You may then generate points for your Javascript as densely as you like:

  $Yfit = array();
  foreach($X as $x) {
    $Yfit[] = $aFit + $bFit * log($x);
  }

In this case, the code estimates bFit = 5.17 and aFit = 9.7, which is quite close for only 50 data points.

For the example data given in the comment below, a logarithmic function does not fit well.

The least squares solution is y = -514.734835478 + 2180.51562281 * log(x) which is essentially a line in this domain.

这篇关于如何在PHP中计算趋势线?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆