在一元线性回归中,我们使用最小二乘法估计出k与b,这其实就是一个求拟合函数的过程。当一元扩展到多元,我们也可以用最小二乘的思想估计出参数
一、最小二乘法
由上图可知,最小二乘法本质上就是一个求无约束目标函数最小值的问题
因此,我们基于这个思想,来介绍一下如何用matlab求解多元函数拟合
二、将最小二乘法视为最值问题
1.利用有约束的fmincon函数
我们前面介绍了用fmincon函数求解非线性规划,但其是一个有约束的求解函数。但是我们只要把约束设置为空,我们也可以用这个函数求解一个无约束目标函数的最小值
(1)定义目标函数
global x y是为了定义全局变量
这里的y_hat是拟合值,是由几个向量运算得到的带有参数的向量。最后我们定义的目标函数为这个向量与真实值的离差平方和,我们要求满足这个目标函数最小值得到的参数
function f = Obj_fun(k)
global x y; % 在子函数中使用全局变量前也需要声明下
y_hat = exp(-k(1)*x(:,1)) .* sin(k(2)*x(:,2)) + x(:,3).^2; % 拟合值
f = sum((y - y_hat) .^ 2);
end
(2)进行求解
我们可以先不带上下界进行求解,得到一个结果,最后再带上上下界,有可能得到一个更好的结果
global x y; % 将x和y定义为全局变量(方便在子函数中直接调用,要先声明)
load data_x_y % 数据集内里面有x和y两个变量
k0 = [0 0]; %初始值,注意哦,这个初始值的选取确实挺难,需要尝试。。。
lb = []; ub = [];
% lb = [-1 -1]; ub = [2 2];
[k, fval] = fmincon(@Obj_fun,k0,[],[],[],[],lb,ub)
2.利用无约束最小值函数
(1)利用fminsearch函数
Nelder-Mead单纯形法求解最小值,适用于解决不可导或求导复杂的函数优化问题
[k, fval] = fminsearch(@Obj_fun,k0)
(2)利用fminunc函数
拟牛顿法求解无约束最小值,适用于解决求导容易的函数优化问题
[k, fval] = fminunc(@Obj_fun,k0)
三、使用matlab自带的非线性最小二乘拟合函数
我们之前将最小二乘法看作一个最值问题,将目标函数设置为离差平方和,能够求解出参数,构造出拟合函数。
但其实matlab有自带的拟合工具函数,其目标函数就不需要我们自己再构造了,下面我们来介绍一下
1.函数语法
这里我们就不用定义全局变量了,k0是我们给的初始值,而xdata,ydata分别为对应的自变量和因变量
x = lsqcurvefit(fun,k0,xdata,ydata,lb,ub,options)
2.定义目标函数
这里的目标函数就是我们的拟合值
function y_hat = fit_fun(k,x)
y_hat = exp(-k(1)*x(:,1)) .* sin(k(2)*x(:,2)) + x(:,3).^2; % 返回的函数就是我们的拟合值
end
3.进行求解
我们可以通过调整options来选择求解算法
k0 = [0 0];
lb = []; ub = [];
[k, fval] = lsqcurvefit(@fit_fun,k0,x,y,lb,ub)
% Choose between 'trust-region-reflective' (default) and 'levenberg-marquardt'.
options= optimoptions('lsqcurvefit','Algorithm','levenberg-marquardt');
[k, fval] = lsqcurvefit(@fit_fun,k0,x,y,lb,ub,options)
四、使用粒子群算法求解拟合问题
粒子群算法求解拟合问题的本质其实也是寻找最小无约束条件下的最小值问题
1.定义目标函数
function f = Obj_fun(k)
global x y; % 在子函数中使用全局变量前也需要声明下
y_hat = exp(-k(1)*x(:,1)) .* sin(k(2)*x(:,2)) + x(:,3).^2;
f = sum((y - y_hat) .^ 2);
end
2.调用函数进行求解
global x y; % 将x和y定义为全局变量(方便在子函数中直接调用,要先声明)
narvs = 2;
% 使用粒子群算法,不需要指定初始值,只需要给定一个搜索的范围
lb = [-10 -10]; ub = [10 10];
[k, fval] = particleswarm(@Obj_fun,narvs,lb,ub)
% 使用粒子群算法后再利用fmincon函数混合求解
options = optimoptions('particleswarm','HybridFcn',@fmincon);
[k,fval] = particleswarm(@Obj_fun,narvs,lb,ub,options)
3.计算拟合值和实际值的相对误差
y_hat = exp(-k(1)*x(:,1)) .* sin(k(2)*x(:,2)) + x(:,3).^2; % 计算拟合值
res_rate = abs(y - y_hat) ./ y; % 相对误差
plot(res_rate) % 每个样本对应的相对误差
mean(res_rate) % 平均相对误差
标签:lb,函数,求解,算法,拟合,fun,ub
From: https://www.cnblogs.com/dlmuwxw/p/18372020