fit custom equation to dataset

9 views (last 30 days)
I have some different datasets, that I would like to fit the following equation to:
1/((A*((x)^(n)))+(B*(x))+C)
As an example I have the following dataset:
x = [0.1418 0.1655 0.1970 0.2309 0.2770 0.3194 0.3697 0.6509 0.7036 0.8242 1.5176 2.4467 3.7230 5.7430 9.5691 11.8164]'
y = [0.0478 0.0741 0.0916 0.1025 0.1064 0.1111 0.1107 0.0640 0.0680 0.0682 0.0401 0.0273 0.0197 0.0140 0.0091 0.0077]'
I have tried fitting it using the following approach. However, the initial guess seems to change the function a lot.
fitfun = fittype ( @(A,B,C,n,x) 1./((A.*((x).^(n)))+(B.*(x))+C)) ;
[fitted_curve] = fit(x,y,fitfun,'StartPoint',x0) ;
Is there a way to optimize the process, to provide a best fit estimate (for instance using least square method) such that the final function does not depend on the initial guess? I have many datasets so the equations should not be estimated by a subject opinion, but instead automatically based on a best fit.
  2 Comments
William Rose
William Rose on 19 Sep 2022
x = [0.1418 0.1655 0.1970 0.2309 0.2770 0.3194 0.3697 0.6509...
0.7036 0.8242 1.5176 2.4467 3.7230 5.7430 9.5691 11.8164]';
y = [0.0478 0.0741 0.0916 0.1025 0.1064 0.1111 0.1107 0.0640...
0.0680 0.0682 0.0401 0.0273 0.0197 0.0140 0.0091 0.0077]';
fitfun = fittype ( @(A,B,C,n,x) 1./((A.*((x).^(n)))+(B.*(x))+C));
x01=[1,1,1,1];
x02=[10,10,10,10];
x03=[-1,-1,-1,-1];
[fitcurve1,gof1] = fit(x,y,fitfun,'StartPoint',x01);
fprintf('x01: sse=%.3f\n',gof1.sse)
x01: sse=0.282
[fitcurve2,gof2] = fit(x,y,fitfun,'StartPoint',x02);
fprintf('x02: sse=%.3f\n',gof2.sse)
x02: sse=0.003
[fitcurve3,gof3] = fit(x,y,fitfun,'StartPoint',x03);
fprintf('x03: sse=%.3f\n',gof3.sse)
x03: sse=0.079
The results above deomnstrate the sensitivity of the fit result to the starting point, as you correctly and originally noticed. The sum squared error is a lot lower, i.e. fit is a lot better, with x02 as the start point.
Alex Sha
Alex Sha on 20 Sep 2022
try to use the tools with the ability of global optimization, no need for guessing initial start-values
Sum Squared Error (SSE): 0.000270672266655144
Root of Mean Square Error (RMSE): 0.00411303010759057
Correlation Coef. (R): 0.993881014964114
R-Square: 0.987799471906097
Parameter Best Estimate
--------- -------------
a 0.00872467906005005
n -3.77763228775143
b 14.2286575620884
c 4.03993812724298

Sign in to comment.

Accepted Answer

William Rose
William Rose on 19 Sep 2022
Different methods for fitting a nonlinear function (such as your nonlinear function) are at risk of finding a local minimum that is not a global minimum. In other words, the initial guess will matter, and there is no simple way to fix that. The non-simple solution is to try a bunch of different initial guesses and then choose the best of the best fits. If you can determine bounds for the parameters to be fitted, then make initial gueeses that are near the bounds. In your case, you are fitting A, B, C, and n. Suppose you are confident that -1<=A<=+1, 0<=B<=10, 1<=C<=100, and 1<=n<=5. Fit with fmincon() (since the "con" in fmincon() indicates that it can accomodate constraints). Try starting at 3 different values of each parameter: 0.1, .5, and 0.9 of the way along the range of possible values for each. Since you are fitting 4 parameters, you would have 3^4=81 different starting points to try. You try all 81. Your parameter estimate is the parameters that give the lowest error among the 81 "best" fits.
I have used this approach for multiple models and published results.
  1 Comment
Julie Christoffersen
Julie Christoffersen on 20 Sep 2022
Thanks! I ended up using the boundary options, which helped a lot on what I tried to achieve. It's still not the solution I was hoping for, but it will do the job.

Sign in to comment.

More Answers (0)

Products


Release

R2021b

Community Treasure Hunt

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

Start Hunting!