sequence of Gamma distributions in Infer.NET
Hi,
I would like to know if it's possible to model a Gamma process (i.e., a sequence of Gamma distributions) in Infer.NET similar to the Kalman Filter for the Gaussian distribution.
The mean of the Gamma in the next time step should be conditioned on the previous time step's Gamma. I'm not sure how to do this with the Gamma alpha and beta parameters. I guess the mean and variance parameters should work? Please let me know.
Here is my code:
double[] data = new double[] {
0.592,
0.708,
0.789,
0.621,
0.873,
1.074,
4.634,
3.945,
2.118,
4.207,
2.884,
1.462,
2.851 };
Range n = new Range(data.Length);
VariableArray<double> nodes = Variable.Array<double>(n).Named("nodes");
VariableArray<double> NoisyNodes = Variable.Array<double>(n).Named("NoisyNodes");
using (var mblock = Variable.ForEach(n))
{
var i = mblock.Index;
var mIs0 = (i == 0);
var mIsGr = (i > 0);
using (Variable.If(mIs0))
{
nodes[n] = Variable.GammaFromMeanAndVariance(1, 1);
}
using (Variable.If(mIsGr))
{
var prevM = i - 1;
nodes[n] = Variable.GammaFromMeanAndVariance(nodes[prevM], 1);
}
NoisyNodes[n] = Variable.GammaFromMeanAndVariance(nodes[n], 1);
}
NoisyNodes.ObservedValue = data;
InferenceEngine engine = new InferenceEngine(new ExpectationPropagation());
Gamma[] postNodes = engine.Infer<Gamma[]>(nodes);
for (int i = 0; i < n.SizeAsInt; i++)
{
Console.WriteLine("{0}: {1}", data[i], postNodes[i]);
}
This code gives the following error message:
I have also tried Variational message passing and Gibbs sampling as well.
Kind regards,
Jaco
The issue here is that GammaFromMeanAndVariance does not handle stochastic arguments. Factors that handle stochastic arguments are listed on the List of factors and constraints. For example, you can make a Gamma with a stochastic rate, or multiply together two Gamma variables.
I changed the code to multiply the Gammas as you suggested, but getting the error below which I'm unable to fix.
double[] data = new double[] {
0.592,
0.708,
0.789,
0.621,
0.873,
1.074,
4.634,
3.945,
2.118,
4.207,
2.884,
1.462,
2.851 };
Range n = new Range(data.Length);
VariableArray<double> nodes = Variable.Array<double>(n).Named("nodes");
//nodes[n] = Variable.GammaFromMeanAndVariance(1, 1).ForEach(n);
VariableArray<double> NoisyNodes = Variable.Array<double>(n).Named("NoisyNodes");
using (var mblock = Variable.ForEach(n))
{
var i = mblock.Index;
var mIs0 = (i == 0);
var mIsGr = (i > 0);
using (Variable.If(mIs0))
{
nodes[n] = Variable.GammaFromMeanAndVariance(1, 1);
}
using (Variable.If(mIsGr))
{
var prevM = i - 1;
nodes[n] = nodes[prevM] * Variable.GammaFromMeanAndVariance(1, 1);
}
NoisyNodes[n] = nodes[n] * Variable.GammaFromMeanAndVariance(1, 1);
}
NoisyNodes.ObservedValue = data;
InferenceEngine engine = new InferenceEngine(new ExpectationPropagation());
Gamma[] postNodes = engine.Infer<Gamma[]>(nodes);
for (int i = 0; i < n.SizeAsInt; i++)
{
Console.WriteLine("{0}: {1}", data[i], postNodes[i]);
}
Thanks, you found a bug in Infer.NET. You can work around it by initializing nodes. Here is one possible initialisation (it doesn't matter which):
nodes[n].InitialiseTo(Variable<Gamma>.Factor(Gamma.PointMass, NoisyNodes[n]));