Implementing a simple toy scenario with probabilistic reasoning in pymc

Also, in your case it is perfectly possible to have everything end to end in PyMC, the trick is to pad the “missing” greeting:

weather_prob = np.asarray([.2, .8])  # Sunny, Not sunny
greeting_prob = np.asarray([[.6, .4, 0.],   # <= notice how the missing greeting has 0 probability
                            [.2, 0., .8]])

with pm.Model() as m:
    observed = pm.Data('observed', 0, mutable=True)
    weather = pm.Categorical('weather', weather_prob)
    greeting = pm.Categorical('greeting', 
                              aesara.shared(greeting_prob)[weather], 
                              observed=observed)
    # Simulate today’s greeting based on the (prior) probability of seeing sunny weather
    prior_sample = pm.sample_prior_predictive(1000)

# Infer today’s weather based on an observed greeting
traces = []
for obs in range(3):
    with m:
        observed.set_value(obs)
        traces.append(pm.sample(initvals={'weather': max(0, obs-1)}))

You can see that the result is the same as indexing to the prior_predictive @jessegrabowski explained:

_, axes = plt.subplots(1, 2, figsize=(5, 5), sharey=True)
for i, trace in enumerate(traces):
    x, y = np.unique(trace.posterior['weather'], return_counts=True)
    axes[0].bar(x + (i-1) / 5, y/y.sum(), width=.2);
    x_, y_ = np.unique(
        prior_sample.prior['weather'].values[prior_sample.prior_predictive['greeting'].values == i],
        return_counts=True)
    axes[1].bar(x_ + (i-1) / 5, y_/y_.sum(), width=.2);
axes[0].legend([f'observed = {i}' for i in range(3)])

image