はじめ
に Perl や Python などの他のオープンソース言語と比較して、PHP コミュニティは数学ライブラリを開発するための強力な努力が不足しています。
その理由の 1 つは、すでに多数の成熟した数学ツールが存在しており、コミュニティが独自に PHP ツールを開発する取り組みを妨げている可能性があることです。たとえば、私は S System という強力なツールに取り組みました。このツールには印象的な統計ライブラリのセットがあり、データ セットを分析するために特別に設計されており、その言語設計で 1998 年に ACM 賞を受賞しました。 S またはそのオープンソースの R が単なる exec_shell 呼び出しである場合、なぜわざわざ同じ統計計算機能を PHP に実装するのでしょうか? S システム、その ACM Award、または R の詳細については、関連参考資料を参照してください。
これは開発者のエネルギーの無駄ではないでしょうか? PHP 数学ライブラリを開発する動機が、開発者の労力を節約し、その仕事に最適なツールを使用することである場合、PHP の現在のトピックは理にかなっています。
一方で、教育的な動機によって PHP 数学ライブラリの開発が促進される可能性があります。約 10% の人にとって、数学は研究する価値のある興味深い主題です。 PHP にも習熟している人にとって、PHP 数学ライブラリの開発は数学の学習プロセスを強化することができます。言い換えれば、T テストに関する章を読むだけでなく、対応する中間結果を計算できるプログラムを実装することもできます。値を取得し、それらを標準形式で表示します。
ガイダンスとトレーニングを通じて、PHP 数学ライブラリの開発は難しい作業ではなく、技術的および学習上の興味深い課題となる可能性があることを実証したいと考えています。この記事では、PHP 数学ライブラリの開発に使用できる一般的なアプローチを示す、SimpleLinearRegression と呼ばれる PHP 数学ライブラリの例を紹介します。まずは、SimpleLinearRegression クラスの開発の指針となったいくつかの一般原則について説明します。
指導原則
SimpleLinearRegression クラスの開発の指針として 6 つの一般原則を使用しました。
解析モデルごとにクラスを作成します。
逆リンクを使用してクラスを開発します。
多数のゲッターが期待されます。
中間結果を保存します。
詳細な API の設定を行います。
完璧は目標ではありません。
これらの各ガイドラインをさらに詳しく見てみましょう。
各分析モデルのクラスを作成します。
各主要な分析テストまたはプロセスには、テストまたはプロセスと同じ名前の PHP クラスが必要です。このクラスには、入力関数、中間値と集計値を計算するための関数、および出力関数が含まれます。中間値を置き換えます)。値と要約値はすべてテキストまたはグラフィック形式で画面に表示されます。
リバース チェーンを使用したクラス開発
数学的プログラミングでは、通常、コーディング ターゲットは、分析手順 (MultipleRegression、TimeSeries、または ChiSquared など) が生成する標準出力値です。問題解決の観点から見ると、これは、逆方向連鎖を使用して数学的な手法を開発できることを意味します。
たとえば、概要出力画面には、1 つ以上の概要統計の結果が表示されます。これらの要約統計結果は中間統計結果の計算に依存しており、これらの中間統計結果にはさらに深い中間統計結果などが含まれる場合があります。このバックリンクベースの開発アプローチは、次の原則につながります。
大量のゲッター
数学クラスが予想されます。クラス開発作業のほとんどには、中間値と要約値の計算が含まれます。実際には、これは、クラスに中間値と要約値を計算するゲッター メソッドが多数含まれていても驚かないことを意味します。
中間結果の保存
中間計算の結果を結果オブジェクト内に保存して、中間結果を後続の計算の入力として使用できるようにします。この原則は S 言語設計に実装されています。現在のコンテキストでは、この原則は、計算された中間値と要約結果を表すインスタンス変数を選択することによって実装されます。
詳細な API の環境設定を行う
SimpleLinearRegression クラスのメンバー関数とインスタンス変数の命名スキームを開発するときに、メンバー関数とインスタンス変数を記述するために長い名前 ( getYY2 の代わりに getSumSquaredError など) を使用すると、関数の演算内容や変数の意味が分かりやすくなります。
私は略称を完全に放棄したわけではありませんが、名前の短縮形を使用する場合は、その名前の意味を十分に説明する注記を提供するように努めなければなりません。私の見解は次のとおりです。高度に省略された命名スキームは数学的プログラミングでは一般的ですが、特定の数学的ルーチンを理解し、正しいことを証明することが必要以上に困難になります。
完璧は目標ではない
このコーディング演習の目標は、必ずしも PHP 用に高度に最適化された厳密な数学エンジンを開発することではありません。初期段階では、有意義な分析テストの実装方法を学び、この分野の困難な問題を解決することに重点を置く必要があります。
インスタンス変数
統計テストまたはプロセスをモデル化する場合、どのインスタンス変数が宣言されているかを示す必要があります。
インスタンス変数の選択は、分析プロセスによって生成された中間値と要約値を考慮して決定できます。各中間値と要約値は、変数の値をオブジェクト プロパティとして持つ、対応するインスタンス変数を持つことができます。
この分析を使用して、リスト 1 の SimpleLinearRegression クラスに対してどの変数を宣言するかを決定しました。同様の分析は、MultipleRegression、ANOVA、または TimeSeries プロシージャでも実行できます。
リスト 1. SimpleLinearRegression クラスのインスタンス変数
<?php
// 著作権 2003、Paul Meagher
// GPL に基づいて配布されます
クラス SimpleLinearRegression {
変数$n;
var $X = 配列();
var $Y = 配列();
var $ConfInt;
var $Alpha;
var $XMean;
var $YMean;
var $SumXX;
var $SumXY;
var $SumYY;
var $Slope;
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 値;
var $YIntStdErr;
var $YIntTVal // Y 切片の T 値
変数$R;
var $RSquared;
var $DF; // 自由度
var $SlopeProb; // 傾斜推定の確率
var $YIntProb; // Y 切片の推定確率
var $AlphaTVal; // 指定されたアルファ設定の T 値
var $ConfIntOfSlope;
var $RPath = "/usr/local/bin/R" // ここにパスを入力します。
var $format = "%01.2f"; // 出力のフォーマットに使用されます。
}
?>
コンストラクター
SimpleLinearRegression クラスのコンストラクター メソッドは、それぞれ同じ数の値を持つ X ベクトルと Y ベクトルを受け入れます。予想される Y 値のデフォルトの 95% 信頼区間を設定することもできます。
コンストラクター メソッドは、データ形式が処理に適しているかどうかを検証することから始まります。入力ベクトルが「等しいサイズ」テストと「1 より大きい値」テストに合格すると、アルゴリズムのコア部分が実行されます。
このタスクの実行には、一連のゲッター メソッドによる統計プロセスの中間値と要約値の計算が含まれます。各メソッド呼び出しの戻り値をクラスのインスタンス変数に代入します。この方法で計算結果を保存すると、連鎖計算の呼び出しルーチンで中間値と要約値を確実に利用できるようになります。リスト 2 で説明されているように、このクラスの出力メソッドを呼び出してこれらの結果を表示することもできます。
リスト 2. クラス出力メソッドの呼び出し
<?php
// 著作権 2003、Paul Meagher
// GPL に基づいて配布されます
function SimpleLinearRegression($X, $Y, $ConfidenceInterval="95") {
$numX = カウント($X);
$numY = カウント($Y);
if ($numX != $numY) {
die("エラー: X ベクトルと Y ベクトルのサイズは同じでなければなりません。");
}
if ($numX <= 1) {
die("エラー: 入力配列のサイズは少なくとも 2 である必要があります。");
}
$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();
true を返します。
}
?>
メソッド名とそのシーケンスは、バックリンクと、中間値の計算方法を段階的に説明する学部生が使用する統計学の教科書への参照を組み合わせて派生しました。計算する必要がある中間値の名前には「get」という接頭辞が付けられ、メソッド名が導出されます。
モデルをデータに適合させる
SimpleLinearRegression プロシージャを使用して、データに適合する直線を生成します。この直線には、次の標準方程式が含まれます:
y = b + mx
この方程式の PHP 形式は、リスト 3 に似ています
。モデルをデータに適合させる PHP 方程式のマッチング
$PredictedY[$i] = $YIntercept + $Slope * $X[$i]
SimpleLinearRegression クラスは、最小二乗基準を使用して、Y 切片 (Y Intercept) および傾き (Slope) パラメーターの推定値を導出します。これらの推定パラメータは、X 値と Y 値の間の関係をモデル化する線形方程式 (リスト 3 を参照) を構築するために使用されます。
導出された一次方程式を使用すると、各 X 値に対する予測 Y 値を取得できます。線形方程式がデータによく適合する場合、Y の観測値と予測値は一致する傾向があります。
適切な適合があるかどうかを判断する方法
SimpleLinearRegression クラスは、かなりの数の集計値を生成します。重要な要約値は、線形方程式がデータにどの程度適合するかを測定する T 統計です。一致が非常に良好な場合、T 統計量は大きくなる傾向があります。 T 統計量が小さい場合は、線形方程式を、Y 値の平均が最良の予測子であると仮定するモデルに置き換える必要があります (つまり、一連の値の平均は通常、有用な予測子です)次の観測の場合は、それをデフォルトのモデルにします)。
T 統計量が Y 値の平均を最良の予測因子として考慮しないほど十分に大きいかどうかをテストするには、T 統計量を取得するランダム確率を計算する必要があります。 T 統計を取得する確率が低い場合は、平均が最良の予測子であるという帰無仮説を棄却できるため、単純な線形モデルがデータによく適合すると確信できます。
では、T 統計値の確率を計算するにはどうすればよいでしょうか?
T 統計値の確率の計算
PHP には T 統計値の確率を計算するための数学的ルーチンがないため、このタスクを統計計算パッケージ R (「参考文献」のwww.r-project.org を参照) に任せることにしました。必要な値を取得します。また、このパッケージにも注目していただきたい理由は次のとおりです。
R は、PHP 開発者が PHP 数学ライブラリでエミュレートできる多くのアイデアを提供します。
R を使用すると、PHP 数学ライブラリから取得した値が、成熟した無料で利用できるオープンソース統計パッケージから取得した値と一致しているかどうかを判断できます。
リスト 4 のコードは、R に任せて値を取得することがいかに簡単であるかを示しています。
リスト 4. R 統計パッケージに処理して値を取得する
<?php
// 著作権 2003、Paul Meagher
// GPL に基づいて配布されます
クラス SimpleLinearRegression {
var $RPath = "/usr/local/bin/R" // ここにパスを入力します。
関数 getStudentProb($T, $df) {
$確率 = 0.0;
$cmd = "エコー 'dt($T, $df)' | $this->RPath --slave";
$result = シェル_exec($cmd);
list($LineNumber, $Probability) =explode(" ", trim($result));
$Probability を返します。
}
関数 getInverseStudentProb($alpha, $df) {
$InverseProbability = 0.0;
$cmd = "エコー 'qt($alpha, $df)' | $this->RPath --slave";
$result = シェル_exec($cmd);
list($LineNumber, $InverseProbability) =explode(" ", trim($result));
$InverseProbability を返します。
}
}
?>
R 実行可能ファイルへのパスが設定され、両方の関数で使用されていることに注意してください。最初の関数はスチューデントの T 分布に基づいて T 統計量に関連付けられた確率値を返し、2 番目の逆関数は指定されたアルファ設定に対応する T 統計量を計算します。 getStudentProb メソッドは線形モデルの適合性を評価するために使用され、getInverseStudentProb メソッドは中間値を返し、これを使用して各予測 Y 値の信頼区間を計算します。
スペースが限られているため、このクラスのすべての関数を 1 つずつ詳細に説明することは不可能です。そのため、単純な線形回帰分析に関連する用語と手順を理解したい場合は、使用されている統計の教科書を参照することをお勧めします。学部生による。
バーンアウト スタディ
このクラスの使用方法を示すために、ユーティリティでバーンアウト スタディのデータを使用できます。 Michael Leiter と Kimberly Ann Meechan は、疲労指数と呼ばれる燃え尽き症候群の尺度と集中力と呼ばれる独立変数の間の関係を研究しました。集中力とは、人々の職場環境から得られる社会的接触の割合を指します。
サンプル中の個人の消費指数値と濃度値の関係を調べるには、これらの値を適切な名前の配列にロードし、これらの配列値を使用してこのクラスをインスタンス化します。クラスをインスタンス化した後、クラスによって生成されたいくつかの要約値を表示して、線形モデルがデータにどの程度適合しているかを評価します。
リスト 5 は、データをロードし、集計値を表示するスクリプトを示しています。
リスト 5. データをロードし、集計値を表示するスクリプト
<?php
// バーンアウトスタディ.php
// 著作権 2003、Paul Meagher
// GPL に基づいて配布されます
「SimpleLinearRegression.php」をインクルードします。
// バーンアウト調査からデータをロードします
$濃度 = 配列(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 = 新しい 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'>式:</th>
<td></td>
</tr>
<tr>
<th align='right'>T:</th>
<td></td>
</tr>
<tr>
<th align='right'>確率 > T:</th>
<td><td>
</tr>
</テーブル>
Web ブラウザを通じてこのスクリプトを実行すると、次の出力が生成されます。
式: 疲労 = -29.50 + (8.87 * 集中)
T: 6.03
Prob > T: 0.000005
この表の最後の行は、このような大きな T 値を取得するランダムな確率が非常に低いことを示しています。単純な線形モデルは、単純に消費値の平均を使用するよりも優れた予測力を持っていると結論付けることができます。
誰かの職場におけるつながりの集中を知ることは、その人が消耗している可能性のある燃え尽き症候群のレベルを予測するために使用できます。この方程式は、集中値が 1 単位増加するごとに、社会サービス分野における人の消費価値が 8 単位増加することを示しています。これは、燃え尽き症候群の可能性を減らすために、社会奉仕活動に従事している人は職場の外で友人を作ることを検討すべきであるというさらなる証拠です。
これは、これらの結果が何を意味するのかについての大まかなスケッチにすぎません。このデータセットの意味を完全に調査するには、データをより詳細に調査して、これが正しい解釈であることを確認する必要があるかもしれません。次の記事では、他にどのような分析を実行する必要があるかについて説明します。
何を学びましたか?
まず、有意義な PHP ベースの数学パッケージを開発するのにロケット科学者である必要はありません。標準のオブジェクト指向技術を遵守し、リバース チェーンの問題解決手法を明示的に採用することにより、PHP を使用してより基本的な統計プロセスのいくつかを実装することが比較的簡単になります。
教えるという観点から見ると、この演習は、より高い抽象レベルとより低い抽象レベルで統計テストやルーチンについて考える必要があるという理由だけで、非常に役立つと思います。言い換えれば、統計テストや手続き型学習を補うための優れた方法は、手続きをアルゴリズムとして実装することです。
統計テストを実装するには、多くの場合、与えられた情報を超えて、創造的な問題解決と発見が必要になります。また、主題に関する知識のギャップを発見する良い方法です。
欠点としては、PHP には、ほとんどの統計テストの実装に必要なサンプリング分布のための固有の手段が欠けていることがわかります。これらの値を取得するには R に処理を行わせる必要がありますが、残念ながら R をインストールする時間や関心はありません。いくつかの一般的な確率関数のネイティブ PHP 実装は、この問題を解決できます。
もう 1 つの問題: このクラスは多くの中間値と要約値を生成しますが、要約出力は実際にはこれを利用しません。扱いにくい出力をいくつか提供しましたが、分析結果を適切に解釈できるほど十分ではなく、十分に整理されていません。実際のところ、出力メソッドをこのクラスに統合する方法がまったくわかりません。これに対処する必要があります。
最後に、データを理解するには、単に要約値を確認するだけでは不十分です。また、個々のデータ ポイントがどのように分散されるかを理解する必要があります。これを行うための最良の方法の 1 つは、データをグラフ化することです。繰り返しになりますが、これについてはあまり知りませんが、このクラスを使用して実際のデータを分析したい場合は、この問題を解決する必要があります。