1. 最佳逼近问题
简单来说,最佳逼近问题就是用一些 (基)函数
φi(x),i∈{0,1,⋯,M} 的线性组合来逼近某个函数
f(x),也就是定义
φ(x)=n=0∑Manφn(x)=a0φ0(x)+a1φ1(x)+⋯+aMφM(x)
使得
f(x) 和
φ(x) 在某种(度量)意义下最小,常见的度量包括
ℓ1 范数,
ℓ2 范数(最佳平方逼近),
ℓ∞ 范数(最佳一致逼近)。
例如,多项式曲线拟合的基函数可以定义为
φn(x)=xn,就有
φ(x)=n=0∑Manφn(x)=a0+a1x+a2x2+⋯+aMxM
当
f(x) 具有周期性质,可以采用三角多项式来逼近,就有
φ(x)=a0+a1cosx+b1sinx+⋯+aMcos(Mx)+bMsin(Mx)
若基函数具有正交性,则会大大简化最佳逼近问题。
2. 最佳平方(最小二乘)逼近
最佳平方逼近采用
ℓ2 范数来度量
f(x) 和
φ(x) 之间接近程度。
扫描二维码关注公众号,回复:
11534313 查看本文章
函数
f(x) 的最佳逼近
φ∗(x) 满足:
∥f(x)−φ∗(x)∥22=min∥f(x)−φ(x)∥22
因此,可定义误差函数
E(a0,⋯,aM) 为:
E(a0,⋯,aM)=∥f(x)−φ(x)∥22=∥f(x)−n=0∑Manφn(x)∥22=∫[f(x)−n=0∑Manφn(x)]2dx
此时,误差函数
E(a0,⋯,aM) 为系数
(a0,⋯,aM) 的二次函数,其取极值的必要条件为:
∂ak∂E(a0,⋯,aM)=0(k=0,1,⋯,M)
因此
∂ak∂E(a0,⋯,aM)=−2∫[f(x)−n=0∑Manφn(x)]φk(x)dx=0(k=0,1,⋯,M)
于是
∫f(x)φk(x)dx=∫n=0∑Manφn(x)φk(x)dx=n=0∑Man∫φn(x)φk(x)dx
写成函数内积的形式:
(f,φk)=n=0∑Man(φn,φk)
实际上是一个关于
a0,⋯,aM 的线性方程组,称为法方程
(normal equation):
⎣⎢⎢⎢⎡(φ0,φ0)(φ0,φ1)⋮(φ0,φM)(φ1,φ0)(φ1,φ1)⋮(φ1,φM)⋯⋯⋮⋯(φM,φ0)(φM,φ1)⋮(φM,φM)⎦⎥⎥⎥⎤⎣⎢⎢⎢⎡a0a1⋮aM⎦⎥⎥⎥⎤=⎣⎢⎢⎢⎡(f,φ0)(f,φ1)⋮(f,φM)⎦⎥⎥⎥⎤(1)
求解该线性方程组,就可以得到系数
(a0,⋯,aM) 的值。
对于连续函数的内积,通常有:
(f,φk)=∫abf(x)φk(x)dx
以及
(φn,φk)=∫abφn(x)φk(x)dx
离散情况——以线性回归为例
离散情况时,以一维线性回归为例,已知观测样本集
{xi,yi}∣∣0N,要求出函数
f(x) 的逼近函数:
φ(x)=n=0∑1anφn(x)=a0+a1x
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200503124947633.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hmaWp1bg==,size_16,color_FFFFFF,t_70)
上图中,线性回归关于每个观测点
(xi,yi) 的
ℓ2 损失(平方误差)为:
[φ(xi)−yi]2
误差函数定义为“误差的平方之和”:
E(a0,a1)=[φ(x0)−y0]2+[φ(x1)−y1]2+⋯+[φ(xN)−yN]2=i=0∑N[φ(xi)−yi]2=i=0∑N(yi−a0−a1xi)2
通过求出系数
(a0,a1) 的值,用
φ(x)≈f(x)。
- 对误差函数求
a0 的偏导:
∂a0∂E(a0,a1)=2i=0∑N(yi−a0−a1xi)(−1)=0
可以写成:
a0i=0∑N1+a1i=0∑Nxi=i=0∑Nyi
⟹
a0=N1i=0∑N(yi−a1xi)
- 对误差函数求
a1 的偏导:
∂a1∂E(a0,a1)=2i=0∑N(yi−a0−a1xi)(−xi)=0
可以写成:
a0i=0∑Nxi+a1i=0∑Nxi2=i=0∑Nyixi
⟹
a1=i=0∑Nxi2i=0∑N(yi−a0)xi
代入
a0,可得到:
a1=i=0∑Nxi2−N1(i=0∑Nxi)2i=0∑Nyi(xi−N1i=0∑Nxi)
若记样本的均值为
xˉ=N1i=0∑Nxi,则
a1=i=0∑Nxi2−Nxˉ2i=0∑Nyi(xi−xˉ)
这种求解,实际上就是求4.1节中的解线性方程组
(1) 的过程。
3. 最小二乘学习(离散情况的另一种描述)
如下图所示,已知观测样本集
{xi,yi}∣∣0N,仍然采用线性模型:
φ(x)=n=0∑Manφn(x)=a0φ0(x)+a1φ1(x)+⋯+aMφM(x)=θTϕ(x)=ϕT(x)θ
其中,
θ=[a0,a1,⋯,aM]T,
ϕ(x)=[φ0(x),φ1(x),⋯,φM(x)]T
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200503124425924.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hmaWp1bg==,size_16,color_FFFFFF,t_70)
上图中,线性模型关于每个观测点
(xi,yi) 的
ℓ2 损失(平方误差)为:
[φ(xi)−yi]2
将“数据集所有观测点上的平方误差之和”设为损失函数
(loss function):
J(θ)=[φ(x0)−y0]2+[φ(x1)−y1]2+⋯+[φ(xN)−yN]2=i=0∑N[φ(xi)−yi]2=i=0∑N[θTϕ(xi)−yi]2=∥Φθ−y∥22
其中,
y=[y0,y1,⋯,yN]T
Φ=⎣⎢⎢⎢⎡ϕ(x0)Tϕ(x1)T⋮ϕ(xN)T⎦⎥⎥⎥⎤=⎣⎢⎢⎢⎡φ0(x0)φ0(x1)⋮φ0(xN)φ1(x0)φ1(x1)⋮φ1(xN)⋯⋯ ⋯φM(x0)φM(x1)⋮φM(xN)⎦⎥⎥⎥⎤
这里的
Φ 称为设计矩阵
(design matrix),其元素为
Φnm=φm(xn)
损失函数
J(θ) 对系数
θ 求偏导:
∂θ∂J(θ)=2ΦT(Φθ−y)=0
可得到:
ΦTΦθ=ΦTy (2)
显然,线性方程组(2)和(1)是等价的,可求得:
θ=(ΦTΦ)−1ΦTy(3)
最小二乘解的几何意义
最小二乘解的几何意义如下图描述:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200127172626885.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hmaWp1bg==,size_16,color_FFFFFF,t_70#pic_center)
From 《PRML》Fig 3.2
考虑线性方程组
Φθ−y=0,可表示为:
[φ0,φ1,φ2,⋯,φM]⎣⎢⎢⎢⎢⎢⎡a0a1a2⋮aM⎦⎥⎥⎥⎥⎥⎤=y
其中,
φi=[φi(x0),φi(x1),φi(x2),⋯,φi(xN)]T
y=[y0,y1,y2,⋯,yN]T
图中的
S=C(Φ),表示矩阵
Φ=[φ0,φ1,φ2,⋯,φM] 的列空间
(column space)。
- 如果
y∈S,线性方程组
Φθ=y 有唯一解
- 如果
y∈/S,线性方程组
Φθ=y 无解,只能到
S 中找一个最接近
y 的解,最小二乘解是指图中的
y^(在
ℓ2 范数下
∥y−y^∥22 的值最小,
y^∈S)
4. 最小二乘法实现曲线拟合
4.1 线性回归(解方程组1)
以比较简单的曲线拟合问题为例,如果我们对于函数
f(x) 的了解只有一个观测样本集
{(xi,yi)}∣∣0N,如下图中绿色的 ‘+’ 所标记的这些数据点所示。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200108153309783.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hmaWp1bg==,size_16,color_FFFFFF,t_70#pic_center)
图1线性函数
曲线拟合的目标是:基于这些观测数据
{xi,yi}∣∣0N,用最佳平方逼近的方式来估计真实函数
f(x) 的表达式,观测值满足
yi=f(xi)+εi。
令基函数为
φn(x)=xn,则多项式函数逼近为:
φ(x)=n=0∑Manφn(x)=a0+a1x+a2x2+⋯+aMxM
通过求出系数
(a0,⋯,aM) 的值,用
φ(x)≈f(x),实际上就是计算:
(f,φk)=n=0∑Man(φn,φk)
曲线拟合问题描述的是离散的情况。考虑图1中的线性拟合问题,只需要计算两个系数
a0 和
a1,近似函数
φ(x)=a0φ0(x)+a1φ1(x)=a0+a1x。
也就是计算线性方程组的未知数
a0 和
a1:
[(φ0,φ0)(φ0,φ1)(φ1,φ0)(φ1,φ1)][a0a1]=[(f,φ0)(f,φ1)]
其中,
φ0(x)=1,
φ1(x)=x。
对于观测样本集
{(xi,yi)}∣∣0N,离散形式的内积为:
(f,φk)=i=0∑Nyiφk(xi)=⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧i=0∑Nyii=0∑Nyixi(k=0)(k=1)
(φn,φk)=i=0∑Nφn(xi)φk(xi)=⎩⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎧i=0∑N1i=0∑Nxii=0∑Nxii=0∑Nxi2(n=0,k=0)(n=0,k=1)(n=1,k=0)(n=1,k=1)
因此,线性方程组为(和第2节中的过程一样):
⎣⎢⎢⎡i=0∑N1i=0∑Nxii=0∑Nxii=0∑Nxi2⎦⎥⎥⎤[a0a1]=⎣⎢⎢⎡i=0∑Nyii=0∑Nyixi⎦⎥⎥⎤
代码实现
import numpy as np
import matplotlib.pyplot as plt
def gen_lineardata(a,b,x):
y = a*x + b
y_noise = y + np.random.randn(len(x))*30
return y, y_noise
def linear_regression(y_noise,x):
a11 = len(x)
a12 = np.sum(x)
a22 = np.sum(np.power(x,2))
f1 = np.sum(y_noise)
f2 = np.sum(y_noise*x)
coef = np.dot(np.linalg.inv(np.array([[a11,a12],[a12,a22]])),np.array([f1,f2]))
return coef
if __name__ == '__main__':
x = np.linspace(0,20,200)
a = int(np.random.rand()*10)+1
b = int(np.random.rand()*20)+1
y, y_noise = gen_lineardata(a,b,x)
plt.plot(x,y,'b')
plt.plot(x,y_noise,'g+')
coef = linear_regression(y_noise,x)
a1 = coef[1]
b1 = coef[0]
print(coef)
y1,y2 = gen_lineardata(a1,b1,x)
plt.plot(x,y1,'r')
plt.legend(labels=['original data','noise data','least-squares'],loc='upper left')
plt.title('y='+str(a)+'x +'+str(b))
plt.show()
某一次的实现结果:b=11.38812346, a=6.59033571(真实值为b=10,a=7)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200123010758456.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hmaWp1bg==,size_16,color_FFFFFF,t_70)
线性回归的实现也可以采用解方程组(2)的方式(M=1):
def linear_regression_approx(y_noise,x,M):
design_matrix = np.asmatrix(np.ones(len(x))).T
for i in range(1,M+1):
arr = np.asmatrix(np.power(x,i)).T
design_matrix = np.concatenate((design_matrix ,arr),axis=1)
coef = (design_matrix.T*design_matrix).I*(design_matrix.T*(np.asmatrix(y_noise).T))
return np.asarray(coef)
4.2 周期函数的逼近(解方程组2)
针对具有周期性质的数据集,更适合采用三角函数作为基函数,即采用公式:
φ(x)=a0+a1cosx+b1sinx+⋯+aMcos(Mx)+bMsin(Mx)
根据公式(3)求出系数。
import numpy as np
import matplotlib.pyplot as plt
def gen_data(x):
y = 2*np.sin(2*np.pi*x) + 3*np.cos(3*np.pi*x)
y_noise = y + np.random.randn(len(x))
return y, y_noise
def least_squares_approx(y_noise,x,M):
design_matrix = np.asmatrix(np.ones(len(x))).T
for i in range(1,M+1):
arr_sin = np.asmatrix(np.sin(i*x)).T
design_matrix = np.concatenate((design_matrix ,arr_sin),axis=1)
arr_cos = np.asmatrix(np.cos(i*x)).T
design_matrix = np.concatenate((design_matrix ,arr_cos),axis=1)
coef = (design_matrix.T*design_matrix).I*(design_matrix.T*(np.asmatrix(y_noise).T))
return np.asarray(coef)
def approx_plot(coef,x,M):
y = np.ones(len(x))*coef[0,0]
for i in range(1,M+1):
y = y + np.sin(i*x)*coef[2*i-1,0] + np.cos(i*x)*coef[2*i,0]
plt.plot(x,y,'r')
if __name__ == '__main__':
x = np.linspace(0,4,100)
y, y_noise = gen_data(x)
plt.plot(x,y,'b')
plt.plot(x,y_noise,'g+')
M = 8
coef = least_squares_approx(y_noise,x,M)
approx_plot(coef,x,M)
plt.legend(labels=['original data','noise data','least square'],loc='upper left')
plt.title('$y=2\sin(2\pi x)+3\cos(3\pi x)$')
plt.show()
运行结果:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200124163420153.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hmaWp1bg==,size_16,color_FFFFFF,t_70)
注:本文并未深入考虑线性方程组(1)和(2)的左端系数矩阵是否可逆的问题,只是实现了通过求解析解来求出系数;在观测数据集非常庞大的时候,求解析解的方式难以实现,需要采用梯度下降法之类的最优化算法来求取近似解。