簡單線性回歸是統計建模基礎,目標是從二維資料點 (X, Y) 中找到最佳擬合直線 y = mx + b。本文涵蓋核心數學、統計檢定、機率函數實作、圖表視覺化與完整資料探勘腳本。
尋找斜率 m 與截距 b,使殘差平方和 (RSS) 最小化:
RSS = Σ(yi - (m·xi + b))²
解析解公式:
m = Σ((xi - x̄)(yi - ȳ)) / Σ((xi - x̄)²)
b = ȳ - m·x̄
計算 T 統計量判斷斜率是否顯著非零:
t = m / SE(m)
若 T 值大且 p-value 低(通常 < 0.05),拒絕虛無假設,認為線性模型顯著優於單純使用平均值預測。
<?php
class SimpleLinearRegression {
private $X, $Y;
private $slope, $intercept;
public function __construct(array $X, array $Y) {
$this->X = $X;
$this->Y = $Y;
$this->calculate();
}
private function calculate() {
$n = count($this->X);
$sumX = array_sum($this->X);
$sumY = array_sum($this->Y);
$sumXY = 0;
$sumX2 = 0;
for ($i = 0; $i < $n; $i++) {
$sumXY += $this->X[$i] * $this->Y[$i];
$sumX2 += $this->X[$i] ** 2;
}
$xMean = $sumX / $n;
$yMean = $sumY / $n;
$this->slope = ($sumXY - $n * $xMean * $yMean) / ($sumX2 - $n * $xMean ** 2);
$this->intercept = $yMean - $this->slope * $xMean;
}
public function getSlope() { return $this->slope; }
public function getIntercept() { return $this->intercept; }
public function predict($x) { return $this->slope * $x + $this->intercept; }
// 更多統計方法:getRSquared(), getTStatistic(), getPValue() 等
}
?>
移植自 John Pezzullo 的 JavaScript 實作,封裝於 Distribution 類別:
<?php
class Distribution {
// 共用數學計算
private function doCommonMath($q, $i, $j, $b) {
$zz = $z = 1;
for ($k = $i; $k <= $j; $k += 2) {
$zz = $zz * $q * $k / ($k - $b);
$z += $zz;
}
return $z;
}
// T 分布累積機率
public function getStudentT($t, $df) {
$t = abs($t);
$w = $t / sqrt($df);
$th = atan($w);
if ($df == 1) return 1 - $th / (M_PI / 2);
$sth = sin($th); $cth = cos($th);
if ($df % 2 == 1) {
return 1 - ($th + $sth * $cth * $this->doCommonMath($cth*$cth, 2, $df-3, -1)) / (M_PI/2);
} else {
return 1 - $sth * $this->doCommonMath($cth*$cth, 1, $df-3, -1);
}
}
// 反 T 分布(臨界值)
public function getInverseStudentT($p, $df) {
$v = $dv = 0.5; $t = 0;
while ($dv > 1e-6) {
$t = (1/$v) - 1; $dv /= 2;
if ($this->getStudentT($t, $df) > $p) $v -= $dv;
else $v += $dv;
}
return $t;
}
}
?>
使用 JpGraph 繪製散佈圖與回歸線:
<?php
require_once 'jpgraph/jpgraph.php';
require_once 'jpgraph/jpgraph_scatter.php';
require_once 'jpgraph/jpgraph_line.php';
$graph = new Graph(600, 400);
$graph->SetScale('linlin');
$graph->title->Set('線性回歸分析');
$graph->xaxis->SetTitle('X 軸');
$graph->yaxis->SetTitle('Y 軸');
// 散佈點
$sp = new ScatterPlot($slr->getY(), $slr->getX());
$sp->mark->SetType(MARK_FILLEDCIRCLE);
$sp->mark->SetFillColor('red');
$sp->SetColor('blue');
// 回歸線
$predY = array_map([$slr, 'predict'], $slr->getX());
$line = new LinePlot($predY, $slr->getX());
$line->SetColor('navy');
$line->SetWeight(2);
$graph->Add($sp);
$graph->Add($line);
$graph->Stroke('regression.png');
?>
<img src="regression.png" alt="回歸分析圖">
<?php
// 接收表單資料:X值、Y值、標題、信心區間等
if (isset($_POST['x_values'], $_POST['y_values'])) {
$X = explode(',', $_POST['x_values']);
$Y = explode(',', $_POST['y_values']);
if (count($X) === count($Y)) {
require_once 'SimpleLinearRegressionHTML.php';
$slr = new SimpleLinearRegressionHTML($X, $Y, $_POST['conf_int']);
echo "<h2>{$_POST['title']}</h2>";
$slr->showTableSummary($_POST['x_name'], $_POST['y_name']);
$slr->showAnalysisOfVariance();
$slr->showParameterEstimates($_POST['x_name'], $_POST['y_name']);
$slr->showFormula($_POST['x_name'], $_POST['y_name']);
$slr->showRValues($_POST['x_name'], $_POST['y_name']);
// 繪圖程式碼...
}
} else {
// 顯示輸入表單
}
?>
PHP 雖非統計分析主流語言,但透過完善的數學函數庫與圖表工具,完全能構建實用的線性回歸分析工具,適合中小型資料集的快速探勘與決策支援。