def test_sample_posterior_predictive_after_set_data_with_coords(self): y = np.array([1.0, 2.0, 3.0]) with pm.Model() as model: x = pm.MutableData("x", [1.0, 2.0, 3.0], dims="obs_id") beta = pm.Normal("beta", 0, 10.0) pm.Normal("obs", beta * x, np.sqrt(1e-2), observed=y, dims="obs_id") idata = pm.sample( 10, tune=100, chains=1, return_inferencedata=True, compute_convergence_checks=False, ) # Predict on new data. with model: x_test = [5, 6] pm.set_data(new_data={"x": x_test}, coords={"obs_id": ["a", "b"]}) pm.sample_posterior_predictive(idata, extend_inferencedata=True, predictions=True) assert idata.predictions["obs"].shape == (1, 10, 2) assert np.all( idata.predictions["obs_id"].values == np.array(["a", "b"])) np.testing.assert_allclose(x_test, idata.predictions["obs"].mean( ("chain", "draw")), atol=1e-1)
def test_sample(self): x = np.random.normal(size=100) y = x + np.random.normal(scale=1e-2, size=100) x_pred = np.linspace(-3, 3, 200, dtype="float32") with pm.Model(): x_shared = pm.MutableData("x_shared", x) b = pm.Normal("b", 0.0, 10.0) pm.Normal("obs", b * x_shared, np.sqrt(1e-2), observed=y) prior_trace0 = pm.sample_prior_predictive(1000) idata = pm.sample(1000, tune=1000, chains=1) pp_trace0 = pm.sample_posterior_predictive(idata) x_shared.set_value(x_pred) prior_trace1 = pm.sample_prior_predictive(1000) pp_trace1 = pm.sample_posterior_predictive(idata) assert prior_trace0.prior["b"].shape == (1, 1000) assert prior_trace0.prior_predictive["obs"].shape == (1, 1000, 100) assert prior_trace1.prior_predictive["obs"].shape == (1, 1000, 200) assert pp_trace0.posterior_predictive["obs"].shape == (1, 1000, 100) np.testing.assert_allclose(x, pp_trace0.posterior_predictive["obs"].mean( ("chain", "draw")), atol=1e-1) assert pp_trace1.posterior_predictive["obs"].shape == (1, 1000, 200) np.testing.assert_allclose(x_pred, pp_trace1.posterior_predictive["obs"].mean( ("chain", "draw")), atol=1e-1)
def test_conversion_from_variables_subset(self): """This is a regression test for issue #5337.""" with pm.Model() as model: x = pm.Normal("x") pm.Normal("y", x, observed=5) idata = pm.sample( tune=10, draws=20, chains=1, step=pm.Metropolis(), compute_convergence_checks=False ) pm.sample_posterior_predictive(idata, var_names=["x"]) pm.sample_prior_predictive(var_names=["x"])
def test_potentials_warning(self): warning_msg = "The effect of Potentials on other parameters is ignored during" with pm.Model() as m: a = pm.Normal("a", 0, 1) p = pm.Potential("p", a + 1) obs = pm.Normal("obs", a, 1, observed=5) trace = az_from_dict({"a": np.random.rand(10)}) with m: with pytest.warns(UserWarning, match=warning_msg): pm.sample_posterior_predictive(trace, samples=5)
def test_chain_idx(): # see https://github.com/pymc-devs/pymc/issues/4469 with pm.Model(): mu = pm.Normal("mu") x = pm.Normal("x", mu=mu, sigma=1, observed=np.asarray(3)) # note draws-tune must be >100 AND we need an observed RV for this to properly # trigger convergence checks, which is one particular case in which this failed # before idata = pm.sample(draws=150, tune=10, chain_idx=1) ppc = pm.sample_posterior_predictive(idata) # TODO FIXME: Assert something. ppc = pm.sample_posterior_predictive(idata, keep_size=True)
def test_no_trace(self): with pm.Model() as model: x = pm.Data("x", [1.0, 2.0, 3.0]) y = pm.Data("y", [1.0, 2.0, 3.0]) beta = pm.Normal("beta", 0, 1) obs = pm.Normal("obs", x * beta, 1, observed=y) # pylint: disable=unused-variable idata = pm.sample(100, tune=100) prior = pm.sample_prior_predictive(return_inferencedata=False) posterior_predictive = pm.sample_posterior_predictive( idata, return_inferencedata=False) # Only prior inference_data = to_inference_data(prior=prior, model=model) test_dict = {"prior": ["beta"], "prior_predictive": ["obs"]} fails = check_multiple_attrs(test_dict, inference_data) assert not fails # Only posterior_predictive inference_data = to_inference_data( posterior_predictive=posterior_predictive, model=model) test_dict = {"posterior_predictive": ["obs"]} fails = check_multiple_attrs(test_dict, inference_data) assert not fails # Prior and posterior_predictive but no trace inference_data = to_inference_data( prior=prior, posterior_predictive=posterior_predictive, model=model) test_dict = { "prior": ["beta"], "prior_predictive": ["obs"], "posterior_predictive": ["obs"], } fails = check_multiple_attrs(test_dict, inference_data) assert not fails
def test_shared_data_as_index(self): """ Allow pm.Data to be used for index variables, i.e with integers as well as floats. See https://github.com/pymc-devs/pymc/issues/3813 """ with pm.Model() as model: index = pm.MutableData("index", [2, 0, 1, 0, 2]) y = pm.MutableData("y", [1.0, 2.0, 3.0, 2.0, 1.0]) alpha = pm.Normal("alpha", 0, 1.5, size=3) pm.Normal("obs", alpha[index], np.sqrt(1e-2), observed=y) prior_trace = pm.sample_prior_predictive(1000) idata = pm.sample( 1000, tune=1000, chains=1, compute_convergence_checks=False, ) # Predict on new data new_index = np.array([0, 1, 2]) new_y = [5.0, 6.0, 9.0] with model: pm.set_data(new_data={"index": new_index, "y": new_y}) pp_trace = pm.sample_posterior_predictive( idata, var_names=["alpha", "obs"]) assert prior_trace.prior["alpha"].shape == (1, 1000, 3) assert idata.posterior["alpha"].shape == (1, 1000, 3) assert pp_trace.posterior_predictive["alpha"].shape == (1, 1000, 3) assert pp_trace.posterior_predictive["obs"].shape == (1, 1000, 3)
def test_predictions_constant_data(self): with pm.Model(): x = pm.ConstantData("x", [1.0, 2.0, 3.0]) y = pm.MutableData("y", [1.0, 2.0, 3.0]) beta = pm.Normal("beta", 0, 1) obs = pm.Normal("obs", x * beta, 1, observed=y) # pylint: disable=unused-variable trace = pm.sample(100, tune=100, return_inferencedata=False) inference_data = to_inference_data(trace) test_dict = {"posterior": ["beta"], "observed_data": ["obs"], "constant_data": ["x"]} fails = check_multiple_attrs(test_dict, inference_data) assert not fails with pm.Model(): x = pm.MutableData("x", [1.0, 2.0]) y = pm.ConstantData("y", [1.0, 2.0]) beta = pm.Normal("beta", 0, 1) obs = pm.Normal("obs", x * beta, 1, observed=y) # pylint: disable=unused-variable predictive_trace = pm.sample_posterior_predictive( inference_data, return_inferencedata=False ) assert set(predictive_trace.keys()) == {"obs"} # this should be four chains of 100 samples # assert predictive_trace["obs"].shape == (400, 2) # but the shape seems to vary between pymc versions inference_data = predictions_to_inference_data(predictive_trace, posterior_trace=trace) test_dict = {"posterior": ["beta"], "~observed_data": ""} fails = check_multiple_attrs(test_dict, inference_data) assert not fails, "Posterior data not copied over as expected." test_dict = {"predictions": ["obs"]} fails = check_multiple_attrs(test_dict, inference_data) assert not fails, "Predictions not instantiated as expected." test_dict = {"predictions_constant_data": ["x"]} fails = check_multiple_attrs(test_dict, inference_data) assert not fails, "Predictions constant data not instantiated as expected."
def test_model_shared_variable(self): rng = np.random.RandomState(9832) x = rng.randn(100) y = x > 0 x_shared = aesara.shared(x) y_shared = aesara.shared(y) with pm.Model(rng_seeder=rng) as model: coeff = pm.Normal("x", mu=0, sd=1) logistic = pm.Deterministic("p", pm.math.sigmoid(coeff * x_shared)) obs = pm.Bernoulli("obs", p=logistic, observed=y_shared) trace = pm.sample(100, return_inferencedata=False, compute_convergence_checks=False) x_shared.set_value([-1, 0, 1.0]) y_shared.set_value([0, 0, 0]) samples = 100 with model: post_pred = pm.sample_posterior_predictive( trace, return_inferencedata=False, samples=samples, var_names=["p", "obs"] ) expected_p = np.array([logistic.eval({coeff: val}) for val in trace["x"][:samples]]) assert post_pred["obs"].shape == (samples, 3) npt.assert_allclose(post_pred["p"], expected_p)
def test_deterministic_of_observed_modified_interface(self): rng = np.random.RandomState(4982) meas_in_1 = pm.aesaraf.floatX(2 + 4 * rng.randn(100)) meas_in_2 = pm.aesaraf.floatX(5 + 4 * rng.randn(100)) with pm.Model(rng_seeder=rng) as model: mu_in_1 = pm.Normal("mu_in_1", 0, 1, initval=0) sigma_in_1 = pm.HalfNormal("sd_in_1", 1, initval=1) mu_in_2 = pm.Normal("mu_in_2", 0, 1, initval=0) sigma_in_2 = pm.HalfNormal("sd__in_2", 1, initval=1) in_1 = pm.Normal("in_1", mu_in_1, sigma_in_1, observed=meas_in_1) in_2 = pm.Normal("in_2", mu_in_2, sigma_in_2, observed=meas_in_2) out_diff = in_1 + in_2 pm.Deterministic("out", out_diff) trace = pm.sample( 100, return_inferencedata=False, compute_convergence_checks=False, ) varnames = [v for v in trace.varnames if v != "out"] ppc_trace = [ dict(zip(varnames, row)) for row in zip(*(trace.get_values(v) for v in varnames)) ] ppc = pm.sample_posterior_predictive( return_inferencedata=False, model=model, trace=ppc_trace, samples=len(ppc_trace), var_names=[x.name for x in (model.deterministics + model.basic_RVs)], ) rtol = 1e-5 if aesara.config.floatX == "float64" else 1e-3 npt.assert_allclose(ppc["in_1"] + ppc["in_2"], ppc["out"], rtol=rtol)
def test_sample_after_set_data(self): with pm.Model() as model: x = pm.MutableData("x", [1.0, 2.0, 3.0]) y = pm.MutableData("y", [1.0, 2.0, 3.0]) beta = pm.Normal("beta", 0, 10.0) pm.Normal("obs", beta * x, np.sqrt(1e-2), observed=y) pm.sample( 1000, tune=1000, chains=1, compute_convergence_checks=False, ) # Predict on new data. new_x = [5.0, 6.0, 9.0] new_y = [5.0, 6.0, 9.0] with model: pm.set_data(new_data={"x": new_x, "y": new_y}) new_idata = pm.sample( 1000, tune=1000, chains=1, compute_convergence_checks=False, ) pp_trace = pm.sample_posterior_predictive(new_idata) assert pp_trace.posterior_predictive["obs"].shape == (1, 1000, 3) np.testing.assert_allclose(new_y, pp_trace.posterior_predictive["obs"].mean( ("chain", "draw")), atol=1e-1)
def test_posterior_predictive_thinned(self, data): with data.model: draws = 20 thin_by = 4 idata = pm.sample(tune=5, draws=draws, chains=2, return_inferencedata=True) thinned_idata = idata.sel(draw=slice(None, None, thin_by)) idata.extend(pm.sample_posterior_predictive(thinned_idata)) test_dict = { "posterior": ["mu", "tau", "eta", "theta"], "sample_stats": ["diverging", "lp", "~log_likelihood"], "log_likelihood": ["obs"], "posterior_predictive": ["obs"], "observed_data": ["obs"], } fails = check_multiple_attrs(test_dict, idata) assert not fails assert idata.posterior.dims["chain"] == 2 assert idata.posterior.dims["draw"] == draws assert idata.posterior_predictive.dims["chain"] == 2 assert idata.posterior_predictive.dims["draw"] == draws / thin_by assert np.allclose(idata.posterior["draw"], np.arange(draws)) assert np.allclose(idata.posterior_predictive["draw"], np.arange(draws, step=thin_by))
def test_exceptions(self, caplog): with pm.Model() as model: mu = pm.Normal("mu", 0.0, 1.0) a = pm.Normal("a", mu=mu, sigma=1, observed=np.array([0.5, 0.2])) idata = pm.sample(idata_kwargs={"log_likelihood": False}) with model: with pytest.raises(IncorrectArgumentsError): ppc = pm.sample_posterior_predictive(idata, samples=10, keep_size=True) with pytest.raises(IncorrectArgumentsError): ppc = pm.sample_posterior_predictive(idata, size=4, keep_size=True) # test wrong type argument bad_trace = {"mu": stats.norm.rvs(size=1000)} with pytest.raises(TypeError): ppc = pm.sample_posterior_predictive(bad_trace)
def test_sample_posterior_predictive(self, tmpdir_factory): directory = str(tmpdir_factory.mktemp("data")) save_dir = pm.save_trace(self.trace, directory, overwrite=True) assert save_dir == directory rng = np.random.RandomState(10) with TestSaveLoad.model(rng_seeder=rng): ppc = pm.sample_posterior_predictive(self.trace) rng = np.random.RandomState(10) with TestSaveLoad.model(rng_seeder=rng): trace2 = pm.load_trace(directory) ppc2 = pm.sample_posterior_predictive(trace2) for key, value in ppc.items(): assert (value == ppc2[key]).all()
def test_variable_type(self): with pm.Model() as model: mu = pm.HalfNormal("mu", 1) a = pm.Normal("a", mu=mu, sigma=2, observed=np.array([1, 2])) b = pm.Poisson("b", mu, observed=np.array([1, 2])) trace = pm.sample(compute_convergence_checks=False, return_inferencedata=False) with model: ppc = pm.sample_posterior_predictive(trace, return_inferencedata=False, samples=1) assert ppc["a"].dtype.kind == "f" assert ppc["b"].dtype.kind == "i"
def test_sum_normal(self): with pm.Model() as model: a = pm.Normal("a", sigma=0.2) b = pm.Normal("b", mu=a) idata = pm.sample() with model: # test list input ppc0 = pm.sample_posterior_predictive( [model.initial_point], return_inferencedata=False, samples=10 ) assert ppc0 == {} ppc = pm.sample_posterior_predictive( idata, return_inferencedata=False, samples=1000, var_names=["b"] ) assert len(ppc) == 1 assert ppc["b"].shape == (1000,) scale = np.sqrt(1 + 0.2 ** 2) _, pval = stats.kstest(ppc["b"], stats.norm(scale=scale).cdf) assert pval > 0.001
def test_sample_prior_and_posterior(self): def build_toy_dataset(N, K): pi = np.array([0.2, 0.5, 0.3]) mus = [[1, 1, 1], [-1, -1, -1], [2, -2, 0]] stds = [[0.1, 0.1, 0.1], [0.1, 0.2, 0.2], [0.2, 0.3, 0.3]] x = np.zeros((N, 3), dtype=np.float32) y = np.zeros((N, ), dtype=np.int) for n in range(N): k = np.argmax(np.random.multinomial(1, pi)) x[n, :] = np.random.multivariate_normal( mus[k], np.diag(stds[k])) y[n] = k return x, y N = 100 # number of data points K = 3 # number of mixture components D = 3 # dimensionality of the data X, y = build_toy_dataset(N, K) with pm.Model() as model: pi = pm.Dirichlet("pi", np.ones(K), shape=(K, )) comp_dist = [] mu = [] packed_chol = [] chol = [] for i in range(K): mu.append(pm.Normal("mu%i" % i, 0, 10, shape=D)) packed_chol.append( pm.LKJCholeskyCov("chol_cov_%i" % i, eta=2, n=D, sd_dist=pm.HalfNormal.dist(2.5))) chol.append( pm.expand_packed_triangular(D, packed_chol[i], lower=True)) comp_dist.append( pm.MvNormal.dist(mu=mu[i], chol=chol[i], shape=D)) pm.Mixture("x_obs", pi, comp_dist, observed=X) with model: idata = pm.sample(30, tune=10, chains=1) n_samples = 20 with model: ppc = pm.sample_posterior_predictive(idata, n_samples) prior = pm.sample_prior_predictive(samples=n_samples) assert ppc["x_obs"].shape == (n_samples, ) + X.shape assert prior["x_obs"].shape == (n_samples, ) + X.shape assert prior["mu0"].shape == (n_samples, D) assert prior["chol_cov_0"].shape == (n_samples, D * (D + 1) // 2)
def test_model_not_drawable_prior(self): data = np.random.poisson(lam=10, size=200) model = pm.Model() with model: mu = pm.HalfFlat("sigma") pm.Poisson("foo", mu=mu, observed=data) idata = pm.sample(tune=1000) with model: with pytest.raises(NotImplementedError) as excinfo: pm.sample_prior_predictive(50) assert "Cannot sample" in str(excinfo.value) samples = pm.sample_posterior_predictive(idata, 40, return_inferencedata=False) assert samples["foo"].shape == (40, 200)
def test_vector_observed(self): with pm.Model() as model: mu = pm.Normal("mu", mu=0, sigma=1) a = pm.Normal("a", mu=mu, sigma=1, observed=np.array([0.0, 1.0])) idata = pm.sample(idata_kwargs={"log_likelihood": False}) with model: # test list input # ppc0 = pm.sample_posterior_predictive([model.initial_point], samples=10) # TODO: Assert something about the output # ppc = pm.sample_posterior_predictive(idata, samples=12, var_names=[]) # assert len(ppc) == 0 ppc = pm.sample_posterior_predictive( idata, return_inferencedata=False, samples=12, var_names=["a"] ) assert "a" in ppc assert ppc["a"].shape == (12, 2) ppc = pm.sample_posterior_predictive( idata, return_inferencedata=False, samples=10, var_names=["a"], size=4 ) assert "a" in ppc assert ppc["a"].shape == (10, 4, 2)
def test_sample_from_xarray_prior(self, point_list_arg_bug_fixture): pmodel, trace = point_list_arg_bug_fixture with pmodel: prior = pm.sample_prior_predictive( samples=20, return_inferencedata=False, ) idat = pm.to_inference_data(trace, prior=prior) with pmodel: pp = pm.sample_posterior_predictive( idat.prior, return_inferencedata=False, var_names=["d"] )
def make_predictions_inference_data( self, data, eight_schools_params ) -> Tuple[InferenceData, Dict[str, np.ndarray]]: with data.model: posterior_predictive = pm.sample_posterior_predictive( data.obj, keep_size=True, return_inferencedata=False ) idata = predictions_to_inference_data( posterior_predictive, posterior_trace=data.obj, coords={"school": np.arange(eight_schools_params["J"])}, dims={"theta": ["school"], "eta": ["school"]}, ) assert isinstance(idata, InferenceData) return idata, posterior_predictive
def test_posterior_predictive_warning(self, data, eight_schools_params, caplog): with data.model: posterior_predictive = pm.sample_posterior_predictive( data.obj, 370, return_inferencedata=False, keep_size=False ) with pytest.warns(UserWarning, match="shape of variables"): inference_data = to_inference_data( trace=data.obj, posterior_predictive=posterior_predictive, coords={"school": np.arange(eight_schools_params["J"])}, dims={"theta": ["school"], "eta": ["school"]}, ) shape = inference_data.posterior_predictive.obs.shape assert np.all([obs_s == s for obs_s, s in zip(shape, (1, 370, eight_schools_params["J"]))])
def get_inference_data(self, data, eight_schools_params): with data.model: prior = pm.sample_prior_predictive(return_inferencedata=False) posterior_predictive = pm.sample_posterior_predictive( data.obj, return_inferencedata=False ) return to_inference_data( trace=data.obj, prior=prior, posterior_predictive=posterior_predictive, coords={"school": np.arange(eight_schools_params["J"])}, dims={"theta": ["school"], "eta": ["school"]}, model=data.model, )
def test_normal_vector_idata(self, caplog): with pm.Model() as model: mu = pm.Normal("mu", 0.0, 1.0) a = pm.Normal("a", mu=mu, sigma=1, observed=np.array([0.5, 0.2])) trace = pm.sample(return_inferencedata=False) assert not isinstance(trace, InferenceData) with model: # test keep_size parameter with inference data as input... idata = pm.to_inference_data(trace) assert isinstance(idata, InferenceData) ppc = pm.sample_posterior_predictive(idata, return_inferencedata=False, keep_size=True) assert ppc["a"].shape == (trace.nchains, len(trace), 2)
def test_posterior_predictive_keep_size(self, data, chains, draws, eight_schools_params): with data.model: posterior_predictive = pm.sample_posterior_predictive( data.obj, keep_size=True, return_inferencedata=False ) inference_data = to_inference_data( trace=data.obj, posterior_predictive=posterior_predictive, coords={"school": np.arange(eight_schools_params["J"])}, dims={"theta": ["school"], "eta": ["school"]}, ) shape = inference_data.posterior_predictive.obs.shape assert np.all( [obs_s == s for obs_s, s in zip(shape, (chains, draws, eight_schools_params["J"]))] )
def test_multivariate2(self): # Added test for issue #3271 mn_data = np.random.multinomial(n=100, pvals=[1 / 6.0] * 6, size=10) with pm.Model() as dm_model: probs = pm.Dirichlet("probs", a=np.ones(6)) obs = pm.Multinomial("obs", n=100, p=probs, observed=mn_data) burned_trace = pm.sample( 20, tune=10, cores=1, return_inferencedata=False, compute_convergence_checks=False ) sim_priors = pm.sample_prior_predictive( return_inferencedata=False, samples=20, model=dm_model ) sim_ppc = pm.sample_posterior_predictive( burned_trace, return_inferencedata=False, samples=20, model=dm_model ) assert sim_priors["probs"].shape == (20, 6) assert sim_priors["obs"].shape == (20,) + mn_data.shape assert sim_ppc["obs"].shape == (20,) + mn_data.shape
def test_one_gaussian(self): assert self.count_rvs(self.SMABC_test.logpt) == 1 with self.SMABC_test: trace = pm.sample_smc(draws=1000, return_inferencedata=False) pr_p = pm.sample_prior_predictive(1000, return_inferencedata=False) po_p = pm.sample_posterior_predictive(trace, 1000, return_inferencedata=False) assert abs(self.data.mean() - trace["a"].mean()) < 0.05 assert abs(self.data.std() - trace["b"].mean()) < 0.05 assert pr_p["s"].shape == (1000, 1000) assert abs(0 - pr_p["s"].mean()) < 0.10 assert abs(1.4 - pr_p["s"].std()) < 0.10 assert po_p["s"].shape == (1000, 1000) assert abs(self.data.mean() - po_p["s"].mean()) < 0.10 assert abs(self.data.std() - po_p["s"].std()) < 0.10
def get_predictions_inference_data( self, data, eight_schools_params, inplace ) -> Tuple[InferenceData, Dict[str, np.ndarray]]: with data.model: prior = pm.sample_prior_predictive(return_inferencedata=False) posterior_predictive = pm.sample_posterior_predictive( data.obj, keep_size=True, return_inferencedata=False ) idata = to_inference_data( trace=data.obj, prior=prior, coords={"school": np.arange(eight_schools_params["J"])}, dims={"theta": ["school"], "eta": ["school"]}, ) assert isinstance(idata, InferenceData) extended = predictions_to_inference_data( posterior_predictive, idata_orig=idata, inplace=inplace ) assert isinstance(extended, InferenceData) assert (id(idata) == id(extended)) == inplace return (extended, posterior_predictive)
def test_normal_scalar_idata(self): nchains = 2 ndraws = 500 with pm.Model() as model: mu = pm.Normal("mu", 0.0, 1.0) a = pm.Normal("a", mu=mu, sigma=1, observed=0.0) trace = pm.sample( draws=ndraws, chains=nchains, return_inferencedata=False, discard_tuned_samples=False, ) assert not isinstance(trace, InferenceData) with model: # test keep_size parameter and idata input idata = pm.to_inference_data(trace) assert isinstance(idata, InferenceData) ppc = pm.sample_posterior_predictive(idata, keep_size=True, return_inferencedata=False) assert ppc["a"].shape == (nchains, ndraws)
def test_posterior_predictive_warning(self, data, eight_schools_params, caplog): with data.model: posterior_predictive = pm.sample_posterior_predictive( data.obj, 370, return_inferencedata=False) inference_data = to_inference_data( trace=data.obj, posterior_predictive=posterior_predictive, coords={"school": np.arange(eight_schools_params["J"])}, dims={ "theta": ["school"], "eta": ["school"] }, ) records = caplog.records shape = inference_data.posterior_predictive.obs.shape assert np.all([ obs_s == s for obs_s, s in zip(shape, (1, 370, eight_schools_params["J"])) ]) assert len(records) == 1 assert records[0].levelname == "WARNING"