Is there an appropriate fitting methods for data that as orders of magnitude differences

34 次查看(过去 30 天)
Hi I want to fit my data to a nonlinear equation that I have. This is to extract the equation parameters. I tried to use lsqcurvefit but didn't got very good results. The problem is that the data spans over money orders of magnitudes, from ~1e-10 to ~1 (diode IV curve of both forward and reverse bias). I suspect it gives more weight to the larger values and therefore doesn't fit well at the other parts. Is there more appropriate fitting methods or options that can help in this situation?Thanks
  5 个评论

请先登录,再进行评论。

回答(1 个)

John D'Errico
John D'Errico 2022-2-3
编辑:John D'Errico 2022-2-3
You do NOT want to use a simple least squares on suh a problem. What will happen is the points that are very large will dominate the fit. Think about it. You have two numbers, one is one the order of 1e-10. Your other data point is around 1.
Then what would an error of 1e-2 mean in context of the second point? It seems pretty close.
But how about that really tiny point? An error of 1e-2, on a point at 1e-10 is HUGE.
So what do you do? This is almost always the case where proportional error is what makes sense anyway. The way to deal with that is to log your data. That is, take the logs of all those y values. Now any errors on each point are treated as equally important.
Implicitly, this assumes your noise is a proportional, lognormally distributed noise. And much of the time, this is exactly what you wanted. In terms of your model, this also often works out well. For example, suppose this is my data:
x = 1:10;
y = exp(2.3*x)*17.*lognrnd(0,1,[1 10]) % that is pretty large noise in context!
y = 1×10
1.0e+11 * 0.0000 0.0000 0.0000 0.0000 0.0001 0.0001 0.0057 0.0092 0.0633 5.5667
plot(x,y,'o')
As you can see, the plot is pretty much useless to visualize the data. But a semi-logy plot works quite well.
semilogy(x,y,'o')
We can fit the data simply enough. I'll use a natural log.
ylog = log(y);
But what happens when we log the equation a*exp(b*x)? We will get log(a) + b*x. And now we can use polyfit to fit the data.
coef = polyfit(x,ylog,1)
coef = 1×2
2.3338 2.7103
a = exp(coef(2))
a = 15.0342
b = coef(1)
b = 2.3338
And those coeffcients are actually pretty close to the original values. Again, remember the noise was actually pretty large.
semilogy(x,y,'bo')
hold on
semilogy(x,a*exp(b*x),'r-')
If the model cannot be logged as easily (so you have a sum of terms) you can still use a nonlinear least squares. Just be careful and do so on the logged data.

类别

Help CenterFile Exchange 中查找有关 Get Started with Curve Fitting Toolbox 的更多信息

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by