I have a dataset that consists of two truncated normal distributions that I’m trying to unmix. I know the mu/sigma of one of the two and I’m trying to extract the weights, as well as the mu/sigma of the unknown gaussian. The follow code works most of the time:
with pm.Model() as model:
w = pm.Dirichlet('w', a=np.array([1, 1])) # 2 mixture weights
mu1 = pm.Normal("mu1", mu=np.mean(x), sigma=np.std(x))
sig1 = pm.HalfNormal('sig1', sigma=np.std(x))
tn1 = pm.TruncatedNormal.dist(mu=mu1,
sigma=sig1,
lower=low_cutoff,
upper=high_cutoff)
tn2 = pm.TruncatedNormal.dist(mu=known_mean,
sigma=known_sigma,
lower=low_cutoff,
upper=high_cutoff)
like = pm.Mixture(name="like",
w=w,
comp_dists=[tn1, tn2],
observed = x)
However sometimes it converges on some obviously wrong results. I know things about the distribution such as the bound on the weights (no distribution should be less than 5% of the mixture, sig1 should be bounded between 0.5 and 2), but I can’t quite figure out how to add bounds like this.
I tried:
pm.Bound(pm.HalfNormal, lower=0.5, upper=2.0)('x', mu=np.mean(x), sigma=np.std(x))
and I get an error about dist:
TypeError: __new__() missing 1 required positional argument: 'dist'
It seems like this package would have a nice way to give the model this range before hand, but I just can’t quite figure it out in the documentation/googling around.