nonlinear regression

조회 수: 3(최근 30일)
john birt
john birt 2011년 3월 7일
I have code
c = [-0.0007, 0.1575, 11.8862, 0.2478, 18.5870];
f = @(c,x) exp(c(1)*x+c(2)*c(3)-c(2)*(c(3)^(1/c(4))+c(5)^2-(c(5)+x).^2).^c(4));
cfit = nlinfit(xdata,ydata,f,c)
My problem is when I run it comes back with say
cfit =
-0.0007 0.1661 12.0481 0.2476 17.9985
but the fit is not that good so i have to re-enter the c values like
c = [-0.0007, 0.1661, 12.0481, 0.2476, 17.9985];
and then i run the nlinfit again, but again the fitted values are not that good, so repeat the procedure of re-netering the c values and running the nlinfit over and over again until I get values that are a good fit. (by good fit I mean that the parameter estimates fit very well graphically)
anyway, how can I get around this so I dont have to labor away by keep on re-entering the cfit values until Im happy with the fit?
I have tried increasing the iterations by
opts = statset('MaxIter',600); fit = nlinfit(xdata,ydata,f,c,opts)
but this seems to make no difference, what should I do?
p.s. my data is
ydata = [1.000010215, 1.000020867, 1.000031957, 1.000043484, 1.000055448, 1.00006785, 1.000080689, 1.000093966, 1.00010768, 1.000121832, 1.000136422, 1.000151449, 1.000166913, 1.000182816, 1.000199156, 1.000215933, 1.000233149, 1.000250802, 1.000268893, 1.000287423]
xdata [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2]

채택된 답변

the cyclist
the cyclist 2011년 3월 7일
I doubt that nlinfit is using all the iterations. It is probably finding a solution that is within the default tolerance, but which is not a tight enough fit for your purposes. You can try setting the "TolFun" and "TolX" variables to very small values, to get a fit with a tighter tolerance.
I also think you might do better if you fit the log of your function (i.e. get rid of the exponentiation) against the log of your ydata. Although it is the same fit in a theoretical sense, numerically you will be more accurate, I think.

추가 답변(3개)

Matt Tearle
Matt Tearle 2011년 3월 7일
I'm not getting the problem you are. I get a warning (see below), but then slightly different coefficients and a very good match to the data. I can also run with random initial c values and often get a good fit. What version of MATLAB do you have?
The bigger problem is that you're trying to fit 5 parameters to a data set of only 20 points, which also vary very slowly and smoothly. Plus the function you have, as the cyclist points out, has an exponential, which will make things pretty touchy. On top of that, your y data lives in a limited range and is prone to roundoff because they are all 1.000stuff. That leading 1 means that you lose about 4 digits of precision. Is there any way you can reexpress your data to make the fitting problem more tractable?

Richard Willey
Richard Willey 2011년 3월 7일
The quality of a nonlinear regression is often highly dependent on the starting conditions that you provide to the optimization solvers.
For this specific problem, I would recommend the following:
  • Perform a log transform
  • Apply linear regression to the transformed data
  • Use the output from the linear regression to estimate good starting conditions for your original nonlinear regression
  • Feed these starting conditions into nlinfit
If you prefer a brute force approach, you might want to look at the multistart capabilities inside Global Optimization Toolbox.

you 2011년 11월 21일
The following results are obtained from other software named Auto2Fit (1stOpt)
(RMSE): 0.0381041237608456
(SSE): 0.0290384849516368
(R): 0.997863797250854
(R^2): 0.995732157863893
Parameter Best Estimated ---------- -------------
c1 0.84902302786944
c2 0.026462634590753
c3 0.0464216499982052
c4 9316.06191718759
c5 -0.500412856603213

Community Treasure Hunt

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

Start Hunting!

Translated by