Einleitung
Im Vergleich zu anderen Open-Source-Sprachen wie Perl und Python mangelt es der PHP-Community an großen Anstrengungen zur Entwicklung mathematischer Bibliotheken.
Ein Grund dafür könnte sein, dass es bereits eine große Anzahl ausgereifter mathematischer Tools gibt, was die Bemühungen der Community, PHP-Tools selbst zu entwickeln, behindern könnte. Ich habe beispielsweise an einem leistungsstarken Tool gearbeitet, S System, das über eine beeindruckende Menge an Statistikbibliotheken verfügte, speziell für die Analyse von Datensätzen entwickelt wurde und 1998 für sein Sprachdesign einen ACM Award gewann. Wenn S oder sein Open-Source-Cousin R nur ein exec_shell-Aufruf ist, warum sollte man sich dann die Mühe machen, die gleiche Funktionalität für statistische Berechnungen in PHP zu implementieren? Weitere Informationen zum S-System, seinem ACM Award oder R finden Sie in den entsprechenden Referenzen.
Ist das nicht eine Verschwendung von Entwicklerenergie? Wenn die Motivation für die Entwicklung einer PHP-Mathebibliothek darin besteht, Entwickleraufwand zu sparen und das beste Tool für den Job zu verwenden, dann ist das aktuelle Thema von PHP sinnvoll.
Andererseits können pädagogische Motivationen die Entwicklung von PHP-Mathebibliotheken fördern. Für etwa 10 % der Menschen ist Mathematik ein interessantes Fach, das es wert ist, erkundet zu werden. Für diejenigen, die sich auch mit PHP auskennen, kann die Entwicklung einer PHP-Mathe-Bibliothek den Mathematik-Lernprozess verbessern. Mit anderen Worten: Lesen Sie nicht nur das Kapitel über T-Tests, sondern implementieren Sie auch ein Programm, das die entsprechenden Zwischenwerte berechnen kann Werte und zeigen sie in einem Standardformat an.
Durch Anleitung und Schulung möchte ich zeigen, dass die Entwicklung einer PHP-Mathebibliothek keine schwierige Aufgabe ist und eine interessante technische und lerntechnische Herausforderung darstellen kann. In diesem Artikel werde ich ein Beispiel für eine PHP-Mathematikbibliothek namens SimpleLinearRegression bereitstellen, das einen allgemeinen Ansatz demonstriert, der zur Entwicklung von PHP-Mathematikbibliotheken verwendet werden kann. Beginnen wir mit der Erörterung einiger allgemeiner Prinzipien, die mich bei der Entwicklung der SimpleLinearRegression-Klasse geleitet haben.
Leitprinzipien
Ich habe sechs allgemeine Prinzipien verwendet, um die Entwicklung der SimpleLinearRegression-Klasse zu leiten.
Erstellen Sie für jedes Analysemodell eine Klasse.
Verwenden Sie Reverse-Linking, um Klassen zu entwickeln.
Es wird mit einer großen Zahl an Gettern gerechnet.
Zwischenergebnisse speichern.
Legen Sie Einstellungen für detaillierte APIs fest.
Perfektion ist nicht das Ziel.
Lassen Sie uns jede dieser Richtlinien genauer untersuchen.
Erstellen Sie für jedes Analysemodell eine Klasse,
die über eine PHP-Klasse mit demselben Namen wie der Test oder Prozess verfügt. Diese Klasse enthält Eingabefunktionen, Funktionen zur Berechnung von Zwischenwerten und Zusammenfassungswerten sowie Ausgabefunktionen. (Ersetzen der Zwischenwerte). Werte und Zusammenfassungswerte werden alle auf dem Bildschirm im Text- oder Grafikformat angezeigt.
Verwenden der umgekehrten Verkettung zum Entwickeln von Klassen
In der mathematischen Programmierung ist das Codierungsziel normalerweise der Standardausgabewert, den eine Analyseprozedur (z. B. MultipleRegression, TimeSeries oder ChiSquared) erzeugen möchte. Aus Sicht der Problemlösung bedeutet dies, dass Sie mithilfe der Rückwärtsverkettung mathematikähnliche Methoden entwickeln können.
Der zusammenfassende Ausgabebildschirm zeigt beispielsweise die Ergebnisse einer oder mehrerer zusammenfassender Statistiken an. Diese zusammenfassenden statistischen Ergebnisse basieren auf der Berechnung statistischer Zwischenergebnisse, und diese statistischen Zwischenergebnisse können tiefere statistische Zwischenergebnisse usw. beinhalten. Dieser Backlink-basierte Entwicklungsansatz führt zum nächsten Prinzip.
Erwarten Sie eine große Anzahl von Getter
-Mathematikklassen. Der Großteil der Klassenentwicklungsarbeit umfasst die Berechnung von Zwischen- und Zusammenfassungswerten. In der Praxis bedeutet dies, dass Sie sich nicht wundern sollten, wenn Ihre Klasse viele Getter-Methoden enthält, die Zwischen- und Zusammenfassungswerte berechnen.
Zwischenergebnisse speichern
Speichert die Ergebnisse einer Zwischenberechnung in einem Ergebnisobjekt, sodass Sie die Zwischenergebnisse als Eingabe für nachfolgende Berechnungen verwenden können. Dieses Prinzip wird im S-Sprachdesign umgesetzt. Im aktuellen Kontext wird dieses Prinzip durch die Auswahl von Instanzvariablen umgesetzt, um berechnete Zwischenwerte und zusammenfassende Ergebnisse darzustellen.
Festlegen von Einstellungen für eine detaillierte API
Beim Entwickeln eines Benennungsschemas für die Mitgliedsfunktionen und Instanzvariablen in der SimpleLinearRegression-Klasse habe ich festgestellt, dass, wenn ich längere Namen (etwa getSumSquaredError anstelle von getYY2 ) zur Beschreibung der Mitgliedsfunktionen und Instanzvariablen verwende, dies der Fall ist Es ist einfacher, den Operationsinhalt der Funktion und die Bedeutung der Variablen zu verstehen.
Ich habe abgekürzte Namen nicht ganz aufgegeben; wenn ich jedoch eine Kurzform eines Namens verwende, muss ich versuchen, eine Anmerkung zu geben, die die Bedeutung des Namens vollständig erklärt. Mein Standpunkt ist folgender: Stark abgekürzte Benennungsschemata sind in der mathematischen Programmierung üblich, aber sie erschweren das Verständnis und den Beweis, dass eine bestimmte mathematische Routine korrekt ist, als es sein müsste.
Perfektion ist nicht das Ziel
Das Ziel dieser Codierungsübung besteht nicht unbedingt darin, eine hochoptimierte und strenge Mathematik-Engine für PHP zu entwickeln. In der Anfangsphase sollte der Schwerpunkt darauf gelegt werden, zu lernen, aussagekräftige analytische Tests durchzuführen und schwierige Probleme in diesem Bereich zu lösen.
Instanzvariablen
Beim Modellieren eines statistischen Tests oder Prozesses müssen Sie angeben, welche Instanzvariablen deklariert werden.
Die Auswahl der Instanzvariablen kann durch Berücksichtigung der durch den Analyseprozess generierten Zwischen- und Zusammenfassungswerte bestimmt werden. Jeder Zwischen- und Zusammenfassungswert kann eine entsprechende Instanzvariable haben, wobei der Wert der Variablen eine Objekteigenschaft ist.
Ich habe diese Analyse verwendet, um zu bestimmen, welche Variablen für die SimpleLinearRegression-Klasse in Listing 1 deklariert werden sollen. Eine ähnliche Analyse kann für MultipleRegression-, ANOVA- oder TimeSeries-Prozeduren durchgeführt werden.
Listing 1. Instanzvariablen der SimpleLinearRegression-Klasse
<?php
// Copyright 2003, Paul Meagher
// Unter GPL vertrieben
Klasse SimpleLinearRegression {
var $n;
var $X = array();
var $Y = array();
var $ConfInt;
var $Alpha;
var $XMean;
var $YMean;
var $SumXX;
var $SumXY;
var $SumYY;
var $Steigung;
var $YInt;
var $PredictedY = array();
var $Error = array();
var $SquaredError = array();
var $TotalError;
var $SumError;
var $SumSquaredError;
var $ErrorVariance;
var $StdErr;
var $SlopeStdErr;
var $SlopeVal; // T-Wert der Steigung
var $YIntStdErr;
var $YIntTVal; // T-Wert für Y-Achsenabschnitt
var $R;
var $RSquared;
var $DF; // Freiheitsgrade
var $SlopeProb; // Wahrscheinlichkeit der Steigungsschätzung
var $YIntProb; // Wahrscheinlichkeit der Y-Intercept-Schätzung
var $AlphaTVal; // T Wert für gegebene Alpha-Einstellung
var $ConfIntOfSlope;
var $RPath = "/usr/local/bin/R"; // Ihr Pfad hierher
var $format = "%01.2f"; // Wird zur Formatierung der Ausgabe verwendet
}
?>
Konstruktor
Die Konstruktormethode der SimpleLinearRegression-Klasse akzeptiert einen X- und einen Y-Vektor mit jeweils der gleichen Anzahl an Werten. Sie können auch ein Standardkonfidenzintervall von 95 % für Ihren erwarteten Y-Wert festlegen.
Die Konstruktormethode überprüft zunächst, ob das Datenformular für die Verarbeitung geeignet ist. Sobald die Eingabevektoren die Tests „Gleichgröße“ und „Wert größer als 1“ bestehen, wird der Kernteil des Algorithmus ausgeführt.
Die Ausführung dieser Aufgabe umfasst die Berechnung der Zwischen- und Gesamtwerte des statistischen Prozesses mithilfe einer Reihe von Getter-Methoden. Weisen Sie den Rückgabewert jedes Methodenaufrufs einer Instanzvariablen der Klasse zu. Durch das Speichern von Berechnungsergebnissen auf diese Weise wird sichergestellt, dass Aufrufroutinen in verketteten Berechnungen Zwischen- und Summenwerte zur Verfügung stehen. Sie können diese Ergebnisse auch anzeigen, indem Sie die Ausgabemethode dieser Klasse aufrufen, wie in Listing 2 beschrieben.
Listing 2. Aufrufen von Klassenausgabemethoden
<?php
// Copyright 2003, Paul Meagher
// Unter GPL vertrieben
Funktion SimpleLinearRegression($X, $Y, $ConfidenceInterval="95") {
$numX = count($X);
$numY = count($Y);
if ($numX != $numY) {
die("Fehler: Die Größe der X- und Y-Vektoren muss gleich sein.");
}
if ($numX <= 1) {
die("Fehler: Die Größe des Eingabearrays muss mindestens 2 betragen.");
}
$this->n = $numX;
$this->X = $X;
$this->Y = $Y;
$this->ConfInt = $ConfidenceInterval;
$this->Alpha = (1 + ($this->ConfInt / 100) ) / 2;
$this->XMean = $this->getMean($this->X);
$this->YMean = $this->getMean($this->Y);
$this->SumXX = $this->getSumXX();
$this->SumYY = $this->getSumYY();
$this->SumXY = $this->getSumXY();
$this->Slope = $this->getSlope();
$this->YInt = $this->getYInt();
$this->PredictedY = $this->getPredictedY();
$this->Error = $this->getError();
$this->SquaredError = $this->getSquaredError();
$this->SumError = $this->getSumError();
$this->TotalError = $this->getTotalError();
$this->SumSquaredError = $this->getSumSquaredError();
$this->ErrorVariance = $this->getErrorVariance();
$this->StdErr = $this->getStdErr();
$this->SlopeStdErr = $this->getSlopeStdErr();
$this->YIntStdErr = $this->getYIntStdErr();
$this->SlopeTVal = $this->getSlopeTVal();
$this->YIntTVal = $this->getYIntTVal();
$this->R = $this->getR();
$this->RSquared = $this->getRSquared();
$this->DF = $this->getDF();
$this->SlopeProb = $this->getStudentProb($this->SlopeTVal, $this->DF);
$this->YIntProb = $this->getStudentProb($this->YIntTVal, $this->DF);
$this->AlphaTVal = $this->getInverseStudentProb($this->Alpha, $this->DF);
$this->ConfIntOfSlope = $this->getConfIntOfSlope();
return true;
}
?>
Methodennamen und ihre Sequenzen wurden durch eine Kombination aus Backlinking und Verweis auf ein von Studenten im Grundstudium verwendetes Statistiklehrbuch abgeleitet, in dem Schritt für Schritt erklärt wird, wie Zwischenwerte berechnet werden. Dem Namen des Zwischenwerts, den ich berechnen muss, wird „get“ vorangestellt, wodurch der Methodenname abgeleitet wird.
Passen Sie das Modell an die Daten an.
Mit der SimpleLinearRegression-Prozedur wird eine gerade Linienanpassung an die Daten erstellt, wobei die Linie die folgende Standardgleichung aufweist:
y = b + mx
.Das PHP-Format dieser Gleichung ähnelt Listing 3:
Listing 3. Passen Sie das Modell an die Daten-Matching-PHP-Gleichung an
$PredictedY[$i] = $YIntercept + $Slope * $X[$i]
Die SimpleLinearRegression-Klasse verwendet das Kriterium der kleinsten Quadrate, um Schätzungen der Parameter Y-Achsenabschnitt (Y Intercept) und Steigung (Slope) abzuleiten. Diese geschätzten Parameter werden verwendet, um eine lineare Gleichung zu erstellen (siehe Listing 3), die die Beziehung zwischen den X- und Y-Werten modelliert.
Mithilfe der abgeleiteten linearen Gleichung können Sie den vorhergesagten Y-Wert für jeden X-Wert erhalten. Wenn die lineare Gleichung gut zu den Daten passt, sind die beobachteten und vorhergesagten Werte von Y tendenziell konsistent.
So ermitteln Sie, ob eine gute Anpassung vorliegt
. Die SimpleLinearRegression-Klasse generiert eine ganze Reihe zusammenfassender Werte. Ein wichtiger zusammenfassender Wert ist die T-Statistik, die misst, wie gut eine lineare Gleichung zu den Daten passt. Wenn die Übereinstimmung sehr gut ist, ist die T-Statistik tendenziell groß. Wenn die T-Statistik klein ist, sollte die lineare Gleichung durch ein Modell ersetzt werden, das davon ausgeht, dass der Mittelwert der Y-Werte der beste Prädiktor ist (d. h. der Mittelwert einer Reihe von Werten ist normalerweise ein nützlicher Prädiktor). der nächsten Beobachtung machen Sie es zum Standardmodell).
Um zu testen, ob die T-Statistik groß genug ist, um den Mittelwert der Y-Werte nicht als besten Prädiktor zu betrachten, müssen Sie die Zufallswahrscheinlichkeit für den Erhalt der T-Statistik berechnen. Wenn die Wahrscheinlichkeit, eine T-Statistik zu erhalten, gering ist, können Sie die Nullhypothese, dass der Mittelwert der beste Prädiktor ist, ablehnen und dementsprechend sicher sein, dass das einfache lineare Modell gut zu den Daten passt.
Wie berechnet man also die Wahrscheinlichkeit des T-Statistikwerts?
Berechnung der Wahrscheinlichkeit des T-Statistikwerts
Da PHP keine mathematischen Routinen zur Berechnung der Wahrscheinlichkeit des T-Statistikwerts hat, habe ich beschlossen, diese Aufgabe dem statistischen Rechenpaket R (siehe www.r-project.org in Ressourcen) zu überlassen die notwendigen Werte erhalten. Ich möchte auch die Aufmerksamkeit auf dieses Paket lenken, weil:
R viele Ideen bietet, die ein PHP-Entwickler in einer PHP-Mathebibliothek emulieren könnte.
Mit R kann festgestellt werden, ob die aus der PHP-Mathematikbibliothek erhaltenen Werte mit denen übereinstimmen, die aus ausgereiften, frei verfügbaren Open-Source-Statistikpaketen erhalten wurden.
Der Code in Listing 4 zeigt, wie einfach es ist, R das Erhalten eines Werts zu überlassen.
Listing 4. Verarbeiten Sie es mit dem R-Statistikpaket, um einen Wert zu erhalten
<?php
// Copyright 2003, Paul Meagher
// Unter GPL vertrieben
Klasse SimpleLinearRegression {
var $RPath = "/usr/local/bin/R"; // Ihr Pfad hierher
Funktion getStudentProb($T, $df) {
$Wahrscheinlichkeit = 0,0;
$cmd = "echo 'dt($T, $df)' | $this->RPath --slave";
$result = shell_exec($cmd);
list($LineNumber, $Probability) = explosion(" ", trim($result));
return $Probability;
}
Funktion getInverseStudentProb($alpha, $df) {
$InverseProbability = 0.0;
$cmd = "echo 'qt($alpha, $df)' | $this->RPath --slave";
$result = shell_exec($cmd);
list($LineNumber, $InverseProbability) = explosion(" ", trim($result));
return $InverseProbability;
}
}
?>
Beachten Sie, dass der Pfad zur ausführbaren R-Datei festgelegt und in beiden Funktionen verwendet wurde. Die erste Funktion gibt den mit der T-Statistik verbundenen Wahrscheinlichkeitswert basierend auf der Student-T-Verteilung zurück, während die zweite Umkehrfunktion die T-Statistik entsprechend der gegebenen Alpha-Einstellung berechnet. Die Methode getStudentProb wird verwendet, um die Anpassung des linearen Modells zu bewerten. Die Methode getInverseStudentProb gibt einen Zwischenwert zurück, der zur Berechnung des Konfidenzintervalls für jeden vorhergesagten Y-Wert verwendet wird.
Aufgrund des begrenzten Platzes ist es mir unmöglich, alle Funktionen in dieser Klasse einzeln zu beschreiben. Wenn Sie also die Terminologie und die Schritte einer einfachen linearen Regressionsanalyse herausfinden möchten, empfehle ich Ihnen, sich auf das verwendete Statistiklehrbuch zu beziehen von Bachelor-Studenten.
Burnout-Studie
Um zu demonstrieren, wie dieser Kurs verwendet wird, kann ich Daten aus einer Burnout-Studie in einem Versorgungsunternehmen verwenden. Michael Leiter und Kimberly Ann Meechan untersuchten die Beziehung zwischen einem Maß für Burnout, dem Erschöpfungsindex, und einer unabhängigen Variablen namens Konzentration. Unter Konzentration versteht man den Anteil der sozialen Kontakte eines Menschen, der aus seinem Arbeitsumfeld stammt.
Um die Beziehung zwischen Verbrauchsindexwerten und Konzentrationswerten für Personen in ihrer Stichprobe zu untersuchen, laden Sie diese Werte in ein entsprechend benanntes Array und instanziieren diese Klasse mit diesen Array-Werten. Zeigen Sie nach der Instanziierung einer Klasse einige von der Klasse generierte Zusammenfassungswerte an, um zu bewerten, wie gut das lineare Modell zu den Daten passt.
Listing 5 zeigt ein Skript, das Daten lädt und Zusammenfassungswerte anzeigt:
Listing 5. Skript, das Daten lädt und Zusammenfassungswerte anzeigt
<?php
// BurnoutStudy.php
// Copyright 2003, Paul Meagher
// Unter GPL vertrieben
include „SimpleLinearRegression.php“;
// Daten aus Burnout-Studie laden
$Concentration = array(20,60,38,88,79,87,
68,12,35,70,80,92,
77,86,83,79,75,81,
75,77,77,77,17,85,96);
$ExhaustionIndex = array(100.525.300.980.310.900,
410.296.120.501.920.810,
506.493.892.527.600.855,
709.791.718.684.141.400.970);
$slr = new SimpleLinearRegression($Concentration, $ExhaustionIndex);
$YInt = sprintf($slr->format, $slr->YInt);
$Slope = sprintf($slr->format, $slr->Slope);
$SlopeTVal = sprintf($slr->format, $slr->SlopeTVal);
$SlopeProb = sprintf("%01.6f", $slr->SlopeProb);
?>
<table border='1' cellpadding='5'>
<tr>
<th align='right'>Gleichung:</th>
<td></td>
</tr>
<tr>
<th align='right'>T:</th>
<td></td>
</tr>
<tr>
<th align='right'>Prob > T:</th>
<td><td>
</tr>
</table>
Das Ausführen dieses Skripts über einen Webbrowser erzeugt die folgende Ausgabe:
Gleichung: Erschöpfung = -29,50 + (8,87 * Konzentration)
T: 6.03
Prob > T: 0,000005
Die letzte Zeile dieser Tabelle zeigt an, dass die zufällige Wahrscheinlichkeit, einen so großen T-Wert zu erhalten, sehr gering ist. Daraus lässt sich schließen, dass ein einfaches lineares Modell eine bessere Vorhersagekraft hat als die einfache Verwendung des Mittelwerts der Verbrauchswerte.
Wenn man die Konzentration der Kontakte am Arbeitsplatz einer Person kennt, kann man vorhersagen, wie stark die Burnout-Erkrankung sein könnte. Diese Gleichung sagt uns: Mit jeder Erhöhung des Konzentrationswerts um 1 Einheit erhöht sich der Konsumwert einer Person im Bereich der sozialen Dienste um 8 Einheiten. Dies ist ein weiterer Beweis dafür, dass Menschen in sozialen Diensten darüber nachdenken sollten, Freunde außerhalb ihres Arbeitsplatzes zu finden, um einem potenziellen Burnout vorzubeugen.
Dies ist nur eine grobe Skizze dessen, was diese Ergebnisse bedeuten könnten. Um die Auswirkungen dieses Datensatzes vollständig zu untersuchen, möchten Sie die Daten möglicherweise genauer untersuchen, um sicherzustellen, dass es sich um die richtige Interpretation handelt. Im nächsten Artikel werde ich besprechen, welche weiteren Analysen durchgeführt werden sollten.
Was hast du gelernt?
Zum einen muss man kein Raketenwissenschaftler sein, um sinnvolle PHP-basierte Mathematikpakete zu entwickeln. Durch die Einhaltung standardmäßiger objektorientierter Techniken und die explizite Übernahme von Reverse-Chaining-Problemlösungsmethoden ist es relativ einfach, PHP zur Implementierung einiger grundlegenderer statistischer Prozesse zu verwenden.
Aus pädagogischer Sicht halte ich diese Übung für sehr nützlich, schon allein deshalb, weil Sie dabei über statistische Tests oder Routinen auf höheren und niedrigeren Abstraktionsebenen nachdenken müssen. Mit anderen Worten: Eine gute Möglichkeit, Ihre statistischen Tests oder Ihr prozedurales Lernen zu ergänzen, besteht darin, das Verfahren als Algorithmus zu implementieren.
Die Implementierung statistischer Tests erfordert oft, über die bereitgestellten Informationen hinauszugehen und kreative Probleme zu lösen und zu entdecken. Es ist auch eine gute Möglichkeit, Wissenslücken zu einem Thema aufzudecken.
Der Nachteil besteht darin, dass es PHP an inhärenten Mitteln zum Sampling von Verteilungen mangelt, was für die Implementierung der meisten statistischen Tests erforderlich ist. Sie müssen R die Verarbeitung überlassen, um diese Werte zu erhalten, aber ich fürchte, Sie haben weder die Zeit noch das Interesse, R zu installieren. Native PHP-Implementierungen einiger gängiger Wahrscheinlichkeitsfunktionen können dieses Problem lösen.
Ein weiteres Problem: Die Klasse generiert viele Zwischen- und Zusammenfassungswerte, die Zusammenfassungsausgabe nutzt dies jedoch nicht wirklich aus. Ich habe einige unhandliche Ausgaben bereitgestellt, die jedoch weder ausreichend noch gut organisiert sind, sodass Sie die Ergebnisse der Analyse angemessen interpretieren können. Eigentlich habe ich überhaupt keine Ahnung, wie ich die Ausgabemethode in diese Klasse integrieren kann. Dies muss angegangen werden.
Um die Daten zu verstehen, ist schließlich mehr erforderlich, als nur die zusammenfassenden Werte zu betrachten. Sie müssen auch verstehen, wie einzelne Datenpunkte verteilt sind. Eine der besten Möglichkeiten, dies zu tun, besteht darin, Ihre Daten grafisch darzustellen. Auch hier weiß ich nicht viel darüber, aber wenn Sie diese Klasse zur Analyse realer Daten verwenden möchten, müssen Sie dieses Problem lösen.