Логарифмические наименьшие квадраты
Поскольку мы можем преобразовать логарифмическую функцию в строку, взяв 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
точкам данных.
Для данных примера, приведенных в комментарии ниже, логарифмическая функция не подходит.
Решение для наименьших квадратов - y = -514.734835478 + 2180.51562281 * log(x)
, которое по сути является линией в этой области.