Wie kann ich eine Trendlinie in PHP berechnen?
-
03-10-2019 - |
Frage
So habe ich die zwei miteinander verbundene Fragen gelesen habe eine Trendlinie für eine grafische Darstellung für die Berechnung, aber ich bin immer noch verloren.
Ich habe ein Array von xy-Koordinaten, und ich möchte mit einem anderen Array von xy-Koordinaten kommen (können weniger Koordinaten sein), die eine logarithmische Trendlinie mit PHP darstellen.
ich diese Arrays Javascript Plot Grafiken auf der Client-Seite übergeben.
Lösung
logarithmisch Least Squares
Da wir eine logarithmische Funktion in eine Linie, indem sie die log
der x
Werte umwandeln kann, können wir eine linear least squares Kurvenanpassung. In der Tat hat sich die Arbeit für uns getan und eine Lösung unter Math Welt präsentiert wird.
Kurz gesagt, sind wir $X
und $Y
Werte gegeben, die von einer Verteilung wie y = a + b * log(x)
sind. Die Methode der kleinsten Quadrate werden einige Werte aFit
und bFit
geben, dass der Abstand von der Parameterkurve an die Datenpunkte gegeben minimieren.
Hier ist ein Beispiel-Implementierung in PHP:
Zuerst werde ich einige zufälligen Daten mit bekannter zugrunde liegender Verteilung von $a
und $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);
}
Nun, hier ist, wie die Gleichungen zu schätzen $a
und $b
gegeben verwenden.
// 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;
Sie können dann Punkte für Ihre Javascript erzeugen so dicht, wie Sie mögen:
$Yfit = array();
foreach($X as $x) {
$Yfit[] = $aFit + $bFit * log($x);
}
In diesem Fall wird der Code schätzt bFit = 5.17
und aFit = 9.7
, die für nur 50
Datenpunkte ganz in der Nähe ist.
Für das Beispiel angegebenen Daten in dem Kommentar unten, eine logarithmische Funktion paßt nicht gut.
Die Lösung der kleinsten Quadrate ist y = -514.734835478 + 2180.51562281 * log(x)
die im Wesentlichen eine Linie in dieser Domäne ist.
Andere Tipps
Ich würde mit Bibliothek empfehlen: http://www.drque.net/Projects/PolynomialRegression/
Verfügbar nach Komponist: https://packagist.org/packages/dr-que/ Polynom-Regression .