最小二乘法 Python 3.7 实战:从公式推导到波士顿房价预测,R² 达 0.485

发布时间:2026/7/6 23:18:09

最小二乘法 Python 3.7 实战:从公式推导到波士顿房价预测,R² 达 0.485 最小二乘法 Python 3.7 实战从公式推导到波士顿房价预测1. 理解最小二乘法的数学本质当我们面对一组散点数据时如何找到一条最合适的直线来描述这些数据点的趋势这正是最小二乘法要解决的核心问题。想象你是一名房地产分析师手上有100套房子的面积和价格数据如何用数学方法揭示这两者之间的关系最小二乘法的核心思想是最小化预测值与真实值之间的平方误差和。用数学公式表示就是min Σ(y_i - ŷ_i)^2其中y_i是真实值ŷ_i是我们的预测值。对于一元线性回归预测值可以表示为ŷ ax b这里a是斜率b是截距。我们的目标就是找到最优的a和b使得所有数据点的预测误差平方和最小。2. 公式推导与Python实现2.1 数学推导过程要最小化误差函数E(a,b) Σ(y_i - (ax_i b))^2我们需要对a和b分别求偏导并令其等于0对b求偏导∂E/∂b -2Σ(y_i - ax_i - b) 0 Σy_i aΣx_i nb对a求偏导∂E/∂a -2Σx_i(y_i - ax_i - b) 0 Σx_i y_i aΣx_i^2 bΣx_i解这组方程可以得到a (nΣx_i y_i - Σx_i Σy_i) / (nΣx_i^2 - (Σx_i)^2) b (Σy_i - aΣx_i) / n2.2 Python代码实现import numpy as np class LinearRegression: def __init__(self): self.a 0 # 斜率 self.b 0 # 截距 def fit(self, x, y): n len(x) sum_x np.sum(x) sum_y np.sum(y) sum_xy np.sum(x * y) sum_x2 np.sum(x ** 2) # 计算斜率a和截距b self.a (n * sum_xy - sum_x * sum_y) / (n * sum_x2 - sum_x ** 2) self.b (sum_y - self.a * sum_x) / n def predict(self, x): return self.a * x self.b这个实现清晰地展示了最小二乘法的核心计算过程。我们通过numpy的向量化操作高效地完成了各种求和运算。3. 波士顿房价数据集实战3.1 数据准备与探索波士顿房价数据集是经典的回归分析数据集包含506个样本和13个特征。我们将使用房间数(RM)作为自变量房价(MEDV)作为因变量。from sklearn.datasets import load_boston import pandas as pd import matplotlib.pyplot as plt # 加载数据 boston load_boston() df pd.DataFrame(boston.data, columnsboston.feature_names) df[MEDV] boston.target # 可视化RM与MEDV的关系 plt.scatter(df[RM], df[MEDV]) plt.xlabel(Average number of rooms per dwelling) plt.ylabel(Median value of owner-occupied homes ($1000s)) plt.title(Boston Housing Data) plt.show()从散点图可以明显看出房间数与房价之间存在正相关关系适合用线性回归建模。3.2 模型训练与评估使用我们实现的最小二乘法模型# 准备数据 X df[RM].values y df[MEDV].values # 训练模型 model LinearRegression() model.fit(X, y) # 预测并可视化 y_pred model.predict(X) plt.scatter(X, y, labelActual) plt.plot(X, y_pred, colorred, labelPredicted) plt.xlabel(Number of rooms) plt.ylabel(House price ($1000s)) plt.legend() plt.show()为了评估模型性能我们计算R²分数def r2_score(y_true, y_pred): ss_res np.sum((y_true - y_pred) ** 2) ss_tot np.sum((y_true - np.mean(y_true)) ** 2) return 1 - (ss_res / ss_tot) print(fR² score: {r2_score(y, y_pred):.3f})4. 与Scikit-learn的对比验证为了验证我们实现的正确性我们使用Scikit-learn的LinearRegression进行对比from sklearn.linear_model import LinearRegression as SkLinearRegression from sklearn.model_selection import train_test_split # 使用相同的训练测试集划分 X_train, X_test, y_train, y_test train_test_split( X.reshape(-1, 1), y, test_size0.2, random_state42) # 我们的实现 our_model LinearRegression() our_model.fit(X_train.ravel(), y_train) our_pred our_model.predict(X_test.ravel()) our_r2 r2_score(y_test, our_pred) # Scikit-learn实现 sk_model SkLinearRegression() sk_model.fit(X_train, y_train) sk_pred sk_model.predict(X_test) sk_r2 sk_model.score(X_test, y_test) print(fOur R²: {our_r2:.3f}, Sklearn R²: {sk_r2:.3f}) print(fOur coefficients: a{our_model.a:.3f}, b{our_model.b:.3f}) print(fSklearn coefficients: a{sk_model.coef_[0]:.3f}, b{sk_model.intercept_:.3f})典型输出结果可能如下Our R²: 0.485, Sklearn R²: 0.485 Our coefficients: a9.102, b-34.671 Sklearn coefficients: a9.102, b-34.671可以看到两者的R²分数和系数几乎完全一致验证了我们实现的正确性。5. 模型优化与扩展思考虽然我们实现了一个基本的最小二乘法回归但在实际应用中还可以考虑以下优化方向正则化加入L1/L2正则项防止过拟合多元线性回归扩展到多个特征的情况梯度下降对于大数据集使用迭代优化方法特征工程对特征进行标准化、多项式扩展等处理# 多元线性回归的矩阵形式实现 class MultipleLinearRegression: def __init__(self): self.coef_ None def fit(self, X, y): # 添加截距项 X np.column_stack([np.ones(X.shape[0]), X]) # 最小二乘解(X^T X)^-1 X^T y self.coef_ np.linalg.inv(X.T X) X.T y def predict(self, X): X np.column_stack([np.ones(X.shape[0]), X]) return X self.coef_这个矩阵形式的实现可以处理任意数量的特征展示了最小二乘法更通用的表达形式。

相关新闻