Как я могу рассчитать линию тренда в PHP? - PullRequest
12 голосов
/ 05 мая 2010

Итак, я прочитал два связанных вопроса для расчета линии тренда для графика, но я все еще потерян.

У меня есть массив координат xy, и я хочу предложить другой массив координат xy (может быть меньше координат), которые представляют логарифмическую линию тренда с использованием PHP.

Я передаю эти массивы в javascript для построения графиков на стороне клиента.

Ответы [ 2 ]

29 голосов
/ 05 мая 2010

Логарифмические наименьшие квадраты

Поскольку мы можем преобразовать логарифмическую функцию в строку, взяв log из значений x, мы можем выполнить линейное наименьших квадратов подгонку кривой. Фактически, работа была проделана за нас, и решение представлено на Math World .

Вкратце, нам даны значения $X и $Y, которые относятся к распределению, подобному y = a + b * log(x). Метод наименьших квадратов даст некоторые значения aFit и bFit, которые минимизируют расстояние от параметрической кривой до заданных точек данных.

Вот пример реализации в 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.17 и aFit = 9.7, что довольно близко только к 50 точкам данных.

alt text

Для данных примера, приведенных в комментарии ниже, логарифмическая функция не подходит.

alt text

Решение для наименьших квадратов - y = -514.734835478 + 2180.51562281 * log(x), которое по сути является линией в этой области.

3 голосов
/ 03 октября 2015

Я бы порекомендовал использовать библиотеку: http://www.drque.net/Projects/PolynomialRegression/

Доступно для композитора: https://packagist.org/packages/dr-que/polynomial-regression.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...