主要内容

非线性数据拟合

这个例子展示了如何使用几种优化工具箱算法将非线性函数拟合到数据。

问题的设置

考虑以下数据:

Data =[0.0000 5.8955 0.1000 3.5639 0.2000 2.5173 0.3000 1.9790 0.4000 1.8990 0.5000 1.3938 0.6000 1.1359 0.7000 1.0096 0.8000 1.0343 0.9000 0.8435 1.0000 0.6856 1.1000 0.6100 1.2000 0.5392 1.3000 0.3946 1.4000 0.3903 1.5000 0.5474 1.6000 0.3459 1.7000 0.1370 1.8000 0.2211 1.9000 0.1704 2.0000 0.2636];

让我们把这些数据点画出来。

t =数据(:1);y =数据(:,2);%轴([0 2 -0.5 6])%抓住情节(t y“罗”)标题(的数据点)

%推迟

我们想要拟合函数

c(1)*exp(-lam(1)*t) + c(2)*exp(-lam(2)*t)

的数据。

解决方案方法使用lsqcurvefit

lsqcurvefit函数很容易解决这类问题。

首先,用一个变量x定义参数:

x (1) = c (1)

x (2) = lam (1)

x (3) = c (2)

林x (4) = (2)

然后将曲线定义为参数x和数据t的函数:

F = @ (x, xdata) x (1) * exp (- x (2) * xdata) + x (3) * exp (- x (4) * xdata);

我们任意设初始点x0如下:c(1) = 1, lam(1) = 1, c(2) = 1, lam(2) = 0:

x0 = [1 1 1 0];

我们运行求解器并绘制出结果的拟合度。

[x, resnorm ~, exitflag,输出]= lsqcurvefit (F, x0、t、y)
局部最小值。lsqcurvefit停止是因为相对于其初始值的平方和的最终变化小于函数公差的值。
x =1×43.0068 10.5869 2.8891 1.4003
resnorm = 0.1477
exitflag = 3
输出=结构体字段:firststorderopt: 7.8852e-06 iterations: 6 funcCount: 35 cgiterations: 0 algorithm: 'trust-region-reflective' stepsize: 0.0096 message: '…'
持有情节(t, F (x, t))

解决方案方法使用fminunc

用它来解决问题fminunc,我们设定目标函数为残差平方和。

Fsumsquares = @(x)sum((F(x,t) - y) ^2);选择= optimoptions (“fminunc”,“算法”,“拟牛顿”);[xunc, ressquared eflag outputu] =fminunc (x0, Fsumsquares选择)
局部最小值。优化完成是因为梯度的大小小于最优性公差的值。
xunc =1×42.8890 1.4003 3.0069 10.5862
ressquared = 0.1477
eflag = 1
outputu =结构体字段:迭代:30 funcCount: 185 stepsize: 0.0017 lssteplength: 1 firststorderopt: 2.9662e-05 algorithm: '拟牛顿' message: '…'

请注意,fminunc找到了相同的解决方案lsqcurvefit,但需要更多的函数计算才能做到这一点。的参数fminunc和那些的顺序相反吗lsqcurvefit;大的是林(2),不是林(1)。这并不奇怪,变量的顺序是任意的。

流([使用fminunc有%d次迭代'和%d使用lsqcurvefit.\n'),outputu.iterations output.iterations)
使用fminunc有30次迭代,使用lsqcurvefit有6次。
流([使用fminunc对%d函数进行评估'和%d使用lsqcurvefit '),outputu.funcCount output.funcCount)
使用fminunc进行函数计算185次,使用lsqcurvefit进行函数计算35次。

分解线性和非线性问题

注意,参数c(1)和c(2)的拟合问题是线性的。这意味着,对于lam(1)和lam(2)的任何值,我们都可以使用反斜杠操作符来找到解决最小二乘问题的c(1)和c(2)的值。

现在我们将问题重新化为一个二维问题,寻找lam(1)和lam(2)的最佳值。c(1)和c(2)的值在每一步使用上面描述的反斜杠操作符计算。

类型fitvector
函数yEst = fitvector(lam,xdata,ydata) % fitvector由DATDEMO用于返回拟合函数的值。% yEst = FITVECTOR(lam,xdata)返回参数设置为lam的数据点xdata处拟合函数y %(定义如下)的值。% yes作为一个N乘1的列向量返回,其中N是%数据点的个数。% % FITVECTOR假设拟合函数y的形式为% % y = c(1)*exp(-lam(1)*t) +…+ c(n)*exp(-lam(n)*t) % %有n个线性参数c, n个非线性参数lam。为了求解线性参数c,我们构建一个矩阵a %,其中a的第j列为exp(-lam(j)*xdata) (xdata是一个向量)。%则求线性最小二乘解c的A*c = ydata,其中ydata是y的观测值。A = 0 (length(xdata),length(lam));% build A matrix for j = 1:length(lam) A(:,j) = exp(-lam(j)*xdata);c = A\ydata;%求解线性参数A*c = y % return the estimated response based on c

用下列方法解决问题lsqcurvefit,从二维初始点lam(1)开始,lam(2):

x02 = [1 0];F2 = @(x,t) fitvector(x,t,y);(x2, resnorm2, ~, exitflag2 output2] = lsqcurvefit (F2, x02 t y)
局部最小值。lsqcurvefit停止是因为相对于其初始值的平方和的最终变化小于函数公差的值。
x2 =1×210.5861 - 1.4003
resnorm2 = 0.1477
exitflag2 = 3
output2 =结构体字段:firststorderopt: 4.4018e-06 iterations: 10 funcCount: 33 cgriterations: 0 algorithm: 'trust-region-reflective' stepsize: 0.0080 message: '…'

二维解的效率与四维解相似:

流(["有%d函数评估使用2d "'公式,%d使用4-d公式'),output2.funcCount output.funcCount)
采用二维配方的评价结果为33项,采用4-d配方的评价结果为35项。

分割问题比初始猜测更有鲁棒性

为最初的四参数问题选择一个糟糕的起点会导致一个不是全局的局部解决方案。选择一个具有相同坏lam(1)和lam(2)值的起始点作为分裂双参数问题的全局解。为了说明这一点,我们重新运行最初的问题,从一个导致相对糟糕的局部解决方案的起点,并将结果与全局解决方案进行比较。

x0bad = [5 1 1 0];[xbad, resnormbad, ~, exitflagbad outputbad] =lsqcurvefit (F, x0bad t y)
局部最小值。lsqcurvefit停止是因为相对于其初始值的平方和的最终变化小于函数公差的值。
xbad =1×4-22.9036 2.4792 28.0273 2.4791
resnormbad = 2.2173
exitflagbad = 3
outputbad =结构体字段:firststorderopt: 0.0057 iterations: 32 funcCount: 165 cgriterations: 0 algorithm: 'trust-region- reflection ' stepsize: 0.0021 message: '…'
持有情节(t、F (xbad t),‘g’)传说(“数据”,“全球健康”,“坏当地合适的,“位置”,“不”)举行

流([“良好终点的剩余规范是%f,”而在糟糕的终点的剩余norm是%f。),resnorm resnormbad)
好的端点处的残差范数为0.147723,坏的端点处的残差范数为2.217300。

相关的话题