Python 一元线性回归实战:从数学推导到 3 行代码实现最小二乘法
在数据科学和机器学习领域,线性回归是最基础且广泛应用的算法之一。它不仅是理解更复杂模型的基石,也是许多实际业务场景中的首选工具。本文将带你深入一元线性回归的数学本质,从最小二乘法的原理推导开始,最终用 Python 实现一个仅需 3 行核心代码的线性回归类。
1. 一元线性回归的数学基础
一元线性回归描述的是单个自变量(x)和因变量(y)之间的线性关系,其基本形式为:
y = ax + b
其中:
- a 是斜率(回归系数)
- b 是截距
- ε 是误差项
最小二乘法的核心思想是通过最小化预测值与实际值之间的残差平方和来求解最优参数。具体来说,我们需要找到 a 和 b 使得以下损失函数最小化:
L(a,b) = Σ(y_i - (a*x_i + b))²通过对损失函数分别关于 a 和 b 求偏导并令导数为零,我们可以得到闭式解(closed-form solution):
a = Σ(x_i - x̄)(y_i - ȳ) / Σ(x_i - x̄)² b = ȳ - a*x̄其中 x̄ 和 ȳ 分别是 x 和 y 的样本均值。
提示:这个解被称为"正规方程",它直接给出了参数的最优解,而不需要迭代优化。
2. 手动实现最小二乘法
理解了数学原理后,我们可以用 NumPy 来实现这个计算过程。以下是完整的实现步骤:
import numpy as np class SimpleLinearRegression: def __init__(self): self.a = None # 斜率 self.b = None # 截距 def fit(self, X, y): # 计算均值 x_mean = np.mean(X) y_mean = np.mean(y) # 计算分子和分母 numerator = np.sum((X - x_mean) * (y - y_mean)) denominator = np.sum((X - x_mean) ** 2) # 计算斜率和截距 self.a = numerator / denominator self.b = y_mean - self.a * x_mean def predict(self, X): return self.a * X + self.b这个实现虽然简单,但完整包含了最小二乘法的核心逻辑。让我们分解一下关键部分:
fit方法:
- 计算 x 和 y 的均值
- 计算协方差(分子)和方差(分母)
- 根据公式求解 a 和 b
predict方法:
- 使用学得的参数进行预测
3. 三行代码的极简实现
如果追求极简,我们可以将核心计算浓缩为 3 行代码:
class TinyLinearRegression: def fit(self, X, y): self.a = np.cov(X, y, bias=True)[0,1] / np.var(X) self.b = np.mean(y) - self.a * np.mean(X) def predict(self, X): return self.a * X + self.b这个版本利用了 NumPy 的协方差函数np.cov和方差函数np.var,进一步简化了计算。虽然代码行数减少了,但数学本质完全相同。
4. 模型评估与应用
实现模型后,我们需要评估其性能。常用的评估指标包括:
| 指标 | 公式 | 解释 |
|---|---|---|
| R²得分 | 1 - (Σ(y_i - ŷ_i)²)/(Σ(y_i - ȳ)²) | 解释方差的比例,越接近1越好 |
| MSE | Σ(y_i - ŷ_i)²/n | 均方误差,越小越好 |
| MAE | Σ | y_i - ŷ_i |
以下是评估代码示例:
def evaluate(y_true, y_pred): # 计算R² ss_res = np.sum((y_true - y_pred) ** 2) ss_tot = np.sum((y_true - np.mean(y_true)) ** 2) r2 = 1 - (ss_res / ss_tot) # 计算MSE和MAE mse = np.mean((y_true - y_pred) ** 2) mae = np.mean(np.abs(y_true - y_pred)) return {'R²': r2, 'MSE': mse, 'MAE': mae}5. 实际应用示例
让我们用一个实际例子演示如何使用这个模型。假设我们有以下工龄与薪资的数据:
# 示例数据 X = np.array([1, 2, 3, 4, 5]) # 工龄(年) y = np.array([30000, 35000, 48000, 40000, 55000]) # 薪资(元) # 创建并训练模型 model = TinyLinearRegression() model.fit(X, y) # 预测 new_X = np.array([6, 7]) # 预测6年和7年工龄的薪资 predictions = model.predict(new_X) # 评估 train_pred = model.predict(X) metrics = evaluate(y, train_pred)在这个例子中,模型会学习工龄与薪资之间的线性关系,并可以预测新工龄对应的薪资水平。通过评估指标,我们可以了解模型的拟合质量。
注意:在实际应用中,数据预处理(如归一化、处理异常值等)和更复杂的模型评估(如交叉验证)通常也是必要的步骤。
理解一元线性回归的数学原理和实现方式,不仅有助于我们更好地应用这个基础模型,也为理解更复杂的机器学习算法奠定了坚实基础。当遇到更复杂的问题时,这种从基本原理出发的思考方式往往能带来更深入的理解和更灵活的解决方案。