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.

War es hilfreich?

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

gegeben erzeugen
  // 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.

alt text

Für das Beispiel angegebenen Daten in dem Kommentar unten, eine logarithmische Funktion paßt nicht gut.

alt text

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

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top