6
$\begingroup$

I'm trying to fit

data = {{2002, 45000}, {2004, 90000}, {2005, 120000}, {2013, 211000}};

to an exponential function a*Exp[b*x]+c but Mathematica returns FittedModel[0] when I use:

NonlinearModelFit[data,a*Exp[b*x]+c,{a,b,c},x]

Any help would be gladly welcomed.

$\endgroup$
8
  • $\begingroup$ I edited the question for readability. Please read through it and make sure this is what you meant to ask, and update if necessary. I do get an error, but not "FittedModel[0]". $\endgroup$
    – Szabolcs
    Commented Nov 25, 2013 at 19:09
  • 1
    $\begingroup$ You have four points that are roughly linear. What makes you think that the data should fit an exponential model? Fitting four points to a model with three parameters is going to be tricky. $\endgroup$ Commented Nov 25, 2013 at 19:26
  • 2
    $\begingroup$ Thank you for your feedback... one question, surely it would be possible to find some aExp[bx] such that the four points lie on the line? $\endgroup$ Commented Nov 25, 2013 at 19:43
  • $\begingroup$ @DanielvanFlymen Three parameters fit three points, not four $\endgroup$ Commented Nov 25, 2013 at 19:53
  • $\begingroup$ While it's clear from looking at the points that this form of function is not going to fit them well, you are right that there still should be a best fit, even if not a very good one. Why NonlinearModelFit can't find this I do not know. Something goes wrong with its minimization algorithm. When this happens, I'd try to change the method it uses. I checked the Method option in the docs and came up with NonlinearModelFit[data,a*Exp[b*x]+c,{a,b,c},x, Method -> NMinimize]. This does return a result without complaints. If it's indeed the global minimum, I do not know. $\endgroup$
    – Szabolcs
    Commented Nov 25, 2013 at 20:05

1 Answer 1

9
$\begingroup$

Edit - incorporating ideas from the comments

It makes sense to transform the exponential equation to both take advantage of the benefits of normalization and generate results that are on the same scale as the original data. If our model is defined by eqn below, then we can transform the equation by applying Rescale to the x and y values to get eqn2:

{xmin, xmax, ymin, ymax} = Flatten[Through[{Min, Max}[#]] & /@ Transpose@data]
eqn = y == a Exp[b x] + c
eqn2 = y /. Solve[eqn /. {y -> Rescale[y, {ymin, ymax}],
    x -> Rescale[x, {xmin, xmax}]}, y] // First
(* 1000*(45 + 166*c + 166*a*E^(b*(-182 + x/11))) *)

Performing the NonlinearModelFit with Method->NMinimize appears to be a little more forgiving with the starting values for the parameters, at the expense of a slightly longer calculation time.

nlm = NonlinearModelFit[data, eqn2, {a, b, c}, x, Method -> NMinimize]; 
Column[{
  nlm["BestFitParameters"],
  Normal[nlm],
  nlm["CorrelationMatrix"] // MatrixForm}, Left, 2]

enter image description here

Plot[nlm[x], {x, xmin, xmax}, Epilog -> {Red, PointSize[0.02], Point /@ data}]

enter image description here

Normal provides a form of the equation that can be used to extract the values of a, b, and c, with the caveat that b is not a trivial transformation. I included the correlation matrix to point out that the parameters are highly correlated in this example, suggesting that a fit to this model may not be the best one. As an example of this point, we could also fit the data to a dosage-response function (eqn3):

eqn3 = y == a + (b - a)/(1 + (c/x));
eqn4 = y /. Solve[eqn3 /. {y -> Rescale[y, {ymin, ymax}], 
       x -> Rescale[x, {xmin, xmax}]}, y] // First;
nlm2 = NonlinearModelFit[data, eqn4, {a, b, c}, x,Method -> NMinimize];
Row[{Plot[nlm2[x], {x, xmin, xmax}, 
   Epilog -> {Red, PointSize[0.02], Point /@ data}], Column[{
    nlm2["BestFitParameters"],
    Normal[nlm2],
    nlm2["CorrelationMatrix"] // MatrixForm}, Left, 2]}]

enter image description here

There is less correlation between the parameters in this model, although note that b and c are fairly highly correlated. Removing c from the model (c = 1) and repeating the above process gives:

enter image description here

I have not looked closely at confidence intervals or goodness of fit; however a visual inspection of the three figures suggests that there is not much difference between the three models, which in my opinion leads to a conclusion that the latter model, with its small number of uncorrelated parameters, is appropriate for this set of data. Granted, this assumes no knowledge of what the data are, how they were obtained, and the theory they are supposed to follow.

Original post

I'm no stats expert, but in my experience, normalizing data that spans different orders of magnitude helps:

datan[[All, 1]] = Rescale[#, {Min[data[[All, 1]]], Max[data[[All, 1]]]}] & /@  data[[All, 1]]
datan[[All, 2]] = Rescale[#, {Min[data[[All, 2]]], Max[data[[All, 2]]]}] & /@  data[[All, 2]]
nlm = NonlinearModelFit[datan, a Exp[b x] + c, {a, b, c}, x]
Plot[nlm[x], {x, 0, 1}, Epilog -> {Red, PointSize[0.02], Point /@ datan}, PlotRange -> All]

enter image description here

$\endgroup$
6
  • 1
    $\begingroup$ scx = {Min[data[[All, 1]]], Max[data[[All, 1]]]}; scy = {Min[data[[All, 2]]], Max[data[[All, 2]]]}; Plot[ Rescale[nlm[Rescale[x, scx, {0, 1}]], {0, 1}, scy], {x, Rescale[0, {0, 1}, scx], Rescale[1, {0, 1}, scx]}, Epilog -> {Red, PointSize[0.02], Point /@ data}, PlotRange -> All] $\endgroup$ Commented Nov 25, 2013 at 21:15
  • $\begingroup$ @belisarius what's not obvious to me is how one converts the parameters back to the OP's original units. a and c should be accessible via some basic algebra; however I don't know the relationship between normalized and non-normalized b. $\endgroup$ Commented Nov 25, 2013 at 21:28
  • $\begingroup$ You've transformed x by a linear transformation, so now your exponential is something like Exp[b (pp xnew + qq)] where pp and qq comes from the Rescale parameters $\endgroup$ Commented Nov 25, 2013 at 21:37
  • 1
    $\begingroup$ @bobthechemist It'll probably be easier to transform the equation instead of the data, then we can spare that back-transformation. $\endgroup$
    – Szabolcs
    Commented Nov 25, 2013 at 21:59
  • $\begingroup$ @bob is right. It's instructive here to look at the actual values of the parameter estimates. If we make the simple transformations xnew = x-2000, ynew = y/1000 we get f[xnew] = 260.48 - 283.569 E^(-0.134679 x). Transforming back gives 1000 f[x - 2000] = 260480. - 2.7145*10^122 E^(-0.134679 x). $\endgroup$ Commented Nov 26, 2013 at 2:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.