5
$\begingroup$

I am trying to fit some data through the Mathematica function FindFit, however I encounter the errror:

FindFit::fmgz: Encountered a gradient that is effectively zero. The result returned may not be a minimum; it may be a maximum or a saddle point.

My code is the following:

data1 = {2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016};
data2 = {0.12, 0.13, 0.13, 0.11, 0.1, 0.08, 0.09, 0.09, 0.07};
data = Transpose@{data1, data2};
f = Normal[FindFit[data, a*Exp[-b *x], {a, b}, x]];
k = Plot[f, {x, 2009, 2016}];
g = ListPlot[data, Epilog -> {PointSize[Medium], Point[data]}];
Show[g, k, PlotRange -> Automatic]

I used excel to fit the data and I get the following function:

$$y=7\cdot10^{61}e^{-0.072x}$$

I would like to get a similar function using Mathematica. Any help is appreciated!

$\endgroup$
3
$\begingroup$

The Possible Issues section of the documentation says Good starting values may be necessary to get a reasonable fit.

It seems we don't need much prior knowledge to get a reasonable fit, in this case:

FindFit[data, 10^a*Exp[-b*x], {a, {b, 0}}, x]
{a -> 59.3085, b -> 0.0690153}
$\endgroup$
  • $\begingroup$ Why did you add ${b,0}$? Is there a way of finding the function without giving this much information in the begining? Say the below function was not given and I wanted to approximate the data with an exponential function $\endgroup$ – user372003 Sep 26 '17 at 8:15
  • $\begingroup$ @user372003 {b, 0} gives b a starting value of zero. I do not know a way of making FindFit work with less information than this. I do not know to what you refer when you write "the below function." $\endgroup$ – Mr.Wizard Sep 26 '17 at 8:32
3
$\begingroup$

What excel does is this:

data1 = {2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016};
data2 = {0.12, 0.13, 0.13, 0.11, 0.1, 0.08, 0.09, 0.09, 0.07};
data = Transpose@{data1, Log[data2]};
FullSimplify[Exp[Fit[data, {1, x}, x]]]

$6.50414\cdot 10^{61} e^{-0.0718844 x}$

$\endgroup$
3
$\begingroup$

For functions that use iterative procedures (such as FindFit and NonlinearModelFit) using "good" starting values is a fact of life. @Mr.Wizard's answer uses a better starting value for b and reparameterizes the function so that 10^a replaces a (which is a common necessity for nonlinear models). That the original parameters are many orders of magnitude apart doesn't help either.

For this particular functional form one can look at a linearization of the function. Instead of fitting

$$y=a e^{-b x} + \epsilon$$

one can consider

$$ \log{y} = \log{a} - b x + \epsilon$$

Then one can use LinearModelFit which does not use an iterative procedure which means there is no need to guess at starting values. (And LinearModelFit is less sensitive to orders of magnitude differences in parameters although it is not completely immune.)

data1 = {2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016};
data2 = {0.12, 0.13, 0.13, 0.11, 0.1, 0.08, 0.09, 0.09, 0.07};
data = Transpose@{data1, data2};
lmf = LinearModelFit[Transpose@{data1, Log[data2]}, x, x];
lmf["BestFitParameters"]
(* {142.33012887191313, -0.07188439391126572} *)

Show[ListPlot[data], Plot[Exp[lmf[x]], {x, 2008, 2016}]]

Data and linear model fit

Note: This is exactly @Coolwater 's answer but much more verbose.

$\endgroup$
  • 2
    $\begingroup$ ...and one always has the option to use the LinearModelFit[]-derived parameters as seeds for further polishing with NonlinearModelFit[]. $\endgroup$ – J. M. will be back soon Sep 26 '17 at 15:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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