# Having trouble fitting data using NonlinearModelFit

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.

-
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]". –  Szabolcs Nov 25 '13 at 19:09
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. –  bobthechemist Nov 25 '13 at 19:26
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? –  Daniel van Flymen Nov 25 '13 at 19:43
@DanielvanFlymen Three parameters fit three points, not four –  belisarius Nov 25 '13 at 19:53
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. –  Szabolcs Nov 25 '13 at 20:05

## 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]


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


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]}]


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:

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]


-
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] –  belisarius Nov 25 '13 at 21:15
@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. –  bobthechemist Nov 25 '13 at 21:28
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 –  belisarius Nov 25 '13 at 21:37
@bobthechemist It'll probably be easier to transform the equation instead of the data, then we can spare that back-transformation. –  Szabolcs Nov 25 '13 at 21:59
@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). –  Ray Koopman Nov 26 '13 at 2:45