You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@commons.apache.org by Michael Howard <mh...@cra.com> on 2014/11/24 19:47:10 UTC

[math] - Fitting curve with 6 parameters

Hello!

I am trying to estimate the parameters of a large number of curves. They are all instances of the generalized logistic function (http://en.wikipedia.org/wiki/Generalised_logistic_function). Right now, I am using a very basic hill climbing algorithm that I wrote quickly just to see if these curves would indeed be suitable for the data I'm working with.  It would be nice to take advantage of the property that the function is differentiable. I am not an expert in optimization, but I think using an algorithm like Levenberg-Marquardt would likely give a better fit, faster than my crude technique. Plus, L-M is what I've seen used in research papers which fit this function.

I'm trying to do this with what is available in the commons library, but I can't make sense of how to accomplish it.

First, there is actually already a implementation of the generalized logistic curve in the commons, under org.apache.commons.math3.analysis.function.Logistic.Parametric. The 'ParametricUnivariateFunction' class looks like it's intended for use with curve fitting algorithms, using subclasses of org.apache.commons.math3.fitting.AbstractCurveFitter. But, there isn't an implementation which accepts Logistic. If I understand correctly, I would have to code my own implementation of a curve fitting algorithm and have it extend AbstractCurveFitter.

Next, I considered following what's described on the Optimization package documentation (http://commons.apache.org/proper/commons-math/userguide/optimization.html). The partial derivatives for the generalized logistic function are listed on the Wikipedia page and so there's nothing hard about coding them.

But, I don't see how I code the partial derivatives in the required format. In the quadratic problem example in the documentation, the Jacobian is computed in the following way:

            jacobian[i][0] = x.get(i) * x.get(i);//x^2
            jacobian[i][1] = x.get(i);//x
            jacobian[i][2] = 1.0;//1

But in my case, coding the partial derivatives also requires knowing what the value of some of the other parameters. For example, dY/dA is 1 - (1+Q*e^(-B(x-M))^(1/v). I don't know how I can code this properly from the observations I have.

Is there a way of correctly representing this kind of function, perhaps by using the DerivativeStructure class?

Thanks,
-Michael

[Math] MATH-1172 (Was: [math] - Fitting curve with 6 parameters)

Posted by Gilles <gi...@harfang.homelinux.org>.
Hi.

On Mon, 24 Nov 2014 18:47:10 +0000, Michael Howard wrote:
> Hello!
>
> I am trying to estimate the parameters of a large number of curves.
> They are all instances of the generalized logistic function [...]
>
> I'm trying to do this with what is available in the commons library,
> but I can't make sense of how to accomplish it.
>
> First, there is actually already a implementation of the generalized
> logistic curve in the commons, under
> org.apache.commons.math3.analysis.function.Logistic.Parametric. The
> 'ParametricUnivariateFunction' class looks like it's intended for use
> with curve fitting algorithms, using subclasses of
> org.apache.commons.math3.fitting.AbstractCurveFitter. But, there 
> isn't
> an implementation which accepts Logistic. If I understand correctly, 
> I
> would have to code my own implementation of a curve fitting algorithm
> and have it extend AbstractCurveFitter.

That would be the simplest way to go, IMHO.
But I think that it is indeed more complicated than it could be for
simple uses (like in your case).

Thus I opened an issue on the bug-tracking system:
   https://issues.apache.org/jira/browse/MATH-1172

There you can find the Java code that would let a user to just pass
the "ParametricUnivariateFunction" which he wants to fit.

You could readily use it in your case as follows:
---CUT---
final WeightedObservedPoints obs = new WeightedObservedPoints();
// Add sample data to "obs"...

final ParametricUnivariateFunction logistic = new 
Logistic.Parametric();
final double[] guess = new double[] { /* initial values of the 
paramters */ };
final BasicCurveFitter fitter = BasicCurveFitter.create(logistic, 
guess);
final double[] params = fitter.fit(obs.toList());
---CUT---

[It will be discussed on the "dev" ML whether this code should be added
to Commons Math.]

Best regards,
Gilles

> [...]


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


[Math] MATH-1172 (Was: [math] - Fitting curve with 6 parameters)

Posted by Gilles <gi...@harfang.homelinux.org>.
Hi.

On Mon, 24 Nov 2014 18:47:10 +0000, Michael Howard wrote:
> Hello!
>
> I am trying to estimate the parameters of a large number of curves.
> They are all instances of the generalized logistic function [...]
>
> I'm trying to do this with what is available in the commons library,
> but I can't make sense of how to accomplish it.
>
> First, there is actually already a implementation of the generalized
> logistic curve in the commons, under
> org.apache.commons.math3.analysis.function.Logistic.Parametric. The
> 'ParametricUnivariateFunction' class looks like it's intended for use
> with curve fitting algorithms, using subclasses of
> org.apache.commons.math3.fitting.AbstractCurveFitter. But, there 
> isn't
> an implementation which accepts Logistic. If I understand correctly, 
> I
> would have to code my own implementation of a curve fitting algorithm
> and have it extend AbstractCurveFitter.

That would be the simplest way to go, IMHO.
But I think that it is indeed more complicated than it could be for
simple uses (like in your case).

Thus I opened an issue on the bug-tracking system:
   https://issues.apache.org/jira/browse/MATH-1172

There you can find the Java code that would let a user to just pass
the "ParametricUnivariateFunction" which he wants to fit.

You could readily use it in your case as follows:
---CUT---
final WeightedObservedPoints obs = new WeightedObservedPoints();
// Add sample data to "obs"...

final ParametricUnivariateFunction logistic = new 
Logistic.Parametric();
final double[] guess = new double[] { /* initial values of the 
paramters */ };
final BasicCurveFitter fitter = BasicCurveFitter.create(logistic, 
guess);
final double[] params = fitter.fit(obs.toList());
---CUT---

[It will be discussed on the "dev" ML whether this code should be added
to Commons Math.]

Best regards,
Gilles

> [...]


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@commons.apache.org
For additional commands, e-mail: user-help@commons.apache.org