2026a
# 通过优化拟合曲线
本示例说明如何使用非线性函数对数据进行拟合。
在本示例中,非线性函数是标准指数衰减曲线
其中,y(t) 是时间 t 时的响应,A 和 λ 是要拟合的参数。对曲线进行拟合是指找出能够使误差平方和最小化的参数 A 和 λ
其中,时间为
# 创建样本数据
通常,您要通过测量获得数据。在此示例中,请基于 A=40 和 λ=0.5 且带正态分布伪随机误差的模型创建人工数据。
using TyMath
using TyPlot
using TyOptimization
rng = MT19937ar(5489) # for reproducibility
tdata = 0:0.1:10;
ydata = 40 * exp.(-0.5 * tdata) + randn(rng, size(tdata));
# 编写目标函数
编写一个函数,该函数可接受参数 A 和 lambda 以及数据 tdata 和 ydata,并返回模型 y(t) 的误差平方和。将要优化的所有变量(A 和 lambda)置入单个向量变量 (x)。
function sseval(x, tdata, ydata)
A = x[1]
lambda = x[2]
sse = sum((ydata - A * exp.(-lambda * tdata)) .^ 2)
return sse
end
fminsearch 求解器适用于一个变量 x 的函数。但 sseval 函数包含三个变量。额外变量 tdata 和 ydata 不是要优化的变量,而是用于优化的数据。将 fminsearch 的目标函数定义为仅含有一个变量 x 的函数:
fun = x -> sseval(x, tdata, ydata);
# 求最优拟合参数
从随机正参数集 x0 开始,使用 fminsearch 求使得目标函数值最小的。
x0 = rand(rng, 2);
bestx, = fminsearch(fun, x0)
bestx = 2-element Vector{Float64}:
40.687700233172286
0.49841877756422254
结果 bestx 与生成数据的参数 A = 40 和 lambda = 0.5 相当接近。
# 检查拟合质量
要检查拟合质量,请绘制数据和生成的拟合响应曲线。根据返回的模型参数。
A = bestx[1];
lambda = bestx[2];
yfit = A * exp.(-lambda * tdata);
plot(tdata, ydata, "*");
hold("on")
plot(tdata, yfit, "r");
xlabel("tdata")
ylabel("Response Data and Curve")
title("Data and Best Fitting Exponential Curve")
legend(["Data", "Fitted Curve"])
hold("off")
