MathGroup Archive 2008

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: FindFit, Weibull

  • To: mathgroup at
  • Subject: [mg92891] Re: FindFit, Weibull
  • From: Bill Rowe <readnews at>
  • Date: Fri, 17 Oct 2008 05:23:06 -0400 (EDT)

On 10/16/08 at 5:04 AM, petervansummeren at (P_ter) wrote:

>I found some data which seemed to fit a WeibullDistribution. The
>data are: pr= {16, 34, 53, 75, 93, 120}; After adding the median
>rank to the data: praxis={{16, 0.109101}, {34, 0.26445}, {53,
>0.421407}, {75, 0.578593}, {93, 0.73555}, {120, 0.890899}}; I
>checked with LeastSquares the parameters: \[Alpha]=1.4301;\[Beta] =
>76.318. So far ok. But the following did not work:
>fit2 = {a, b} /. FindFit[praxis, CDF[WeibullDistribution[a, b], x],
>{a ,b}, {x}]

There are several things that can be done. First, with complete
data it is probably better to use a different approach than
non-linear regression to find estimates for the Weibull
parameters. For example:

In[1]:= meanLog = ExpectedValue[Log[x], WeibullDistribution[a,
b], x]

Out[1]= Log[b] - EulerGamma/a

In[2]:= logMedian =
  Log@Quantile[WeibullDistribution[a, b], 1/2] // PowerExpand

Out[2]= log(b)+log(log(2))/a

In[3]:= pr = {16, 34, 53, 75, 93,
   120}; NSolve[{meanLog == Mean[Log[pr // N]],
   logMedian == Log[Median[pr // N]]}, {a, b}]

Out[3]= {{a->1.20807,b->86.6841}}

Note, instead of using the median of the original data there are
other statistics that could be used to find the parameters which
would lead to somewhat different estimated values.

Another approach would be to maximize the loglikelihood
function. For example,

In[5]:= logP = Log@PDF[WeibullDistribution[a, b], x] // PowerExpand;
ll = Total[logP /. x -> pr // N];
NMaximize[{ll, 0 < a && 0 < b}, {a, b}]

Out[7]= {-29.5849,{a->1.93268,b->73.5261}}

But if you prefer the estimates you get from doing a regression
analysis, you can avoid the problem you are encountering by
placing constraints on a and b as well as providing better
starting values. That is,

In[8]:= FindFit[praxis, {CDF[WeibullDistribution[a, b], x],
   a > 0 && b > 0}, {{a, 1}, {b, 100}}, {x}]

Out[8]= {a->1.52051,b->77.4766}

Note, it is important to use reasonably good estimates with the
constraints since using constraints only results in

In[9]:= FindFit[praxis, {CDF[WeibullDistribution[a, b], x],
   a > 0 && b > 0}, {a, b}, {x}]

Out[9]= {a->0.999501,b->1.00018}

which are clearly not very good estimates.

Alternatively, since

In[10]:= Assuming[a > 0 && b > 0 && x > 0,
  Log[-Log[1 - CDF[WeibullDistribution[a, b], x]]] // FullSimplify]

Out[10]= a*Log[x/b]

The problem can be linearized by taking logarithms and avoiding
the problems inherent in non-linear fitting. Doing this will
avoid the problem of finding good initial starting points for
the non-linear regression problem.

>So, I used the parameters in the Weibull CDF and the times from pr
>to get: praxis1= {{16, 0.106157}, {34, 0.27559}, {53, 0.451308},
>{75, 0.623149}, {93, 0.73256}, {120, 0.848082}} (something went
>wrong with editing, so maybe I sent a by accident an unfinished
>message) I checked with FindFit and it worked. But then I gave extra
>some variations: praxis2 = {#, RandomReal[{0.95, 1.05}]
>CDF[WeibullDistribution[1.4, 76.318], #]} & /@ pr; fit4 = {a,b} /.
>FindFit[praxis2, CDF[WeibullDistribution[a,b], x], {a,b}, {x}] After
>a few times trying the two above lines FindFit did not work. It
>could be ok. But it seems to me that FindFit with a such a small
>relative variation in the data from 0.95 to 1.05 should still work.

It looks like your intent was to generate some random numbers
from a Weibull Distribution to use as a test for FindFit here.
But you have set up a problem that will not be correctly solved
using a standard regression analysis. In the standard problem
statistical error is an additive term. Here, you have made it a
multiplicative term. Doing this doesn't make it significantly
more difficult for FindFit to get a solution. But it will make
it much more likely the solution is different from what you
expect and harder for you to interpret. Simply doing
RandomReal[WeibullDistribution[1.5,77.5],{6}] will give you an
adequate sample for testing.

  • Prev by Date: Re: Import["http://.."] wackiness.... ?
  • Next by Date: Re: FindFit, Weibull
  • Previous by thread: Re: FindFit, Weibull
  • Next by thread: Re: FindFit, Weibull