[含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= x0x1xm1 Y= y0y1ym1

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+θ1hm1=θ0xm1+θ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= h0h1hm1 = x0x1xm1111 [θ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(θ)=HY2=HY2=XθY2
最小二乘法的目的就在于实现解出 θ \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} x0x1xm1 111

向量的投影可以用来对向量进行正交化。
矩阵的投影则可以把向量投影到空间。
线性代数(十三)投影
对于矩阵
[ 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线性组合的形式表达。
[含Matlab程序]最小二乘法线性(以空间平面为例)与非线性(以二次函数为例)拟合,不看后悔_第1张图片

如果向量 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=aH且与 b b b是正交的, e e e很好求得,由于向量是可以平移的,把红色的 e e e向量的尾巴平移到原点处,就可以得到过原点的一个和 b b b正交的向量,这是对 a a a的正交化。
[含Matlab程序]最小二乘法线性(以空间平面为例)与非线性(以二次函数为例)拟合,不看后悔_第2张图片

如果引入一个新的向量 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线性无关且两两正交。这三个向量分别除以各自的模长就得到两两正交的单位向量,这个操作也就是常说的单位化。

[含Matlab程序]最小二乘法线性(以空间平面为例)与非线性(以二次函数为例)拟合,不看后悔_第3张图片

图片是本文原创,使用请标明出处。

二、引入平面的参数求解

注意平面环节中的符号和第一部分的直线环节的可能有相似之处,但意义不相同。
用不同的形式拟合散点,关键是构建 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+θ2hm1=θ0xm1,0+θ1xm1,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,0xm1,0x0,1x1,1xm1,1111
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= h0h1hm1 = x02x12xm12x0x1xm1111 θ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) 

[含Matlab程序]最小二乘法线性(以空间平面为例)与非线性(以二次函数为例)拟合,不看后悔_第4张图片

对于非线性的情况,以二次函数拟合为例,程序如下:

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) 

拟合的结果:
[含Matlab程序]最小二乘法线性(以空间平面为例)与非线性(以二次函数为例)拟合,不看后悔_第5张图片

注意:即使是使用的函数的非线性模式,也可以解决一次函数拟合的问题,也就是一次函数是一种特殊的非线性函数。

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) 

[含Matlab程序]最小二乘法线性(以空间平面为例)与非线性(以二次函数为例)拟合,不看后悔_第6张图片
针对 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+Ahˉm1=θ1xm1+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} x0x1xm1111 以及[θ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
[含Matlab程序]最小二乘法线性(以空间平面为例)与非线性(以二次函数为例)拟合,不看后悔_第7张图片

参考文章:
[1] 一文让你彻底搞懂最小二乘法(超详细推导)
[2] 线性代数(十三)投影
[3] QR分解

码字不易难免打错,
发现错误欢迎指出,
万分感谢!!!

你可能感兴趣的:(数模笔记,matlab,最小二乘法,平面,线性代数)