主要内容

非线性数据拟合

这个例子展示了如何使用几个Optimization Toolbox™算法将非线性函数拟合到数据中。

问题的设置

考虑以下数据:

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 0.6856 1.1000 0.6100 1.2000 0.5392 1.3000 0.3946 0.3903 1.5000 0.5474 1.6000 0.3459 1.8000 0.2211 1.9000 0.1704 2.000 0.2636];

把这些数据点画出来。

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

%推迟

我们想要符合函数

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)
局部最小值。lsq曲线拟合停止是因为平方和相对于初始值的最终变化小于函数公差的值。
x =1×43.0068 10.5869 2.8891 1.4003
resnorm = 0.1477
exitflag = 3
输出=结构体字段:firstorderopt: 7.8852e-06 iterations: 6 funcCount: 35 cgiterations: 0算法:'trust-region- reflection ' stepsize: 0.0096消息:'…'
持有情节(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 firstorderopt: 2.9662e-05算法:'类牛顿' message: '…'

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

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

分解线性和非线性问题

注意,拟合问题在参数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 =零(length(xdata),length(lam));A(:,j) = exp(-lam(j)*xdata);end c = A\ydata;% solve A*c = y for linear parameters c; % 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)
局部最小值。lsq曲线拟合停止是因为平方和相对于初始值的最终变化小于函数公差的值。
x2 =1×210.5861 - 1.4003
resnorm2 = 0.1477
exitflag2 = 3
output2 =结构体字段:firstorderopt: 4.4018e-06 iterations: 10 funcCount: 33 cgiterations: 0算法:'trust-region- reflection ' stepsize: 0.0080消息:'…'

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

流(["有%d个函数用2d求值"...'配方,%d使用4-d配方'],...output2.funcCount output.funcCount)
采用二维公式进行函数评价33项,采用4d公式进行函数评价35项。

分裂问题对初始猜测具有更强的鲁棒性

对于原始的四参数问题,选择一个不好的起点会导致局部解不是全局的。选择lam(1)和lam(2)值相同的起始点求解分裂两参数问题,得到全局解。为了证明这一点,我们重新运行了原始问题的起点,导致一个相对较差的局部解决方案,并将结果拟合与全局解决方案进行比较。

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

流(['良好结束点的残差范数是%f '...'在糟糕的结束点处的残差范数是%f '],...resnorm resnormbad)
良好终点处残差范数为0.147723,不良终点处残差范数为2.217300。

相关的话题