最小二乘法原理与Python实现:从数学推导到房价预测
1. 最小二乘法概述:从散点图到最佳拟合直线
最小二乘法(Least Squares Method)是统计学和数据分析中最基础也最实用的曲线拟合技术之一。这个方法的核心思想很简单:找到一条直线,使得所有数据点到这条直线的垂直距离(即残差)的平方和最小。我第一次接触这个概念是在处理一组实验数据时,当时需要从30多个温度传感器的读数中找出温度随时间变化的规律。
为什么是"平方"和而不是简单的绝对值之和?这里有两个关键原因:一是平方运算能放大较大误差的影响,使拟合结果对异常值更敏感;二是平方函数处处可导,便于数学处理。在实际应用中,我们通常用y = kx + b表示拟合直线,其中k是斜率,b是截距。
重要提示:最小二乘法假设误差仅存在于因变量(y)方向,自变量(x)被视为精确值。如果x也存在显著误差,需要考虑更复杂的总体最小二乘法(TLS)。
2. 数学推导:手把手推导演算全过程
2.1 建立误差函数
假设有n个数据点(x₁,y₁), (x₂,y₂), ..., (xₙ,yₙ),拟合直线为ŷ = kx + b。每个点的残差为eᵢ = yᵢ - ŷᵢ = yᵢ - (kxᵢ + b)。误差平方和函数为:
S = Σ(eᵢ)² = Σ[yᵢ - (kxᵢ + b)]²
我们的目标是找到k和b使得S最小。这需要分别对k和b求偏导并令其等于零。
2.2 求偏导方程组
对b求偏导: ∂S/∂b = -2Σ[yᵢ - (kxᵢ + b)] = 0
=> Σyᵢ = kΣxᵢ + nb ...(1)
对k求偏导: ∂S/∂k = -2Σxᵢ[yᵢ - (kxᵢ + b)] = 0
=> Σxᵢyᵢ = kΣxᵢ² + bΣxᵢ ...(2)
2.3 解正规方程
将(1)(2)整理为矩阵形式: [n Σxᵢ ][b] [Σyᵢ ] [Σxᵢ Σxᵢ²][k] = [Σxᵢyᵢ]
解这个方程组得到: k = (nΣxᵢyᵢ - ΣxᵢΣyᵢ)/(nΣxᵢ² - (Σxᵢ)²) b = (Σyᵢ - kΣxᵢ)/n
计算技巧:先计算k再求b,可以避免重复计算中间项。建议先算出Σxᵢ、Σyᵢ、Σxᵢyᵢ、Σxᵢ²这四个基本量。
3. 实际应用案例:房价与面积的关系分析
3.1 数据准备
假设我们有以下房屋数据(单位:面积㎡/价格万元):
| 面积(x) | 价格(y) |
|---|---|
| 80 | 320 |
| 95 | 380 |
| 110 | 420 |
| 125 | 480 |
| 140 | 530 |
3.2 计算中间量
n = 5
Σx = 80+95+110+125+140 = 550
Σy = 320+380+420+480+530 = 2130
Σxy = 80×320 + 95×380 + ... + 140×530 = 241900
Σx² = 80² + 95² + ... + 140² = 62750
3.3 代入公式计算
k = (5×241900 - 550×2130)/(5×62750 - 550²) ≈ 3.23
b = (2130 - 3.23×550)/5 ≈ 63.7
得到回归方程:ŷ = 3.23x + 63.7
3.4 结果解读
斜率3.23表示每增加1平方米,房价预计上涨3.23万元;截距63.7可以理解为固定成本或基础价格。当x=100㎡时,预测价格ŷ=3.23×100+63.7=386.7万元。
4. 编程实现:Python代码实战
4.1 基础实现
import numpy as np
def least_squares(x, y):
n = len(x)
sum_x = sum(x)
sum_y = sum(y)
sum_xy = sum(xi*yi for xi,yi in zip(x,y))
sum_x2 = sum(xi**2 for xi in x)
k = (n*sum_xy - sum_x*sum_y) / (n*sum_x2 - sum_x**2)
b = (sum_y - k*sum_x) / n
return k, b
# 使用示例
x = [80, 95, 110, 125, 140]
y = [320, 380, 420, 480, 530]
slope, intercept = least_squares(x, y)
print(f"回归方程: y = {slope:.2f}x + {intercept:.2f}")
4.2 使用NumPy优化
def least_squares_np(x, y):
A = np.vstack([x, np.ones(len(x))]).T
k, b = np.linalg.lstsq(A, y, rcond=None)[0]
return k, b
4.3 可视化展示
import matplotlib.pyplot as plt
plt.scatter(x, y, color='blue', label='实际数据')
plt.plot(x, [slope*xi + intercept for xi in x], 'r-', label='拟合直线')
plt.xlabel('面积(㎡)')
plt.ylabel('价格(万元)')
plt.legend()
plt.show()
5. 常见问题与解决方案
5.1 数据标准化问题
当x值范围很大时(如x∈[1000,100000]),直接计算可能导致数值不稳定。解决方案:
- 对x进行标准化:x' = (x - μ)/σ
- 或改用梯度下降法迭代求解
5.2 异常值处理
最小二乘法对异常值敏感。当数据中存在明显离群点时:
- 可视化检查散点图
- 使用MAD(中位数绝对偏差)识别异常值
- 考虑改用稳健回归方法(如RANSAC)
5.3 评估拟合质量
常用评估指标:
- R²(决定系数):越接近1说明拟合越好 R² = 1 - Σ(yᵢ-ŷᵢ)²/Σ(yᵢ-ȳ)²
- 均方根误差(RMSE): RMSE = √[Σ(yᵢ-ŷᵢ)²/n]
5.4 非线性关系处理
当数据明显呈现曲线趋势时:
- 变量替换:如对x取对数
- 多项式回归:y = b + k₁x + k₂x² + ...
- 分段线性回归
6. 高级话题:矩阵视角下的最小二乘
对于多元线性回归y = β₀ + β₁x₁ + ... + βₖxₖ,可以用矩阵形式表示:
Y = Xβ + ε
解为:β = (XᵀX)⁻¹XᵀY
其中X是设计矩阵,第一列为1(对应截距项)。这个形式可以统一处理单变量和多变量情况。
数值稳定性提示:实际计算中应避免直接求逆,推荐使用QR分解或SVD等数值稳定算法。在Python中,np.linalg.lstsq已经实现了这些优化。
7. 工程实践中的注意事项
-
数据量较大时 :使用随机梯度下降(SGD)或小批量梯度下降,避免一次性加载所有数据
-
稀疏数据 :考虑使用Lasso回归(L1正则化)自动进行特征选择
-
共线性问题 :当自变量高度相关时,加入岭回归(L2正则化)稳定解
-
实时更新 :对于流式数据,可以使用递归最小二乘法(RLS)在线更新参数
-
内存优化 :对于超大规模数据,可以分块计算并合并结果:
- 分别计算各块的Σx, Σy, Σxy, Σx²
- 合并时简单相加这些统计量
- 最后统一计算k和b
更多推荐

所有评论(0)