【高等数学笔记】彻底弄懂最小二乘法(Least Squares Method)

这篇博客介绍了最小二乘法在拟合一元线性函数时的作用,通过数学推导展示了如何找到使得偏差平方和最小的参数值。以一次函数为例,详细阐述了计算过程,并提供了Python代码实现,实现了从数据点中求解最佳拟合直线的斜率和截距。最后,讨论了算法的时间复杂度为线性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

假设我们要拟合一个一元函数,目前我们知道的自变量及因变量的值是 ( x 1 , y 1 ) , ( x 2 , y 2 ) , ⋯   , ( x n , y n ) (x_1,y_1),(x_2,y_2),\cdots,(x_n,y_n) (x1,y1),(x2,y2),,(xn,yn),而我们要求 y = f ( x ) y=f(x) y=f(x),使得用它作为近似函数时,函数值与真实值的偏差 r i = f ( x i ) − y i r_i=f(x_i)-y_i ri=f(xi)yi的平方和 ∑ i = 1 n r i 2 = ∑ i = 1 n ( f ( x i ) − y i ) 2 \sum\limits_{i=1}^nr_i^2=\sum\limits_{i=1}^n(f(x_i)-y_i)^2 i=1nri2=i=1n(f(xi)yi)2最小。

假如我们已经选定了一类函数(模型)去拟合,现在要确定其中参数的值。比如我们选择了 f ( x ) = e a x + b f(x)=e^{ax+b} f(x)=eax+b这种模型(一般用于拟合人口增长),就要确定参数 a , b a,b a,b的值。设参数为 a 1 , a 2 , ⋯   , a m a_1,a_2,\cdots,a_m a1,a2,,am,将 f f f表示为 f ( x , a 1 , a 2 , ⋯   , a m ) f(x,a_1,a_2,\cdots,a_m) f(x,a1,a2,,am)。损失函数,即偏差的平方和为 Q ( a 1 , a 2 , ⋯   , a m ) = ∑ i = 1 n ( f ( x i , a 1 , a 2 , ⋯   , a m ) − y i ) 2 Q(a_1,a_2,\cdots,a_m)=\sum\limits_{i=1}^n(f(x_i,a_1,a_2,\cdots,a_m)-y_i)^2 Q(a1,a2,,am)=i=1n(f(xi,a1,a2,,am)yi)2。注意,这里 Q Q Q是参数 a 1 , a 2 , ⋯   , a m a_1,a_2,\cdots,a_m a1,a2,,am的函数,而不是 x , y x,y x,y的函数。让 Q Q Q取得极值,就需要让 Q Q Q a 1 , a 2 , ⋯   , a m a_1,a_2,\cdots,a_m a1,a2,,am的偏导数都为 0 0 0。对于参数 a k a_k ak Q Q Q对它的偏导数为 ∂ Q ∂ a k = 2 ∑ i = 1 n [ ( f ( x i , a 1 , a 2 , ⋯   , a m ) − y i ) ∂ f ∂ a k ∣ x i ] \frac{\partial Q}{\partial a_k}=2\sum\limits_{i=1}^n\left[\left(f(x_i,a_1,a_2,\cdots,a_m)-y_i\right)\left.\frac{\partial f}{\partial a_k}\right|_{x_i}\right] akQ=2i=1n[(f(xi,a1,a2,,am)yi)akfxi]让它等于 0 0 0,就是要使得 ∀ k = 1 , 2 , ⋯   , m , ∑ i = 1 n [ ( f ( x i , a 1 , a 2 , ⋯   , a m ) − y i ) ∂ f ∂ a k ∣ x i ] = 0 \forall k=1,2,\cdots,m,\\\sum\limits_{i=1}^n\left[\left(f(x_i,a_1,a_2,\cdots,a_m)-y_i\right)\left.\frac{\partial f}{\partial a_k}\right|_{x_i}\right]=0 k=1,2,,m,i=1n[(f(xi,a1,a2,,am)yi)akfxi]=0


下面以一次函数拟合为例。设 f ( x ) = a x + b f(x)=ax+b f(x)=ax+b,要通过已知的数据点 ( x 1 , y 1 ) , ( x 2 , y 2 ) , ⋯   , ( x n , y n ) (x_1,y_1),(x_2,y_2),\cdots,(x_n,y_n) (x1,y1),(x2,y2),,(xn,yn)来确定参数 a , b a,b a,b的值。损失函数 Q ( a , b ) = ∑ i = 1 n ( a x i + b − y i ) 2 Q(a,b)=\sum\limits_{i=1}^n(ax_i+b-y_i)^2 Q(a,b)=i=1n(axi+byi)2 ∂ Q ∂ a = 2 ∑ i = 1 n ( a x i + b − y i ) x i = 0 ① ∂ Q ∂ b = 2 ∑ i = 1 n ( a x i + b − y i ) = 0 ② \begin{aligned}\frac{\partial Q}{\partial a}&=2\sum\limits_{i=1}^n(ax_i+b-y_i)x_i=0\qquad&①\\\frac{\partial Q}{\partial b}&=2\sum\limits_{i=1}^n(ax_i+b-y_i)=0&②\end{aligned} aQbQ=2i=1n(axi+byi)xi=0=2i=1n(axi+byi)=0 ② ② a ∑ i = 1 n x i + n b = ∑ i = 1 n y i a\sum\limits_{i=1}^nx_i+nb=\sum\limits_{i=1}^ny_i ai=1nxi+nb=i=1nyi x ‾ = ∑ i = 1 n x i n \overline x=\frac{\sum\limits_{i=1}^n x_i}{n} x=ni=1nxi y ‾ = ∑ i = 1 n y i n \overline y=\frac{\sum\limits_{i=1}^n y_i}{n} y=ni=1nyi(分别为 x , y x,y x,y的平均值),则有 a x ‾ + b = y ‾ ③ a\overline x+b=\overline y\qquad ③ ax+b=y ① ① a ∑ i = 1 n x i 2 + b ∑ i = 1 n x i = ∑ i = 1 n x i y i a\sum\limits_{i=1}^n x_i^2+b\sum\limits_{i=1}^n x_i=\sum\limits_{i=1}^n x_iy_i ai=1nxi2+bi=1nxi=i=1nxiyi x 2 ‾ = ∑ i = 1 n x i 2 n , x y ‾ = ∑ i = 1 n x i y i n \overline{x^2}=\frac{\sum\limits_{i=1}^n x_i^2}{n},\overline{xy}=\frac{\sum\limits_{i=1}^n x_iy_i}{n} x2=ni=1nxi2,xy=ni=1nxiyi,则有 a x 2 ‾ + b x ‾ = x y ‾ ④ a\overline{x^2}+b\overline{x}=\overline{xy}\qquad④ ax2+bx=xy ③ × x ‾ ③\times\overline x ×x a x ‾ 2 + b x ‾ = x ˉ y ˉ ⑤ a{\overline x}^2+b\overline x=\bar x\bar y\qquad⑤ ax2+bx=xˉyˉ ⑤ − ④ ⑤-④ a ( x ‾ 2 − x 2 ‾ ) = x ˉ y ˉ − x y ‾ a({\overline x}^2-\overline{x^2})=\bar x\bar y-\overline{xy} a(x2x2)=xˉyˉxy由此算出直线的斜率 a = x ˉ y ˉ − x y ‾ x ‾ 2 − x 2 ‾ a=\frac{\bar x\bar y-\overline{xy}}{{\overline x}^2-\overline{x^2}} a=x2x2xˉyˉxy ③ ③ b = y ‾ − a x ‾ b=\overline y-a\overline x b=yax


一次函数拟合的Python代码实现:

# Least Squares Method (Linear)
# Author: seh_sjij

import matplotlib.pyplot as plt
import numpy as np

class LeastSquareMethod(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.n = len(self.x)
        if len(self.y) != self.n:
            raise Exception(
                'LeastSquareMethod: len(x) != len(y)')

    def Calculate(self):
        self.xmean = self.xsquaremean = 0
        # average of x and x^2
        for x_i in self.x:
            self.xmean += x_i
            self.xsquaremean += x_i * x_i
        self.xmean /= self.n
        self.xsquaremean /= self.n
        self.ymean = 0
        # average of y
        for y_i in self.y:
            self.ymean += y_i
        self.ymean /= self.n
        self.xymean = 0
        # average of xy
        for i in range(0, self.n):
            self.xymean += self.x[i] * self.y[i]
        self.xymean /= self.n
        a = (self.xmean * self.ymean - self.xymean) \
            / (self.xmean * self.xmean - self.xsquaremean)
        b = self.ymean - a * self.xmean
        return (a, b) # y = ax + b

if __name__ == '__main__':
    x = [1, 2, 4, 6, 7, 9, 10, 12]
    y = [0.7, 2.25, 4.64, 5.69, 7.40, 8.57, 10.72, 11.64]
    lsm = LeastSquareMethod(x, y)
    a, b = lsm.Calculate()
    plt.scatter(x, y)
    plt.plot(x, [a * x_i + b for x_i in x])
    plt.title('Least Squares Method: y = %fx + %f' % (a, b))
    plt.show()

执行结果:
在这里插入图片描述
时间复杂度: Θ ( n ) \Theta(n) Θ(n)

<think>嗯,用户想了解如何使用最小二乘法进行路径平滑处理。首先,我得回忆一下最小二乘法的基本原理。最小二乘法主要是通过最小化误差的平方和来找到最佳拟合曲线,对吧?这在数据拟合和参数估计中很常见。那如何应用到路径平滑呢? 路径平滑通常是在机器人导航或者自动驾驶中遇到的问题,原始路径可能有很多折线或者不连续的转折点,需要平滑处理以减少急转弯,提高行驶的平稳性。这时候,最小二乘法可能用来拟合这些点,生成平滑的曲线。 接下来,我得考虑具体怎么实现。可能需要将路径点视为观测数据,设定一个参数化的曲线模型,比如多项式曲线或者样条曲线,然后用最小二乘法求解模型参数。误差项应该是实际路径点与拟合曲线之间的偏差,平方和最小化这个过程。 另外,用户提到应用场景,可能需要举几个例子,比如机器人路径规划、自动驾驶轨迹优化或者游戏中的角色移动路径平滑。这些都是常见的应用领域。 还要注意是否要考虑约束条件,比如路径的起点和终点必须固定,或者某些点必须经过。这时候可能需要带约束的最小二乘法,或者使用惩罚项的方法。 然后,实现步骤可能需要数学建模,比如构造设计矩阵和观测向量,求解线性方程组。对于二次曲线的情况,可能需要用矩阵运算来求解系数。 最后,代码示例可能会有帮助,用Python或者MATLAB展示如何用最小二乘法拟合路径点。同时,相关的问题可以引导用户深入探讨,比如与其他平滑算法的比较,如何处理动态障碍物,或者实时性要求高的场景如何优化。 不过,我得检查一下引用的资料是否相关。用户提供的引用中,有关于加权最小二乘法在相位解包裹的应用,这可能涉及到不同权重的处理,或许在路径平滑中也可以引入权重,比如对某些关键点给予更高的权重,确保拟合曲线更贴近这些点。另外,引用中还提到梯度下降,不过可能和最小二乘的直接解法不太相关,除非问题规模很大需要迭代方法。 总之,我需要整理出一个清晰的步骤,从问题分析到数学模型,再到算法实现和应用举例,同时结合用户提供的引用中的相关内容,比如加权最小二乘法的应用,可能作为扩展点提到。</think>### 最小二乘法路径平滑算法实现及应用 #### 1. 问题分析 路径平滑的核心是将原始离散路径点转化为连续平滑曲线,同时减少剧烈方向变化。最小二乘法通过最小化实际路径点与拟合曲线的垂直距离平方和,找到最优平滑路径[^1]。 #### 2. 数学模型 假设原始路径点为$(x_i, y_i)$,需拟合$n$次多项式曲线: $$ y = a_0 + a_1x + a_2x^2 + \dots + a_nx^n $$ 构造误差函数: $$ E = \sum_{i=1}^m \left( y_i - \sum_{k=0}^n a_kx_i^k \right)^2 $$ #### 3. 算法实现步骤 1. **构造设计矩阵**: $$ X = \begin{bmatrix} 1 & x_1 & x_1^2 & \dots & x_1^n \\ 1 & x_2 & x_2^2 & \dots & x_2^n \\ \vdots & \vdots & \vdots & \ddots & \vdots \\ 1 & x_m & x_m^2 & \dots & x_m^n \end{bmatrix} $$ 2. **求解正规方程**: $$ (X^T X) \mathbf{a} = X^T \mathbf{y} $$ 解得系数向量: $$ \mathbf{a} = (X^T X)^{-1} X^T \mathbf{y} $$ 3. **加权优化**(可选): 引入权重矩阵$W$处理关键点优先级[^2]: $$ \mathbf{a} = (X^T W X)^{-1} X^T W \mathbf{y} $$ #### 4. Python实现示例 ```python import numpy as np def smooth_path(points, degree=3): x = np.array([p[0] for p in points]) y = np.array([p[1] for p in points]) # 构造范德蒙德矩阵 X = np.vander(x, degree+1) # 求解最小二乘 coeffs = np.linalg.lstsq(X, y, rcond=None)[0] # 生成平滑曲线 x_smooth = np.linspace(min(x), max(x), 100) y_smooth = np.polyval(coeffs, x_smooth) return list(zip(x_smooth, y_smooth)) ``` #### 5. 应用场景 1. **自动驾驶轨迹优化**:将传感器原始路径点转化为可执行轨迹 2. **机器人导航**:平滑SLAM生成的栅格地图路径 3. **游戏AI寻路**:优化A*算法生成的折线路径[^1] 4. **无人机航迹规划**:消除GPS定位点抖动 #### 6. 参数选择建议 - **多项式次数**:通常选择3-5次,过高易过拟合 - **权重设置**:对障碍物附近点赋予更高权重保证安全性 - **边界约束**:保持起点/终点位置不变
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值