5
$\begingroup$

I'm executing the command

NonlinearModelFit[data, c/(1 + a Exp[-b x]), {a, b, c}, x]

with the data being

data = { {0, 15576}, {10, 15935}, {20, 16326}, 
{30, 18235}, {40, 21680}, {50, 22927}, {60, 28667}, 
{70, 41674}, {80, 50020}, {90, 75979}, {100, 148700}, 
{110, 197200}, {120, 212801}, {130, 215499}, {140, 227511}}

and I'm getting a nonsensical result. It's a horrible fit. I've tried various Method options and I always get a bad fit. My goal is to try to replicate what a TI-84 would give.

I don't know enough about this stuff to know why the TI-84 always seems to give reasonable fits but Mathematica does not.

$\endgroup$
1
  • 1
    $\begingroup$ Here is a shallow description of how TI calculators do logistic fitting. $\endgroup$
    – J. M.'s torpor
    Apr 25 '13 at 9:56
7
$\begingroup$

I think you have to give some reasonable start values for the fit. E.g. try

fitFkt = NonlinearModelFit[data,c/(1 + a Exp[-b x]), {a, {b, 0.1}, {c, Max[data[[All, 2]]]}}, x]

As you can see from Show[ListPlot[data], Plot[fitFkt[x], {x, 0, 150}]], the fit is quite ok.

$\endgroup$
3
  • 2
    $\begingroup$ Indeed, the second example under "scope" in the documentation for NonlinearModelFit is exactly this kind of thing. Apparently, if you don't specify initial conditions, it assumes initial values 1. reference.wolfram.com/mathematica/ref/NonlinearModelFit.html $\endgroup$
    – bill s
    Apr 25 '13 at 8:27
  • $\begingroup$ Now, suppose one was given a different set of data with a logistic trend. How does one pick out a reasonable initial guess for b? :) $\endgroup$
    – J. M.'s torpor
    Apr 25 '13 at 13:41
  • $\begingroup$ If another data set shows a similar trend and if you do not know which initial value for b you should chose, then you could try to change the Method. E.g. NonlinearModelFit[data, c/(1 + a Exp[-b x]), {a, b, {c, Max[data[[All, 2]]]}}, x, Method -> "Newton"] leads to the same result without any initial guess for b. $\endgroup$
    – partial81
    Apr 26 '13 at 6:35
5
$\begingroup$

Here's a rather ad hoc procedure for logistic fitting that I use:

dat = N[{{0, 15576}, {10, 15935}, {20, 16326}, {30, 18235}, {40, 21680}, {50, 22927},
         {60, 28667}, {70, 41674}, {80, 50020}, {90, 75979}, {100, 148700}, {110, 197200},
         {120, 212801}, {130, 215499}, {140, 227511}}];

(* rough estimate of asymptote *)
c0 = Max[dat[[All, 2]]];

dm = DeleteCases[dat, {_, c0}];
(* linear regression of transformed data *)
{a0, b0} = {Exp[-\[FormalK]], \[FormalM]} /.
 FindFit[Transpose[{dm[[All, 1]], Log[#/(c0 - #)] &[dm[[All, 2]]]}],
         \[FormalK] + \[FormalM] \[FormalX], {\[FormalK], \[FormalM]}, \[FormalX]];

{at, bt, ct} = {\[FormalA], \[FormalB], \[FormalC]} /. 
          FindFit[dat, \[FormalC]/(1 + \[FormalA] Exp[-\[FormalB] \[FormalX]]),
                  {{\[FormalA], a0}, {\[FormalB], b0}, {\[FormalC], c0}}, \[FormalX]]
   {874.6314992136595, 0.07113415632530808, 242526.3213562982}

We obtain something a bit useful:

Plot[ct/(1 + at Exp[-bt x]), {x, 0, 140}, 
     Epilog -> {Directive[Red, AbsolutePointSize[6]], Point[dat]}]

a logistic fit

FWIW, I also tried the problem on my TI-83 Plus. Using the built-in logistic regression function, I obtained {a, b, c} = {874.6224282, 0.0711340415, 242526.4026}. Pretty close...

$\endgroup$
1
  • $\begingroup$ You're welcome. I figured you'd want to see a way to handle sigmoidally-shaped data in general instead of just the specific data set in the OP, so I presented one of the usual ways. $\endgroup$
    – J. M.'s torpor
    Apr 25 '13 at 15:12

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.