Infer.NET user guide : Calling Infer.NET from IronPython
Mixture of Gaussians in IronPython
For a description of this tutorial and the C# code please see the mixture of Gaussians tutorial.
### IronPython script
#-----------------------------------------------------------------------------------
# Infer.NET IronPython example: A mixture of 2 multivariate Gaussians
#-----------------------------------------------------------------------------------
import InferNetWrapper
from InferNetWrapper import *
# Initialisation function for breaking symmetry
def init_func() :
return Discrete.PointMass(Rand.Int(2), 2)
# Generate data from function
def generate_data(n_data):
trueM1 = Vector.FromArray(System.Array[float]((2.0, 3.0)))
p1 = System.Array.CreateInstance(float,2,2); p1[0,0] = 3.0; p1[1,0] = 0.2; p1[0,1] = 0.2; p1[1,1] = 2.0
trueP1 = PositiveDefiniteMatrix(p1)
trueM2 = Vector.FromArray(System.Array[float]((7.0, 5.0)))
p2 = System.Array.CreateInstance(float,2,2); p2[0,0] = 2.0; p2[1,0] = 0.4; p2[0,1] = 0.4; p2[1,1] = 4.0
trueP2 = PositiveDefiniteMatrix(p2)
trueVG1 = VectorGaussian.FromMeanAndPrecision(trueM1, trueP1)
trueVG2 = VectorGaussian.FromMeanAndPrecision(trueM2, trueP2)
truePi = 0.6
trueB = Bernoulli(truePi)
Rand.Restart(12347)
data = System.Array.CreateInstance(Vector, n_data)
for j in range(0, n_data):
bSamp = trueB.Sample()
if bSamp:
data[j] = trueVG1.Sample()
else:
data[j] = trueVG2.Sample()
return data
def gaussian_mixture():
print("\n\n------------------ Infer.NET Mixture of Gaussians example ------------------\n");
# Define a range for the number of mixture components
k = Range(2)
# Mixture component means
means = Variable.Array[Vector](k).Named("means")
mm0 = Vector.FromArray(0.0,0.0)
mp0 = PositiveDefiniteMatrix.IdentityScaledBy(2,0.01)
means[k] = Variable.VectorGaussianFromMeanAndPrecision(mm0, mp0).ForEach(k)
# Mixture component precisions
precs = Variable.Array[PositiveDefiniteMatrix](k).Named("precs")
precs[k] = Variable.WishartFromShapeAndScale(100.0, PositiveDefiniteMatrix.IdentityScaledBy(2,0.01)).ForEach(k)
# Mixture weights
weights = Variable.Dirichlet(k, System.Array[float]((1, 1))).Named("weights")
# Create a variable array which will hold the data
n = Range(300)
data = Variable.Array[Vector](n).Named("x")
# Initialise to break symmetry
length = n.SizeAsInt
# Create latent indicator variable for each data point
z = Variable.Array[int](n).Named("z")
# Call initialiser from wrapper
InitArray.init_var_arr(z, init_func, length)
#mixture of gaussians
with (Variable.ForEach(n)) :
z[n] = Variable.Discrete(weights)
with (Variable.Switch(z[n])) :
data[n] = Variable.VectorGaussianFromMeanAndPrecision(means[z[n]], precs[z[n]])
# Binding the data
data.ObservedValue = generate_data(n.SizeAsInt)
# The inference
ie = InferenceEngine(VariationalMessagePassing())
wDist = ie.Infer(weights)
print "Estimated means for pi = (", wDist.GetMean().ToString(), ")"
print "Distribution over pi = ", wDist.ToString()
print "Distribution over vector Gaussian means ="
print ie.Infer(means)
print "Distribution over vector Gaussian precisions ="
print ie.Infer(precs)