Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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.

share|improve this question
1  
Here is a shallow description of how TI calculators do logistic fitting. –  J. M. Apr 25 '13 at 9:56
add comment

2 Answers 2

up vote 6 down vote accepted

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.

share|improve this answer
2  
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 –  bill s Apr 25 '13 at 8:27
    
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? :) –  J. M. Apr 25 '13 at 13:41
    
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. –  partial81 Apr 26 '13 at 6:35
add comment

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...

share|improve this answer
    
Thank you for your detailed answer. –  YequalsX Apr 25 '13 at 14:49
    
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. –  J. M. Apr 25 '13 at 15:12
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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