【Matlab】线性回归之最小二乘法的应用与验证

目录

0. 引言

1. 最小二乘法的目标函数

2. 数学推导

3. 代码实现

4. 结果检验

5. 完整代码

6. 多元非线性回归

7. 交流讨论


0. 引言

一个很常见的问题,已知散点图如下,将其拟合成一条直线。

比如我现在随便画了两条直线,那么该如何评估这两条直线的拟合效果呢?或者说,可以通过什么函数来评估直线对散点图的拟合效果?进一步地,可以通过什么目标函数来求解最优的拟合直线?

1. 最小二乘法的目标函数

最小二乘法的目标函数可以简单理解成下面这个表达式,其中y_{i}是理论值,\hat{y_{i}}是观测值。

Min\sum_{i=1}^n(y_{i}-\hat{y_{i}})^{2}

为了简化问题,我们将y视为一个一次函数,其表达式为y=a*x+b

已知

x=\begin{bmatrix} x_1 & x_2 & ... & x_n \end{bmatrix}

y=\begin{bmatrix} y_1 & y_2 & ... & y_n \end{bmatrix}

\hat{y_{i}}=a*x+b

求最佳的ab,使得上述目标函数取最小值

2. 数学推导

x进行增广得到矩阵运算表达式

\begin{bmatrix} y_{1} & y_{2} & ... & y_{n} \end{bmatrix}=\begin{bmatrix} a & b \end{bmatrix}*\begin{bmatrix} x_{1} & x{2} & ... & x_{n}\\ 1 & 1 & ... & 1 \end{bmatrix}

x的增广矩阵为xp\begin{Vmatrix} a & b \end{Vmatrix}C,则

y=C* xp

一般地,如果xp为方阵,等式两边同时右乘xp^{-1},就可以很快得到ab,但此时xp的规模为2*n,不可逆。

考虑到xp*xp^{T}的规模为2*2,将上述等式两边右乘xp的转置xp^{T},得

y*xp^{T}=C*xp*xp^{T}

此时矩阵xp*xp^{T}可逆,两边右乘xp*xp^{T}的逆矩阵(xp*xp^{T})^{-1},则

y*xp^{T}*(xp*xp^{T})^{-1}=C

C=y*xp^{T}*(xp*xp^{T})^{-1}                                               

3. 代码实现

%% 初始化x,y
x = 1:10;
y = [1.46 2.65 3.70 4.87 6.07 7.47 8.01 10.81 12.20 12.38];
%% 最小二乘法计算a,b
xp = [x; ones(size(x))];
C = y * xp' * inv(xp*xp');
a = C(1);
b = C(2);
%% 作图
plot(x, y, 'o')
hold on
plot(x, a*x+b, '--r');

 

4. 结果检验

通过C=y*xp^{T}*(xp*xp^{T})^{-1}计算得到的a和b究竟能否满足

Min\sum_{i=1}^n(y_{i}-\hat{y_{i}})^2

这中间是缺少数学证明的。现通过实践进行结果检验。

因为matlab的本质是矩阵和向量的运算,所以上述目标函数可以写作

sum((a*x+b-y).*(a*x+b-y))

使用匿名函数可表示为

fun = @(D) sum((D(1)*x+D(2)-y).^2);

这里我们使用fminsearch计算满足目标函数的最佳a和b

%% 验证最小平方和
fun = @(D) sum((D(1)*x+D(2)-y).^2);
D0 = [0 0];
D = fminsearch(fun, D0);
a_ = D(1);
b_ = D(2);

从工作区观察结果可以发现,通过fminsearch计算得到的a_和b_与我们计算的a和b完全一致

5. 完整代码

clear
%% 初始化x,y
x = 1:10;
y = [1.46 2.65 3.70 4.87 6.07 7.47 8.01 10.81 12.20 12.38];
%% 最小二乘法计算a,b
xp = [x; ones(size(x))];
C = y * xp' * inv(xp*xp');
a = C(1);
b = C(2);
%% 作图
plot(x, y, 'o')
hold on
plot(x, a*x+b, '--r');
%% 验证最小平方和
fun = @(D) sum((D(1)*x+D(2)-y).^2);
D0 = [0 0];
D = fminsearch(fun, D0);
a_ = D(1);
b_ = D(2);

6. 多元非线性回归

上述问题其实是一元线性回归问题,现将其推广到多元非线性回归问题。

现有y=a_1x_1x_2+a_2x_1x_3+a_3x_2x_3+a_4,已知x_1x_2x_3y,求系数a_1a_2a_3a_4

这里可以把非线性表达式转换成线性表达式,即令

m=x_1*x_2n=x_1*x_3q = x_2*x_3

y=a_1m+a_2n+a_3q+a_4,多元非线性回归问题转变成了多元线性回归问题。

\begin{bmatrix} y_1 & y_2 & ... & y_n \end{bmatrix}=\begin{bmatrix} a_1 & a_2 & a_3 & a_4 \end{bmatrix}*\begin{bmatrix} m_{1} & m_{2} & ... & m_{n}\\ s_{1} & s_{2} & ... & s_{n}\\ q_{1} & q_{2} & ... & q_{n}\\ 1 & 1 & ... & 1 \end{bmatrix}

clear
%% y = a1x1x2+a2x1x3+a3x2x3+a4
%% 初始化x1,x2,x3,y
x1 = 1:10;
x2 = [6 4 2 7 8 5 1 3 2 3];
x3 = [0.44 0.52 0.45 0.87 0.51 0.94 0.63 0.95 0.24 0.67];
y = [1.46 2.65 3.70 4.87 6.07 7.47 8.01 10.81 12.20 12.38];
%% 最小二乘法计算a1,a2,a3,a4
xp = [x1.*x2; x1.*x3; x2.*x3; ones(size(x1))];
A = y * xp' * inv(xp*xp');
%% 作图
plot(y, 'o')
hold on
plot(A*xp, '+');
%% 验证最小平方和
fun = @(D) sum((D*xp-y).^2);
D0 = [0 0 0 0];
D = fminsearch(fun, D0);

 可以发现A和D完全一致,说明最小二乘法推广到多元线性回归同样适用。

7. 交流讨论

Toblerone_Wind的代码交流群

猜你喜欢

转载自blog.csdn.net/qq_42276781/article/details/121337432