Как я могу рассчитать линию тренда в PHP?

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

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

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

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

Поскольку мы можем преобразовать логарифмическую функцию в прямую, взяв 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) которое по существу является линией в этой области.

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

Доступно Composer: https://packagist.org/packages/dr-que/polynomial-regression .