[含Matlab程序]最小二乘法线性(以空间平面为例)与非线性(以二次函数为例)拟合,不看后悔 | 您所在的位置:网站首页 › 如何利用最小二乘法求拟合直线 › [含Matlab程序]最小二乘法线性(以空间平面为例)与非线性(以二次函数为例)拟合,不看后悔 |
目录
一、以直线拟合作为切入点进行解释二、引入平面的参数求解三、引入非线性表达式的参数求解
最小二乘法解决的是什么问题?使用最小二乘法求参数的关键是什么? ○最小二乘法用于处理数据拟合问题,本质是实现向量向 X {\rm X} X矩阵的列空间投影 ○关键是找 X {\rm X} X矩阵 一、以直线拟合作为切入点进行解释做两个假设 1.我们手中有m个散点,要想用一条直线去拟合,散点的形式是: X = [ x 0 x 1 ⋮ x m − 1 ] Y = [ y 0 y 1 ⋮ y m − 1 ] X = {\begin{bmatrix} {{x_0}}\\ {{x_1}}\\ \vdots \\ {{x_{m - 1}}} \end{bmatrix}} Y = {\begin{bmatrix} {{y_0}}\\ {{y_1}}\\ \vdots \\ {{y_{m - 1}}} \end{bmatrix}} X= x0x1⋮xm−1 Y= y0y1⋮ym−1 2.假如这条直线的形式是已知的,如下: h = θ 0 x + θ 1 h = {\theta _0}x+{\theta _1} h=θ0x+θ1 将我们已知的点的自变量x代入,可以得到以下形式,因此由这条拟合直线可以给我们输出m个结果组成向量H: h 0 = θ 0 x 0 + θ 1 h 1 = θ 0 x 1 + θ 1 ⋮ h m − 1 = θ 0 x m − 1 + θ 1 \begin{array}{l} {h_0} = {\theta _0}{x_0} + {\theta _1}\\ {h_1} = {\theta _0}{x_1} + {\theta _1}\\ \vdots \\ {h_{m-1}} = {\theta _0}{x_{m-1}} + {\theta _1} \end{array} h0=θ0x0+θ1h1=θ0x1+θ1⋮hm−1=θ0xm−1+θ1 H = [ h 0 h 1 ⋮ h m − 1 ] = [ x 0 1 x 1 1 ⋮ ⋮ x m − 1 1 ] [ θ 0 θ 1 ] = X θ (1) {H}= \begin{bmatrix} h_0 \\ h_1 \\ \vdots \\ h_{m-1} \\ \end{bmatrix}=\begin{bmatrix} x_0 &1\\ x_1 &1\\ \vdots &\vdots\\ x_{m-1} &1\\ \end{bmatrix}\begin{bmatrix} \theta_0 \\ \theta_1 \\ \end{bmatrix}={\rm X}{\theta}\tag{1} H= h0h1⋮hm−1 = x0x1⋮xm−111⋮1 [θ0θ1]=Xθ(1) 注意这个 X {\rm X} X从原来的 X X X向量的基础上扩展成mx2的矩阵。 用下面这个公式描述直线的输出值和真实散点的y值的差距: J ( θ ) = ∥ H − Y ∥ 2 = ∥ H − Y ∥ 2 = ∥ X θ − Y ∥ 2 J(\theta) = {\left\| {H - Y} \right\|^2} = {\left\| {H - Y} \right\|^2} = {\left\| {{\rm X}\theta - Y} \right\|^2} J(θ)=∥H−Y∥2=∥H−Y∥2=∥Xθ−Y∥2 最小二乘法的目的就在于实现解出 θ \theta θ矩阵,使 J ( θ ) J(\theta ) J(θ)最小化,即: arg min θ J ( θ ) \mathop {\arg \min }\limits_\theta J(\theta ) θargminJ(θ) 具体是通过矩阵求导实现解出 θ \theta θ矩阵的,参考这篇文章:一文让你彻底搞懂最小二乘法(超详细推导) 这里直接给出结果: θ = ( X T X ) − 1 X T Y (2) \theta = {({{\rm X}^T}{\rm X})^{ - 1}}{{\rm X}^T}Y\tag{2} θ=(XTX)−1XTY(2) 这个形式让人联想起投影矩阵。 H = X θ = X ( X T X ) − 1 X T Y = P Y H = {\rm X}\theta ={\rm X}{({{\rm X}^T}{\rm X})^{ - 1}}{{\rm X}^T}Y={P}Y H=Xθ=X(XTX)−1XTY=PY 其中的P就是常说的投影矩阵,即: P = X ( X T X ) − 1 X T P={\rm X}{({{\rm X}^T}{\rm X})^{ - 1}}{{\rm X}^T} P=X(XTX)−1XT 从形式上看,拟合的输出向量 H H H实际上是真实散点的因变量(对于直线来说就是 Y Y Y)向量向自变量 X {\rm X} X矩阵的列空间投影的结果。 对于直线而言, X {\rm X} X的列空间就是由下面两个向量张成的空间: [ x 0 x 1 ⋮ x m − 1 ] 和 [ 1 1 ⋮ 1 ] \begin{bmatrix} x_0 \\ x_1 \\ \vdots \\ x_{m-1} \\ \end{bmatrix}和\begin{bmatrix} 1 \\ 1 \\ \vdots \\ 1 \\ \end{bmatrix} x0x1⋮xm−1 和 11⋮1 向量的投影可以用来对向量进行正交化。 矩阵的投影则可以把向量投影到空间。 线性代数(十三)投影 对于矩阵 [ 3 0 0 4 0 0 ] \begin{bmatrix} 3&0 \\ 0&4 \\ 0&0 \\ \end{bmatrix} 300040 张成的空间,在下图中即是由向量 c c c和向量 b b b张成的黄色平面。图上标注的是一个三角,实际是一个平面,这个平面中的向量都可以用向量 c c c和向量 b b b线性组合的形式表达。 如果向量 a a a要向这个平面投影,根据投影矩阵: H = X ( X T X ) − 1 X T Y = P Y H ={\rm X}{({{\rm X}^T}{\rm X})^{ - 1}}{{\rm X}^T}Y={P}Y H=X(XTX)−1XTY=PY 在本题中: Y = [ 0 3 4 ] X = [ 3 0 0 4 0 0 ] Y=\begin{bmatrix} 0 \\ 3 \\ 4\\ \end{bmatrix} {\rm X}=\begin{bmatrix} 3&0\\ 0&4 \\ 0&0\\ \end{bmatrix} Y= 034 X= 300040 因此可以求出投影到 X {\rm X} X张成平面上的结果是: H = [ 0 3 0 ] H=\begin{bmatrix} 0\\ 3\\ 0\\ \end{bmatrix} H= 030 用这样一段程序(matlab)就能快速计算: x = [3,0;0,4;0,0] %x = [0,3;4,0;0,0]%交换次序因为张成空间不变,投影结果也不变 y = [0;3;4] h = x/(x'*x)*x'*y在这里顺势介绍一下向量的正交化,这块和最小二乘法关系不大但是和投影关系比较大。 如下图,向量 a a a和向量 b b b原本不是正交的(正交要求内积为0), H H H是 a a a在 b b b上的投影,上一步我们已经求得,而 e = a − H e=a-H e=a−H且与 b b b是正交的, e e e很好求得,由于向量是可以平移的,把红色的 e e e向量的尾巴平移到原点处,就可以得到过原点的一个和 b b b正交的向量,这是对 a a a的正交化。 如果引入一个新的向量 d d d,要想使 d d d与正交化 a a a得到的 e 1 e_1 e1以及 b b b都正交,要先作出 d d d到 e 1 e_1 e1与 b b b张成平面的投影(下图中是一个蓝色的向量,没有字母标注),再用 d d d减去这个投影得到的向量就可以解出向量 e 2 e_2 e2。最终 e 1 e 2 e_1e_2 e1e2和 b b b线性无关且两两正交。这三个向量分别除以各自的模长就得到两两正交的单位向量,这个操作也就是常说的单位化。 图片是本文原创,使用请标明出处。 二、引入平面的参数求解注意平面环节中的符号和第一部分的直线环节的可能有相似之处,但意义不相同。 用不同的形式拟合散点,关键是构建 X {\rm X} X矩阵,对于平面, X {\rm X} X矩阵和直线是不同的。 平面的形式如下: a x + b y + c z + d = 0 或者用一个和直线环节介绍的类似的形式: h = θ 0 x 0 + θ 1 x 1 + θ 2 \begin{array}{l} ax + by +cz+d=0\\ \\ 或者用一个和直线环节介绍的类似的形式:\\ \\ h = {\theta _0}{x_0} + {\theta _1}{x_1} + {\theta _2} \end{array} ax+by+cz+d=0或者用一个和直线环节介绍的类似的形式:h=θ0x0+θ1x1+θ2 可以看出如果找到一个平面去拟合散点,这个平面的因变量变成两个自变量线性组合的形式,而对于直线只有一个因变量。两个自变量 x 0 {x_0} x0, x 1 {x_1} x1分别对应着平面一般式中的 x x x和 y y y,而因变量 h h h则代表着一般式中的 z z z。 如果这时候我们手中有很多散点,把他们带入到平面方程中: h 0 = θ 0 x 0 , 0 + θ 1 x 0 , 1 + θ 2 h 1 = θ 0 x 1 , 0 + θ 1 x 1 , 1 + θ 2 ⋮ h m − 1 = θ 0 x m − 1 , 0 + θ 1 x m − 1 , 1 + θ 2 \begin{array}{l} {{h_0} = {\theta _0}{x_{0,0}} + {\theta _1}{x_{0,1}} + {\theta _2}}\\ {{h_1} = {\theta _0}{x_{1,0}} + {\theta _1}{x_{1,1}} + {\theta _2}}\\ \vdots \\ {{h_{m - 1}} = {\theta _0}{x_{m - 1,0}} + {\theta _1}{x_{m - 1,1}} + {\theta _2}} \end{array} h0=θ0x0,0+θ1x0,1+θ2h1=θ0x1,0+θ1x1,1+θ2⋮hm−1=θ0xm−1,0+θ1xm−1,1+θ2 待求的参数是 θ 0 {\theta _0} θ0, θ 1 {\theta _1} θ1, θ 2 {\theta _2} θ2,同样可以写成 H = X θ H={\rm X}{\theta} H=Xθ的形式,对于求解平面的这三个参数来说, X {\rm X} X矩阵是长得这个样子: [ x 0 , 0 x 0 , 1 1 x 1 , 0 x 1 , 1 1 ⋮ ⋮ ⋮ x m − 1 , 0 x m − 1 , 1 1 ] \begin{bmatrix} x_{0,0} &x_{0,1}&1\\ x_{1,0} &x_{1,1}&1\\ \vdots &\vdots &\vdots\\ x_{m-1,0} &x_{m-1,1}&1\\ \end{bmatrix} x0,0x1,0⋮xm−1,0x0,1x1,1⋮xm−1,111⋮1 而 Y {Y} Y矩阵就是我们手中散点的因变量,对于平面来说就是 z z z值,注意区分符号。 现在 X {\rm X} X和 Y {Y} Y矩阵都是已知的,根据 ( 2 ) (2) (2)式即可求解出 θ {\theta} θ矩阵(其实是向量): [ θ 0 θ 1 θ 2 ] \begin{bmatrix} \theta_0 \\ \theta_1 \\ \theta_2 \\ \end{bmatrix} θ0θ1θ2 三、引入非线性表达式的参数求解假如手中一些散点,要用二次函数进行拟合,一个二次函数的典型形式如下: h = θ 0 x 2 + θ 1 x + θ 2 h = {\theta _0}x^2+{\theta _1} x+{\theta _2} h=θ0x2+θ1x+θ2 对于非线性的场景,关键仍然是找 X {\rm X} X矩阵,首先还是考虑怎么写成 ( 1 ) (1) (1)式的形式: H = [ h 0 h 1 ⋮ h m − 1 ] = [ x 0 2 x 0 1 x 1 2 x 1 1 ⋮ ⋮ ⋮ x m − 1 2 x m − 1 1 ] [ θ 0 θ 1 θ 2 ] = X θ {H}= \begin{bmatrix} h_0 \\ h_1 \\ \vdots \\ h_{m-1} \\ \end{bmatrix}=\begin{bmatrix} x_0^2 &x_0&1\\ x_1^2 &x_1&1\\ \vdots &\vdots&\vdots\\ x_{m-1}^2 &x_{m-1}&1\\ \end{bmatrix}\begin{bmatrix} \theta_0 \\ \theta_1 \\ \theta_2 \\ \end{bmatrix}={\rm X}{\theta} H= h0h1⋮hm−1 = x02x12⋮xm−12x0x1⋮xm−111⋮1 θ0θ1θ2 =Xθ 对于更高次幂的函数,也是如此找 X {\rm X} X矩阵,因为对差距函数(损失函数) J ( θ ) J(\theta) J(θ)求导并使导函数等于零,这是一个对 θ \theta θ求导的过程,不管是线性还是非线性,结果都是 ( 2 ) (2) (2)式,因此只要找到 X {\rm X} X矩阵,就可以求出 θ {\theta} θ。 下面是matlab程序,首先介绍我自定义的LS_fit函数 LS_fit(自变量1,自变量2,因变量,是否是非线性,如果是非线性函数的话最高次项是几次) function [theta] = LS_fit(Mat_x1,Mat_x2,Mat_x3,bool_nonlinear,exponent) if bool_nonlinear == false %随机生成样本(点)的个数 Mat_x4 = Mat_x1.^0;%常数项没有自变量,自变量的位置填充1 %绘出点图 plot3(Mat_x1,Mat_x2,Mat_x3,'redo') hold on %制作X矩阵 x = [Mat_x1,Mat_x2,Mat_x4]; %解出最优参数 theta = (x'*x)\x'*Mat_x3%这里就是用投影矩阵计算投影向量 %绘出平面图 a = 0:1:30; b = 0:1:30; [X,Y] = meshgrid(a,b); Z = theta(1)*X+theta(2)*Y+theta(3); mesh(X,Y,Z) title("拟合图像") xlabel("x值") ylabel("y值") elseif (bool_nonlinear == true) if ischar(exponent) Mat_x4 = Mat_x1.^0;%常数项没有自变量,自变量的位置填充1 x = [Mat_x1,Mat_x4]; Mat_x2copy = Mat_x2; Mat_x2copy = log(Mat_x2copy); theta = (x'*x)\x'*Mat_x2copy; theta(2)=exp(theta(2)); X = 0:0.1:2.5; Y = theta(2)*exp(theta(1)*X); else %制作X矩阵 x = zeros(size(Mat_x1,1),exponent+1); for i = 1:(exponent+1) x(:,i) = Mat_x1.^(exponent-i+1); end %使用x矩阵解出参数 theta = (x'*x)\x'*log(Mat_x2); X = -15:0.1:15; Y = 0; for i = 1:(exponent+1) Y = Y+theta(i)*X.^(exponent+1-i); end end %绘出散点图 plot(Mat_x1,Mat_x2,'o') hold on %绘出曲线图 plot(X,Y,'red-') title("拟合图像") xlabel("x值") ylabel("y值") zlabel("z值") %text(x,y,'说明') legend('样本点','拟合曲线') else disp("错误的输入") end end新建一个脚本,调用刚才定义的LS_fit函数,首先展示平面拟合功能 num = 100;%随机生成100组点 Mat_x1 = 30*rand(num,1);%随机生成自变量 Mat_x2 = 20*rand(num,1); %平面方程,z = (-3x-5y-3)/7 fuc_plane_z = (-3*Mat_x1-5*Mat_x2-3)/7; Mat_z = fuc_plane_z-5+(5+5)*rand(num,1);%在z的基础上上下漂移 LS_fit(Mat_x1,Mat_x2,Mat_z,false,NaN)对于非线性的情况,以二次函数拟合为例,程序如下: num = 100;%随机生成100组点 Mat_x1 = -15 + (30)*rand(num,1) %用公式求x3,并随机加上正负50 offset = -50 + 100*rand(num,1) Mat_y = 4*Mat_x1.^2+6*Mat_x1+1+offset%二次函数 %Mat_y = 5.5*Mat_x1.^3+4*Mat_x1.^2+6*Mat_x1+1+offset%三次函数 %Mat_y = 6*Mat_x1+1+offset%一次函数 LS_fit(Mat_x1,Mat_y,NaN,true,2)拟合的结果: 注意:即使是使用的函数的非线性模式,也可以解决一次函数拟合的问题,也就是一次函数是一种特殊的非线性函数。 num = 100;%随机生成100组点 Mat_x1 = -15 + (30)*rand(num,1) %用公式求x3,并随机加上正负1 offset = -5 + 10*rand(num,1) %Mat_y = 4*Mat_x1.^2+6*Mat_x1+1+offset%二次函数 %Mat_y = 5.5*Mat_x1.^3+4*Mat_x1.^2+6*Mat_x1+1+offset%三次函数 Mat_y = 6*Mat_x1+1+offset%一次函数 LS_fit(Mat_x1,Mat_y,NaN,true,1)针对 h = θ 0 e θ 1 x h = {\theta _0}{{\rm{e}}^{{\theta _1}x}} h=θ0eθ1x的形式,首先线性化,两边取对数可得 ln h = ln θ 0 + θ 1 x \ln h = \ln {\theta _0}{\rm{ + }}{\theta _{\rm{1}}}x lnh=lnθ0+θ1x,记 A = ln θ 0 A=\ln {\theta _0} A=lnθ0 , h ˉ = ln h \bar h=\ln h hˉ=lnh可得 h ˉ = θ 1 x + A \bar h = {\theta _{\rm{1}}}x{\rm{ + }}A hˉ=θ1x+A,这是一个一次函数的形式。 当有多个样本点,需要提前把每个样本的 h ˉ \bar h hˉ解出来 h ˉ 0 = θ 1 x 0 + A h ˉ 1 = θ 1 x 1 + A ⋮ h ˉ m − 1 = θ 1 x m − 1 + A \begin{array}{l} {{\bar h_0} = {\theta _1}{x_0} +A}\\ {{\bar h_1} = {\theta _1}{x_1} +A}\\ \vdots \\ {{\bar h_{m - 1}} = {\theta _1}{x_{m - 1}} +A} \end{array} hˉ0=θ1x0+Ahˉ1=θ1x1+A⋮hˉm−1=θ1xm−1+A 显然 X {\rm X} X矩阵和参数矩阵分别为: [ x 0 1 x 1 1 ⋮ ⋮ x m − 1 1 ] 以及 [ θ 1 A ] \begin{bmatrix} x_0 &1\\ x_1 &1\\ \vdots &\vdots \\ x_{m-1} &1\\ \end{bmatrix} 以及 \begin{bmatrix} {\theta_1} \\ A\\ \end{bmatrix} x0x1⋮xm−111⋮1 以及[θ1A] 用解一次函数的方式解出两个参数, θ 0 = e A {\theta_0}=e^A θ0=eA解出 θ 0 {\theta_0} θ0,这样两个参数就都求解出来了。 Mat_x1 = [1,1.25,1.5,1.75,2]'; Mat_y = [5.1,5.79,6.53,7.45,8.46]'; LS_fit(Mat_x1,Mat_y,NaN,true,'EXP')求得参数分别是 [ θ 1 θ 0 ] = [ 0.5057 3.0725 ] \begin{bmatrix} {\theta_1} \\ {\theta_0}\\ \end{bmatrix}= \begin{bmatrix} 0.5057 \\ 3.0725\\ \end{bmatrix} [θ1θ0]=[0.50573.0725] 注意参数 θ 0 {\theta_0} θ0和 θ 1 {\theta_1} θ1的输出顺序,代入待拟合的函数中得到 h = 3.0725 e 0.5057 x h=3.0725{\rm{e}^{0.5057{x}}} h=3.0725e0.5057x 参考文章: [1] 一文让你彻底搞懂最小二乘法(超详细推导) [2] 线性代数(十三)投影 [3] QR分解 码字不易难免打错, 发现错误欢迎指出, 万分感谢!!! |
CopyRight 2018-2019 实验室设备网 版权所有 |