fit custom equation to dataset

조회 수: 19 (최근 30일)
Julie Christoffersen
Julie Christoffersen 2022년 9월 19일
댓글: Julie Christoffersen 2022년 9월 20일
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
William Rose
William Rose 2022년 9월 19일
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 2022년 9월 20일
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

댓글을 달려면 로그인하십시오.

채택된 답변

William Rose
William Rose 2022년 9월 19일
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
Julie Christoffersen
Julie Christoffersen 2022년 9월 20일
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.

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Least Squares에 대해 자세히 알아보기

제품


릴리스

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by