Hello,
I’m new to PyMC and I’m trying to perform a simple task: fitting a linear model in a Bayesian way.
I’m a beginner to PyMC, so this is a naive question.
I’ve been studying the documentation and came across several examples like Example 1, Example 2, Example 3, Example 4.
While I’ve made progress, there are still some aspects that confuse me, especially regarding how to structure my model to allow for modifying observed data later for out-of-sample predictions using Coordinates and Mutable data. Let me explain:
I initially created my model following Example 1, which I understood. It looks like this:
with pm.Model() as linear_model_s_t:
# 1 Prior Knowledge:
#Intercept
intercept = pm.LogNormal('Intercept', mu=mu_B, sigma=std_B)
#Slope
slope = pm.LogNormal('Slope', mu=mu_A, sigma=std_A)
#Standard Deviation of the normal distribution Y~N(X,b,sigma**2)
sigma = pm.HalfNormal('sigma', sigma=10)
# 2 - Estimate the mean, that will be my Y
# Y = Ax + B ->
mu = slope * x_new + intercept
# 3 - Define Likelihood
y_obs = pm.Normal('y_obs', mu=mu, sigma=sigma, observed = y_new)
# 4 - Sampling
trace = pm.sample(2000, tune=2000,chains=4, cores=2, random_seed=rng)
# 5 - Generate prior and posterior samples
prior_pred = pm.sample_prior_predictive(samples=1000, random_seed=rng)
post_pred = pm.sample_posterior_predictive(trace,random_seed=rng)
Then I came across Example 2, which uses the “babies” dataset and seems more similar to what I intend to do. However, it raised some questions:
with pm.Model(
coords_mutable={"obs_idx": np.arange(len(data))}, coords={"parameter": ["intercept", "slope"]}
) as model_babies:
mean_params = pm.Normal("mean_params", sigma=10, dims=["parameter"])
sigma_params = pm.Normal("sigma_params", sigma=10, dims=["parameter"])
month = pm.MutableData("month", data.Month.values.astype(float), dims=["obs_idx"])
mu = pm.Deterministic("mu", mean_params[0] + mean_params[1] * month**0.5, dims=["obs_idx"])
sigma = pm.Deterministic("sigma", sigma_params[0] + sigma_params[1] * month, dims=["obs_idx"])
length = pm.Normal("length", mu=mu, sigma=sigma, observed=data.Length, dims=["obs_idx"])
idata_babies = pm.sample(random_seed=RANDOM_SEED)
- I understand that I set the mutable coordinates: ‘obs_idx’ and the ones that will not change: ‘parameter’. But I don’t understand how PyMC will know which parameter it is, e.g., mean_params = pm.Normal(“mean_params”, sigma=10, dims=[“parameter”]). How does it determine whether it is for ‘intercept’ or ‘slope’?
- I don’t understand the roles of mean_params and sigma_params. Based on mu, it seems they correspond to the slope and intercept.
- I don’t understand why there are two sigma parameters.
- How should I set the sigma values? I know they should be positive, so using a half-normal distribution is okay. But what about the specific value of sigma? I’ve set it to 10, but only because all the examples use 10. How can I correctly determine this value? I understand the sigma for the slope and intercept, but not for mu.