# Are samples from the trace equivalent to samples from pm.sample\_posterior\_predictive?

**URL:** <https://discourse.pymc.io/t/are-samples-from-the-trace-equivalent-to-samples-from-pm-sample-posterior-predictive/5991>\
**Category:** Questions\
**Created:** [October 15, 2020, 6:30am UTC](https://discourse.pymc.io/t/are-samples-from-the-trace-equivalent-to-samples-from-pm-sample-posterior-predictive/5991 "2020-10-15T06:30:28Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![lewiso1](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.pymc.io/lewiso1/32/2426_2.png) [@lewiso1](https://discourse.pymc.io/u/lewiso1)\
**Post date:** [October 15, 2020, 6:30am UTC](https://discourse.pymc.io/t/are-samples-from-the-trace-equivalent-to-samples-from-pm-sample-posterior-predictive/5991/1 "2020-10-15T06:30:28Z")

</div>

Hi PyMC3ers,

I’ve got a large number of models (one model fit on multiple datasets), and would rather not run `pm.sample_posterior_predictive` on each one in order to get samples.

Is it “OK” to just use the actual samples returned by `pm.sample` instead?

What I really want is the range of estimated parameters for a StudentT distribution, which I can then throw into a scipy.stats.t object to get to the `ppf` method. For example:

```auto
from scipy.stats import t 

trace = traces[15] #get the trace for the 15th model
mu = trace['mu'] #these are the values returned by pm.sample
nu = trace['nu'] #these are the values returned by pm.sample
scale = trace['sig'] #these are the values returned by pm.sample

studentT = t(nu,mu,sig) #get an array of t distributions parameterized by those samples above

#now find the ppf value for 0.4 for each of these t distributions:
ppf_values = studenT.ppf(0.4)

```

Thanks for your time!

---

<div class="post-metadata">

**Author:** ![AlexAndorra](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.pymc.io/alexandorra/32/9142_2.png) [@AlexAndorra](https://discourse.pymc.io/u/AlexAndorra)\
**Post date:** [October 15, 2020, 10:34am UTC](https://discourse.pymc.io/t/are-samples-from-the-trace-equivalent-to-samples-from-pm-sample-posterior-predictive/5991/2 "2020-10-15T10:34:40Z")

</div>

Hi Lewis,  
Yes, I don’t see any problem with this here – that’s basically what `pm.sample_posterior_predictive` does under the hood, and what you have to do when there is a bug (#ShapeIssue 😉) in it with a given distribution.  
Hope this helps 🖖

---

<div class="post-metadata">

**Author:** ![mattiasthalen](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.pymc.io/mattiasthalen/32/2362_2.png) [@mattiasthalen](https://discourse.pymc.io/u/mattiasthalen)\
**Post date:** [October 15, 2020, 7:35pm UTC](https://discourse.pymc.io/t/are-samples-from-the-trace-equivalent-to-samples-from-pm-sample-posterior-predictive/5991/3 "2020-10-15T19:35:36Z")

</div>

A related question. Why do we actually predict using sample\_posterior\_predictive instead of just manually calculate using all the samples parameters?

My guess is that using sample\_posterior\_predictive actually does a better prediction on values it can see in the trace. That would explain why I get a narrower HDI from sample\_posterior\_predictive than from “manually” calculating the values using the trace.

Am I completely off? 🙂

---

<div class="post-metadata">

**Author:** ![lewiso1](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.pymc.io/lewiso1/32/2426_2.png) [@lewiso1](https://discourse.pymc.io/u/lewiso1)\
**Post date:** [October 16, 2020, 2:51am UTC](https://discourse.pymc.io/t/are-samples-from-the-trace-equivalent-to-samples-from-pm-sample-posterior-predictive/5991/4 "2020-10-16T02:51:57Z")

</div>

Great thnx alex  
lew

---

<div class="post-metadata">

**Author:** ![lewiso1](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.pymc.io/lewiso1/32/2426_2.png) [@lewiso1](https://discourse.pymc.io/u/lewiso1)\
**Post date:** [October 16, 2020, 2:57am UTC](https://discourse.pymc.io/t/are-samples-from-the-trace-equivalent-to-samples-from-pm-sample-posterior-predictive/5991/5 "2020-10-16T02:57:48Z")

</div>

Hey Mattias - the naming doesn’t quite agree but I guess one reason to use `sample_posterior_predictive` over taking the actual samples is in [https://arxiv.org/pdf/1709.01449.pdf](https://arxiv.org/pdf/1709.01449.pdf) - sometimes you might define a model and, before doing any MCMC, draw some samples just from the priors to assess if they’re at least reasonable.

---

<div class="post-metadata">

**Author:** ![mattiasthalen](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.pymc.io/mattiasthalen/32/2362_2.png) [@mattiasthalen](https://discourse.pymc.io/u/mattiasthalen)\
**Post date:** [October 16, 2020, 3:36am UTC](https://discourse.pymc.io/t/are-samples-from-the-trace-equivalent-to-samples-from-pm-sample-posterior-predictive/5991/6 "2020-10-16T03:36:20Z")

</div>

I thought that was what sample\_prior\_predictive was meant for 🙂

---

<div class="post-metadata">

**Author:** ![AlexAndorra](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.pymc.io/alexandorra/32/9142_2.png) [@AlexAndorra](https://discourse.pymc.io/u/AlexAndorra)\
**Post date:** [October 16, 2020, 1:39pm UTC](https://discourse.pymc.io/t/are-samples-from-the-trace-equivalent-to-samples-from-pm-sample-posterior-predictive/5991/7 "2020-10-16T13:39:01Z")

</div>

> [@mattiasthalen](#):
>
> A related question. Why do we actually predict using sample\_posterior\_predictive instead of just manually calculate using all the samples parameters?

I’d say there are at least two reasons:

1. For convenience: just using this simple one-liner instead of having to basically rebuild the whole model by operating on the posterior samples – I’m much happier when PyMC3 does it for me automatically 😅
2. Although there are no conceptual difference when using `sample_posterior_predictive` to sample latent parameters, there is one when you sample _actual_ posterior predictive samples, aka predictions, aka new observations, aka new `y`s (this has a lot of names 😁). Then, `sample_posterior_predictive` allows you to integrate over all the uncertainty in the model – the one from the latent parameters, the one from the likelihood, and the one from correlations betwen all those parameters.
