曲线拟合

曲线拟合用于查找一系列数据点的“最佳拟合”线或曲线。 大多数情况下,曲线拟合将产生一个函数,可用于在曲线的任何位置找到点。 在某些情况下,也可能不关心找到函数,而是只想使用曲线拟合来平滑数据并改善绘图的外观。

简而言之,曲线拟合就是在受到一定约束条件的情况下,构建可以表示一系列数据点的曲线或数学函数的过程。更加数学化一点的话,对于一个给定的数据集,曲线拟合是以方程形式引入因变量和自变量之间的数学关系的过程。

一般来说,曲线拟合可以认为有以下形式:

  • 平滑

    我们使用一个函数来尽可能的表示(即逼近)数据集中点的数据。

  • 逼近

    或者如前文所述,我们只想使用曲线拟合来平滑数据并改善绘图的外观。前两种情况下,数据的一般会有相当程度的误差或噪声。

    如下所示,为线性拟合:

    fitting

  • 插值

    对于给定的数据集,产生一个或多个插值曲线通过数据集的每一个点。这种情况下,我们认为数据点很足够准确的。

    如图所示,为线性插值:

    interpolation

这里我们主要讲述在一定约束条件下,如何用一个函数尽可能的表示(即逼近)数据集中的点。同时,使用基于最小二乘的多项式曲线来拟合数据点。

多项式曲线拟合

建立模型——多项式曲线

多项式曲线即为用多项式函数表示的曲线:

f(x)=anxn+an1xn1++a2x2+a1x+a0f(x)=a_n*x^n+a_{n-1}*x^{n-1}+···+a_2*x^2+a_1*x+a_0

f(x)=i=0naixif(x)=\sum_{i=0}^{n}{a_i*x^i}

其中nn代表多项式函数的阶次(degree)。

nn为1时,即为线性函数y=ax+by=a*x+bnn为2时,则是二次函数(quadratic function),nn为3时,自然是三次函数(cubic function)。

这样对于数据集中的nn个点(x,y)(x,y),都有:

{y1^(x,w)=w0+w1x1+w2x12++wm1x1m1+wmx1my2^(x,w)=w0+w1x2+w2x22++wm1x2m1+wmx2myn1^(x,w)=w0+w1xn1+w2xn12++wm1xn1m1+wmxn1myn^(x,w)=w0+w1xn+w2xn2++wm1xnm1+wmxnm\left\{\begin{matrix} \hat{y_1}(x,w)=w_0+w_1*x_1+w_2*x_1^2+···+w_{m-1}*x_1^{m-1}+w_m*x_1^m \\ \hat{y_2}(x,w)=w_0+w_1*x_2+w_2*x_2^2+···+w_{m-1}*x_2^{m-1}+w_m*x_2^m \\ \vdots \\ \hat{y_{n-1}}(x,w)=w_0+w_1*x_{n-1}+w_2*x_{n-1}^2+···+w_{m-1}*x_{n-1}^{m-1}+w_m*x_{n-1}^m \\ \hat{y_n}(x,w)=w_0+w_1*x_n+w_2*x_n^2+···+w_{m-1}*x_n^{m-1}+w_m*x_n^m \end{matrix}\right.

将其写为矩阵形式:

Y^=XW\hat{Y}=XW

其中,W= (w_0,w_1,w_2,···,w_{m-1},w_m)^T,为(m+1)×1(m+1)\times 1的矩阵,XXn×(m+1)n\times (m+1)的矩阵

X=[1111x1x2x3xnx1mx2mx3mxnm]TX=\begin{bmatrix} 1 & 1 & 1 & \cdots & 1\\ x_1 & x_2 & x_3 & \cdots & x_n \\ \vdots & \vdots & \vdots & \vdots & \vdots \\ x_1^m & x_2^m & x_3^m & \cdots & x_n^m \end{bmatrix}^T

自然,我们可以看到随着mm也就是degreedegree的增大,多项式曲线可以拟合的数据就可以更加复杂。

实际上,我们可以发现多项式曲线拟合所使用的多项式模型,是一个针对非线性函数数据的线性模型。

这样,多项式曲线拟合即可表示为,给定数据集,求近似曲线f(x)f(x),使得近似曲线和yy的误差最小。

最小二乘法

有了模型,这下我们使用最小二乘法来求解WW

对于矩阵方程:Ax=bAx=b, 根据bRm×1b\in R^{m\times 1}, ARm×nA\in R^{m\times n}的不同,有以下三种形式:

  1. 超定方程 m>nm>n,且AAbb均已知,其中之一或者二者可能存在误差和干扰
  2. 盲矩阵方程 均bb已知,AA未知
  3. 欠定方程 m<nm<nAAbb均已知,但xx为稀疏向量

最小二乘法,是最常用的线性参数估计方法,常用于对平面上的点拟合直线,对高维空间的点拟合超平面。

普通最小二乘

考虑超定矩阵方程Ax=bAx=b, 其中bRm×1b\in R^{m\times 1}, ARm×nA\in R^{m\times n}, 且m>nm>n

假定bb存在加性观测误差或噪声,即b=b0+eb=b_0+e,其中b0b_0为无误差数据向量,ee为误差向量。

为了抵消误差对矩阵方程的求解的影响,我们引入一校正向量Δb\Delta b,使得b+Δb=b0+e+Δbb0b+\Delta b=b_0+e+\Delta b\rightarrow b_0,从而实现

Ax=b+ΔbAx=b0Ax=b+\Delta b\Rightarrow Ax=b_0

的转换。也就是说,选择校正向量Δb=Axb\Delta b=Ax-b,并使校正向量“尽可能小”,则可以实现无误差的矩阵方程Ax=b0Ax=b_0的求解。

矩阵方程的这一求解思想可以用下面的优化问题描述

minxΔb2=Axb22=(Axb)T(Axb)\mathop{min}_x ||\Delta b||^2=||Ax-b||^2_2=(Ax-b)^T(Ax-b)

这一方法被称为普通最小二乘(Ordinary least squares, OLS)法,一般称为最小二乘法。

于是,矩阵方程的Ax=bAx=b的最小二乘解为

x^LS=argminxAxb22\hat{x}_{LS}=arg\mathop{min}_x||Ax-b||^2_2

展开ϕ=(Axb)T(Axb)\phi =(Ax-b)^T(Ax-b)

ϕ=xTATAxxTATbbTAx+bTb\phi = x^TA^TAx-x^TA^Tb-b^TAx+b^Tb

ϕ\phi相对于xx的导数,并令结果等于零,则有

dϕdx=2ATAx2ATb=0\frac{d\phi}{dx}=2A^TAx-2A^Tb=0

也就是说,xx必然满足

ATAx=ATbA^TAx=A^Tb

当矩阵Am×nA_{m\times n}具有不同的秩时,上述方程的解不同:

  • 超定方程(m>nm>n)列满秩时,即rank(A)=nrank(A)=n

    由于ATAA^TA非奇异,所以方程有唯一解

    xLS=(ATA)1ATbx_{LS}=(A^TA)^{-1}A^Tb

  • 对于不满秩(rank(A)<nrank(A)<n)的超定方程,则最小二乘解为

    xLS=(ATA)ATbx_{LS}=(A^TA)^\dagger A^Tb

    其中\dagger表示该矩阵的Moore-Penrose逆矩阵,即伪逆。

Gauss-Markov定理

在参数估计理论,称参数向量θ\theta的估计θ^\hat{\theta}的数学期望等于未知的参数向量,即E{θ^}=θE\{\hat{\theta}\}=\theta,则θ^\hat{\theta}为无偏估计。进一步地,若一个无偏估计还具有最小方差,则称这一估计为最优无偏估计。

在统计学中,高斯-马尔可夫定理(Gauss-Markov Theorem)陈述的是:在线性回归模型中,如果误差满足零均值、同方差且互不相关,则回归系数的最佳线性无偏估计(BLUE, Best Linear unbiased estimator)就是普通最小二乘法估计

  • 这里最佳的意思是指相较于其他估计量有更小方差的估计量,同时把对估计量的寻找限制在所有可能的线性无偏估计量中。
  • 值得注意的是这里不需要假定误差满足独立同分布(iid)或正态分布,而仅需要满足零均值不相关同方差这三个稍弱的条件。

关于Gauss-Markov定理更详细内容见此:Wiki

放入最小二乘法中,对于数据向量bb含有加性噪声的超定方程Ax=b0+eAx=b_0+e,当ee的期望和协方差矩阵分别为

E\{e\}=0 \\ Cov\{e\}=E\{ee^T\}=\sigma^2I \\

当且仅当rank(A)=nrank(A)=n时,xx的最优无偏解x^\hat{x}存在,最小二乘解即为最优无偏解。

也就是说当ee满足Gauss-Markov定理的假设条件时,即ee零均值,且各个分量互不相关,并且具有相同的方差σ2\sigma^2时,最小二乘解为无偏和最优的。

最小二乘法与最大似然解

若加性误差向量e=[e1,em]Te=[e_1,···e_m]^T为独立同分布的高斯随机向量,则其概率密度函数为

f(e)=1πmΓeexp[(eμe)TΓe1(eμe)]f(e)=\frac{1}{\pi^m|\Gamma_e|}exp[-(e-\mu_e)^T{\Gamma_e}^{-1}(e-\mu_e)]

其中,Γe|\Gamma_e|表示协方差矩阵Γe=diag(σ12,,σm2)\Gamma_e=diag(\sigma_1^2,···,\sigma^2_m)的行列式。

在Gauss-Markov定理条件下(即误差向量ee的各个独立同分布的高斯随机变量均具有零均值和同方差σ2\sigma^2),加性噪声向量ee的概率密度函数简化为

f(e)=1(πσ2)mexp(1σ2eTe)=1(πσ2)mexp(1σ2e22)f(e)=\frac{1}{(\pi\sigma^2)^m}exp(-\frac{1}{\sigma^2}e^Te)=\frac{1}{(\pi\sigma^2)^m}exp(-\frac{1}{\sigma^2}||e||^2_2)

其似然函数为

L(e)=logf(e)=1πmσ2(m+1)e22=1πmσ2(m+1)Axb22L(e)=logf(e)=-\frac{1}{\pi^m\sigma^{2(m+1)}||e||^2_2}=-\frac{1}{\pi^m\sigma^{2(m+1)}}||Ax-b||^2_2

于是,Ax=bAx=b的最大似然解为

x^=argmaxx1πmσ2(m+1)Axb22=argminx12Axb22=x^LS\hat{x}=arg \mathop{max}_{x}\frac{-1}{\pi^m\sigma^{2(m+1)}}||Ax-b||^2_2=arg\mathop{min}_x\frac{1}{2}||Ax-b||^2_2=\hat{x}_{LS}

也就是说,在Guass-Markov定理的条件下,矩阵方程Ax=bAx=b的最小二乘解与最大似然解等价。

Python实现

Python的numpy模块已经实现了很多数值函数,自然也包括了最小二乘法numpy.linalg.lstsq,并且numpy将其封装成了polyfit函数,然后配合poly1d函数,即可完成基于最小二乘法的多项式曲线拟合。

但是在这里为了学习最小二乘法,我使用Python实现了一个简单的最小二乘法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def leastSquares(X, Y, degree):      
Xs = []
for i in range(degree+1):
Xs.append(X**i)
Xs = np.array(Xs).T
Y = Y.T
XT = Xs.transpose()
W = np.dot(np.dot(np.linalg.inv(np.dot(XT,Xs)),XT),Y)
return W[::-1]

x = np.arange(1, 17, 1)
y = np.array([4.00, 6.40, 8.00, 8.80, 9.22, 9.50, 9.70, 9.86, 10.00, 10.20, 10.32, 10.42, 10.50, 10.55, 10.58, 10.60])

print(leastSquares(x, y, 3))
1
[ 0.00624491 -0.20371114  2.18193147  2.57208791]

然后使用numpy中的polyfit,我们可以得到一致的结果,说明实现的是正确的,但是缺少很多优化,和numpy中的实现相比速度很慢。

1
2
>>> print(np.polyfit(x, y, 3))
>>> [ 0.00624491 -0.20371114 2.18193147 2.57208791]

最后,我们使用多项式曲线拟合我们的数据,阶数越高,模型参数更多就可以表示更加复杂的数据:

2阶

1
2
3
4
5
6
7
8
f = np.polyfit(x, y, 2)
p = np.poly1d(f)
yvals = p(x)

plt.figure(figsize=(10,8))
plt.plot(x, y, '.')
plt.plot(x, yvals)
plt.show()

3阶

result

4阶

Reference