<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="../assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Austin Rochford (Posts about Nonparametric Statistics)</title><link>https://austinrochford.com/</link><description></description><atom:link href="https://austinrochford.com/tags/nonparametric-statistics.xml" rel="self" type="application/rss+xml"></atom:link><language>en</language><copyright>Contents © 2022 &lt;a href="mailto:austin.rochford@gmail.com"&gt;Austin Rochford&lt;/a&gt; </copyright><lastBuildDate>Mon, 17 Jan 2022 11:51:54 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>Dependent Density Regression with PyMC3</title><link>https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html</link><dc:creator>Austin Rochford</dc:creator><description>&lt;p&gt;My last &lt;a href="http://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html"&gt;post&lt;/a&gt; showed how to use Dirichlet processes and &lt;a href="http://pymc-devs.github.io/pymc3/"&gt;&lt;code&gt;pymc3&lt;/code&gt;&lt;/a&gt; to perform Bayesian nonparametric density estimation. This post expands on the previous one, illustrating dependent density regression with &lt;code&gt;pymc3&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Just as Dirichlet process mixtures can be thought of as infinite mixture models that select the number of active components as part of inference, dependent density regression can be thought of as infinite &lt;a href="https://en.wikipedia.org/wiki/Committee_machine"&gt;mixtures of experts&lt;/a&gt; that select the active experts as part of inference. Their flexibility and modularity make them powerful tools for performing nonparametric Bayesian Data analysis.&lt;/p&gt;
&lt;div class="sourceCode" id="cb1"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb1-1"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb1-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;%&lt;/span&gt;matplotlib inline&lt;/span&gt;
&lt;span id="cb1-2"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb1-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="im"&gt;from&lt;/span&gt; IPython.display &lt;span class="im"&gt;import&lt;/span&gt; HTML&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="sourceCode" id="cb2"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb2-1"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb2-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="im"&gt;from&lt;/span&gt; matplotlib &lt;span class="im"&gt;import&lt;/span&gt; animation &lt;span class="im"&gt;as&lt;/span&gt; ani, pyplot &lt;span class="im"&gt;as&lt;/span&gt; plt&lt;/span&gt;
&lt;span id="cb2-2"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb2-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="im"&gt;import&lt;/span&gt; numpy &lt;span class="im"&gt;as&lt;/span&gt; np&lt;/span&gt;
&lt;span id="cb2-3"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb2-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="im"&gt;import&lt;/span&gt; pandas &lt;span class="im"&gt;as&lt;/span&gt; pd&lt;/span&gt;
&lt;span id="cb2-4"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb2-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="im"&gt;import&lt;/span&gt; pymc3 &lt;span class="im"&gt;as&lt;/span&gt; pm&lt;/span&gt;
&lt;span id="cb2-5"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb2-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="im"&gt;import&lt;/span&gt; seaborn &lt;span class="im"&gt;as&lt;/span&gt; sns&lt;/span&gt;
&lt;span id="cb2-6"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb2-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="im"&gt;from&lt;/span&gt; theano &lt;span class="im"&gt;import&lt;/span&gt; shared, tensor &lt;span class="im"&gt;as&lt;/span&gt; tt&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="sourceCode" id="cb3"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb3-1"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb3-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;plt.rc(&lt;span class="st"&gt;'animation'&lt;/span&gt;, writer&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'avconv'&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb3-2"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb3-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;blue, &lt;span class="op"&gt;*&lt;/span&gt;_ &lt;span class="op"&gt;=&lt;/span&gt; sns.color_palette()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="sourceCode" id="cb4"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb4-1"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb4-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;SEED &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dv"&gt;972915&lt;/span&gt; &lt;span class="co"&gt;# from random.org; for reproducibility&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-2"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb4-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;np.random.seed(SEED)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Throughout this post, we will use the LIDAR data set from Larry Wasserman’s excellent book, &lt;a href="http://www.stat.cmu.edu/~larry/all-of-nonpar/"&gt;&lt;em&gt;All of Nonparametric Statistics&lt;/em&gt;&lt;/a&gt;. We standardize the data set to improve the rate of convergence of our samples.&lt;/p&gt;
&lt;div class="sourceCode" id="cb5"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb5-1"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb5-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;DATA_URI &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="st"&gt;'http://www.stat.cmu.edu/~larry/all-of-nonpar/=data/lidar.dat'&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb5-2"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb5-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb5-3"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb5-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;def&lt;/span&gt; standardize(x):&lt;/span&gt;
&lt;span id="cb5-4"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb5-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="cf"&gt;return&lt;/span&gt; (x &lt;span class="op"&gt;-&lt;/span&gt; x.mean()) &lt;span class="op"&gt;/&lt;/span&gt; x.std()&lt;/span&gt;
&lt;span id="cb5-5"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb5-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb5-6"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb5-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;df &lt;span class="op"&gt;=&lt;/span&gt; (pd.read_csv(DATA_URI, sep&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;' *'&lt;/span&gt;, engine&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'python'&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb5-7"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb5-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        .assign(std_range&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="kw"&gt;lambda&lt;/span&gt; df: standardize(df.&lt;span class="bu"&gt;range&lt;/span&gt;),&lt;/span&gt;
&lt;span id="cb5-8"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb5-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;                std_logratio&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="kw"&gt;lambda&lt;/span&gt; df: standardize(df.logratio)))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="sourceCode" id="cb6"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb6-1"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb6-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;df.head()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;center&gt;
&lt;div&gt;
&lt;table border="1" class="dataframe"&gt;
&lt;thead&gt;
&lt;tr style="text-align: right;"&gt;
&lt;th&gt;
&lt;/th&gt;
&lt;th&gt;
range
&lt;/th&gt;
&lt;th&gt;
logratio
&lt;/th&gt;
&lt;th&gt;
std_logratio
&lt;/th&gt;
&lt;th&gt;
std_range
&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;
0
&lt;/th&gt;
&lt;td&gt;
390
&lt;/td&gt;
&lt;td&gt;
-0.050356
&lt;/td&gt;
&lt;td&gt;
0.852467
&lt;/td&gt;
&lt;td&gt;
-1.717725
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;
1
&lt;/th&gt;
&lt;td&gt;
391
&lt;/td&gt;
&lt;td&gt;
-0.060097
&lt;/td&gt;
&lt;td&gt;
0.817981
&lt;/td&gt;
&lt;td&gt;
-1.707299
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;
2
&lt;/th&gt;
&lt;td&gt;
393
&lt;/td&gt;
&lt;td&gt;
-0.041901
&lt;/td&gt;
&lt;td&gt;
0.882398
&lt;/td&gt;
&lt;td&gt;
-1.686447
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;
3
&lt;/th&gt;
&lt;td&gt;
394
&lt;/td&gt;
&lt;td&gt;
-0.050985
&lt;/td&gt;
&lt;td&gt;
0.850240
&lt;/td&gt;
&lt;td&gt;
-1.676020
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;
4
&lt;/th&gt;
&lt;td&gt;
396
&lt;/td&gt;
&lt;td&gt;
-0.059913
&lt;/td&gt;
&lt;td&gt;
0.818631
&lt;/td&gt;
&lt;td&gt;
-1.655168
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/center&gt;
&lt;p&gt;We plot the LIDAR data below.&lt;/p&gt;
&lt;div class="sourceCode" id="cb7"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb7-1"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb7-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;fig, ax &lt;span class="op"&gt;=&lt;/span&gt; plt.subplots(figsize&lt;span class="op"&gt;=&lt;/span&gt;(&lt;span class="dv"&gt;8&lt;/span&gt;, &lt;span class="dv"&gt;6&lt;/span&gt;))&lt;/span&gt;
&lt;span id="cb7-2"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb7-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb7-3"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb7-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.scatter(df.std_range, df.std_logratio,&lt;/span&gt;
&lt;span id="cb7-4"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb7-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;           c&lt;span class="op"&gt;=&lt;/span&gt;blue)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-5"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb7-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb7-6"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb7-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.set_xticklabels([])&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-7"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb7-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.set_xlabel(&lt;span class="st"&gt;"Standardized range"&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-8"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb7-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb7-9"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb7-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.set_yticklabels([])&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-10"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb7-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.set_ylabel(&lt;span class="st"&gt;"Standardized log ratio"&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;center&gt;
&lt;img src="https://austinrochford.com/resources/ddp/Dependent%20Density%20Regression%20with%20PyMC3_10_0.png" title="fig:" alt="png"&gt;
&lt;/center&gt;
&lt;p&gt;This data set has a two interesting properties that make it useful for illustrating dependent density regression.&lt;/p&gt;
&lt;ol type="1"&gt;
&lt;li&gt;The relationship between range and log ratio is nonlinear, but has locally linear components.&lt;/li&gt;
&lt;li&gt;The observation noise is &lt;a href="https://en.wikipedia.org/wiki/Heteroscedasticity"&gt;heteroskedastic&lt;/a&gt;; that is, the magnitude of the variance varies with the range.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The intuitive idea behind dependent density regression is to reduce the problem to many (related) density estimates, conditioned on fixed values of the predictors. The following animation illustrates this intuition.&lt;/p&gt;
&lt;div class="sourceCode" id="cb8"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb8-1"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;fig, (scatter_ax, hist_ax) &lt;span class="op"&gt;=&lt;/span&gt; plt.subplots(ncols&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;2&lt;/span&gt;, figsize&lt;span class="op"&gt;=&lt;/span&gt;(&lt;span class="dv"&gt;16&lt;/span&gt;, &lt;span class="dv"&gt;6&lt;/span&gt;))&lt;/span&gt;
&lt;span id="cb8-2"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb8-3"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;scatter_ax.scatter(df.std_range, df.std_logratio,&lt;/span&gt;
&lt;span id="cb8-4"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;                   c&lt;span class="op"&gt;=&lt;/span&gt;blue, zorder&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;2&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-5"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb8-6"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;scatter_ax.set_xticklabels([])&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-7"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;scatter_ax.set_xlabel(&lt;span class="st"&gt;"Standardized range"&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-8"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb8-9"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;scatter_ax.set_yticklabels([])&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-10"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;scatter_ax.set_ylabel(&lt;span class="st"&gt;"Standardized log ratio"&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-11"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb8-12"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;bins &lt;span class="op"&gt;=&lt;/span&gt; np.linspace(df.std_range.&lt;span class="bu"&gt;min&lt;/span&gt;(), df.std_range.&lt;span class="bu"&gt;max&lt;/span&gt;(), &lt;span class="dv"&gt;25&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb8-13"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb8-14"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;hist_ax.hist(df.std_logratio, bins&lt;span class="op"&gt;=&lt;/span&gt;bins,&lt;/span&gt;
&lt;span id="cb8-15"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;             color&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'k'&lt;/span&gt;, lw&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;0&lt;/span&gt;, alpha&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="fl"&gt;0.25&lt;/span&gt;,&lt;/span&gt;
&lt;span id="cb8-16"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;             label&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;"All data"&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-17"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-17" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb8-18"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-18" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;hist_ax.set_xticklabels([])&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-19"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-19" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;hist_ax.set_xlabel(&lt;span class="st"&gt;"Standardized log ratio"&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-20"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-20" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb8-21"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-21" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;hist_ax.set_yticklabels([])&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-22"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-22" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;hist_ax.set_ylabel(&lt;span class="st"&gt;"Frequency"&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-23"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-23" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb8-24"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-24" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;hist_ax.legend(loc&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;2&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-25"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-25" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb8-26"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-26" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;endpoints &lt;span class="op"&gt;=&lt;/span&gt; np.linspace(&lt;span class="fl"&gt;1.05&lt;/span&gt; &lt;span class="op"&gt;*&lt;/span&gt; df.std_range.&lt;span class="bu"&gt;min&lt;/span&gt;(), &lt;span class="fl"&gt;1.05&lt;/span&gt; &lt;span class="op"&gt;*&lt;/span&gt; df.std_range.&lt;span class="bu"&gt;max&lt;/span&gt;(), &lt;span class="dv"&gt;15&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb8-27"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-27" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb8-28"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-28" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;frame_artists &lt;span class="op"&gt;=&lt;/span&gt; []&lt;/span&gt;
&lt;span id="cb8-29"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-29" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb8-30"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-30" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="cf"&gt;for&lt;/span&gt; low, high &lt;span class="kw"&gt;in&lt;/span&gt; &lt;span class="bu"&gt;zip&lt;/span&gt;(endpoints[:&lt;span class="op"&gt;-&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;], endpoints[&lt;span class="dv"&gt;2&lt;/span&gt;:]):&lt;/span&gt;
&lt;span id="cb8-31"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-31" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    interval &lt;span class="op"&gt;=&lt;/span&gt; scatter_ax.axvspan(low, high,&lt;/span&gt;
&lt;span id="cb8-32"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-32" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;                                  color&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'k'&lt;/span&gt;, alpha&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="fl"&gt;0.5&lt;/span&gt;, lw&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;0&lt;/span&gt;, zorder&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-33"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-33" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="op"&gt;*&lt;/span&gt;_, bars &lt;span class="op"&gt;=&lt;/span&gt; hist_ax.hist(df[df.std_range.between(low, high)].std_logratio,&lt;/span&gt;
&lt;span id="cb8-34"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-34" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;                            bins&lt;span class="op"&gt;=&lt;/span&gt;bins,&lt;/span&gt;
&lt;span id="cb8-35"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-35" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;                            color&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'k'&lt;/span&gt;, lw&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;0&lt;/span&gt;, alpha&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="fl"&gt;0.5&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-36"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-36" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id="cb8-37"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-37" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    frame_artists.append((interval,) &lt;span class="op"&gt;+&lt;/span&gt; &lt;span class="bu"&gt;tuple&lt;/span&gt;(bars))&lt;/span&gt;
&lt;span id="cb8-38"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-38" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id="cb8-39"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-39" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;animation &lt;span class="op"&gt;=&lt;/span&gt; ani.ArtistAnimation(fig, frame_artists,&lt;/span&gt;
&lt;span id="cb8-40"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-40" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;                                interval&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;500&lt;/span&gt;, repeat_delay&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;3000&lt;/span&gt;, blit&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="va"&gt;True&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb8-41"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb8-41" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;plt.close()&lt;span class="op"&gt;;&lt;/span&gt; &lt;span class="co"&gt;# prevent the intermediate figure from showing&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="sourceCode" id="cb9"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb9-1"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb9-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;HTML(animation.to_html5_video())&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;center&gt;
&lt;video width="1152.0" height="432.0" controls autoplay loop&gt;
&lt;source type="video/mp4" src="data:video/mp4;base64,AAAAHGZ0eXBNNFYgAAACAGlzb21pc28yYXZjMQAAAAhmcmVlAACJGm1kYXQAAAKtBgX//6ncRem9%0A5tlIt5Ys2CDZI+7veDI2NCAtIGNvcmUgMTQyIHIyNDMxIGE1ODMxYWEgLSBILjI2NC9NUEVHLTQg%0AQVZDIGNvZGVjIC0gQ29weWxlZnQgMjAwMy0yMDE0IC0gaHR0cDovL3d3dy52aWRlb2xhbi5vcmcv%0AeDI2NC5odG1sIC0gb3B0aW9uczogY2FiYWM9MSByZWY9MyBkZWJsb2NrPTE6MDowIGFuYWx5c2U9%0AMHgzOjB4MTEzIG1lPWhleCBzdWJtZT03IHBzeT0xIHBzeV9yZD0xLjAwOjAuMDAgbWl4ZWRfcmVm%0APTEgbWVfcmFuZ2U9MTYgY2hyb21hX21lPTEgdHJlbGxpcz0xIDh4OGRjdD0xIGNxbT0wIGRlYWR6%0Ab25lPTIxLDExIGZhc3RfcHNraXA9MSBjaHJvbWFfcXBfb2Zmc2V0PS0yIHRocmVhZHM9NiBsb29r%0AYWhlYWRfdGhyZWFkcz0xIHNsaWNlZF90aHJlYWRzPTAgbnI9MCBkZWNpbWF0ZT0xIGludGVybGFj%0AZWQ9MCBibHVyYXlfY29tcGF0PTAgY29uc3RyYWluZWRfaW50cmE9MCBiZnJhbWVzPTMgYl9weXJh%0AbWlkPTIgYl9hZGFwdD0xIGJfYmlhcz0wIGRpcmVjdD0xIHdlaWdodGI9MSBvcGVuX2dvcD0wIHdl%0AaWdodHA9MiBrZXlpbnQ9MjUwIGtleWludF9taW49MiBzY2VuZWN1dD00MCBpbnRyYV9yZWZyZXNo%0APTAgcmNfbG9va2FoZWFkPTQwIHJjPWNyZiBtYnRyZWU9MSBjcmY9MjMuMCBxY29tcD0wLjYwIHFw%0AbWluPTAgcXBtYXg9NjkgcXBzdGVwPTQgaXBfcmF0aW89MS40MCBhcT0xOjEuMDAAgAAARYZliIQA%0AFv/+99M/zLLr9zm146j3op4mX0N1JQGblsTtOoAAAAMAAAMAAAMAAAVxrHCOXEcOH+g8AAADAAAf%0AtmP/5HfCYD2/am4z+cOi0BO5NXHTmyxvtuMETV0y5mpPX9kBp1jyjRbSjYoZNLzrgb8Goz3DHr8f%0ADj7VXyKAIKKpoxj3IFVoyR0Txq6MryDF4qh79mNHRsmm3OiNGtCiiRu+umfD6+7m+YL6wCyGoSmR%0A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%0Ab28AAAAaZGF0YQAAAAEAAAAATGF2ZjU2LjEuMA=="&gt;
Your browser does not support the video tag. &lt;/source&gt;&lt;/video&gt;
&lt;/center&gt;
&lt;p&gt;As we slice the data with a window sliding along the x-axis in the left plot, the empirical distribution of the y-values of the points in the window varies in the right plot. An important aspect of this approach is that the density estimates that correspond to close values of the predictor are similar.&lt;/p&gt;
&lt;p&gt;In the previous post, we saw that a Dirichlet process estimates a probability density as a mixture model with infinitely many components. In the case of normal component distributions,&lt;/p&gt;
&lt;p&gt;&lt;span class="math display"&gt;\[
y \sim \sum_{i = 1}^{\infty} w_i \cdot N(\mu_i, \tau_i^{-1}),
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;where the mixture weights, &lt;span class="math inline"&gt;\(w_1, w_2, \ldots\)&lt;/span&gt;, are generated by a &lt;a href="https://en.wikipedia.org/wiki/Dirichlet_process#The_stick-breaking_process"&gt;stick-breaking process&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Dependent density regression generalizes this representation of the Dirichlet process mixture model by allowing the mixture weights and component means to vary conditioned on the value of the predictor, &lt;span class="math inline"&gt;\(x\)&lt;/span&gt;. That is,&lt;/p&gt;
&lt;p&gt;&lt;span class="math display"&gt;\[
y\ |\ x \sim \sum_{i = 1}^{\infty} w_i\ |\ x \cdot N(\mu_i\ |\ x, \tau_i^{-1}).
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;In this post, we will follow Chapter 23 of &lt;a href="http://www.stat.columbia.edu/~gelman/book/"&gt;&lt;em&gt;Bayesian Data Analysis&lt;/em&gt;&lt;/a&gt; and use a probit stick-breaking process to determine the conditional mixture weights, &lt;span class="math inline"&gt;\(w_i\ |\ x\)&lt;/span&gt;. The probit stick-breaking process starts by defining&lt;/p&gt;
&lt;p&gt;&lt;span class="math display"&gt;\[
v_i\ |\ x = \Phi(\alpha_i + \beta_i x),
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;where &lt;span class="math inline"&gt;\(\Phi\)&lt;/span&gt; is the cumulative distribution function of the standard normal distribution. We then obtain &lt;span class="math inline"&gt;\(w_i\ |\ x\)&lt;/span&gt; by applying the stick breaking process to &lt;span class="math inline"&gt;\(v_i\ |\ x\)&lt;/span&gt;. That is,&lt;/p&gt;
&lt;p&gt;&lt;span class="math display"&gt;\[
w_i\ |\ x = v_i\ |\ x \cdot \prod_{j = 1}^{i - 1} (1 - v_j\ |\ x).
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;For the LIDAR data set, we use independent normal priors &lt;span class="math inline"&gt;\(\alpha_i \sim N(0, 5^2)\)&lt;/span&gt; and &lt;span class="math inline"&gt;\(\beta_i \sim N(0, 5^2)\)&lt;/span&gt;. We now express this this model for the conditional mixture weights using &lt;code&gt;pymc3&lt;/code&gt;.&lt;/p&gt;
&lt;div class="sourceCode" id="cb10"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb10-1"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb10-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;def&lt;/span&gt; norm_cdf(z):&lt;/span&gt;
&lt;span id="cb10-2"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb10-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="cf"&gt;return&lt;/span&gt; &lt;span class="fl"&gt;0.5&lt;/span&gt; &lt;span class="op"&gt;*&lt;/span&gt; (&lt;span class="dv"&gt;1&lt;/span&gt; &lt;span class="op"&gt;+&lt;/span&gt; tt.erf(z &lt;span class="op"&gt;/&lt;/span&gt; np.sqrt(&lt;span class="dv"&gt;2&lt;/span&gt;)))&lt;/span&gt;
&lt;span id="cb10-3"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb10-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb10-4"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb10-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;def&lt;/span&gt; stick_breaking(v):&lt;/span&gt;
&lt;span id="cb10-5"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb10-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="cf"&gt;return&lt;/span&gt; v &lt;span class="op"&gt;*&lt;/span&gt; tt.concatenate([tt.ones_like(v[:, :&lt;span class="dv"&gt;1&lt;/span&gt;]),&lt;/span&gt;
&lt;span id="cb10-6"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb10-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;                               tt.extra_ops.cumprod(&lt;span class="dv"&gt;1&lt;/span&gt; &lt;span class="op"&gt;-&lt;/span&gt; v, axis&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;)[:, :&lt;span class="op"&gt;-&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;]],&lt;/span&gt;
&lt;span id="cb10-7"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb10-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;                              axis&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="sourceCode" id="cb11"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb11-1"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb11-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;N, _ &lt;span class="op"&gt;=&lt;/span&gt; df.shape&lt;/span&gt;
&lt;span id="cb11-2"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb11-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;K &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dv"&gt;20&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-3"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb11-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb11-4"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb11-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;std_range &lt;span class="op"&gt;=&lt;/span&gt; df.std_range.values[:, np.newaxis]&lt;/span&gt;
&lt;span id="cb11-5"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb11-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;std_logratio &lt;span class="op"&gt;=&lt;/span&gt; df.std_logratio.values[:, np.newaxis]&lt;/span&gt;
&lt;span id="cb11-6"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb11-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb11-7"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb11-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;x_lidar &lt;span class="op"&gt;=&lt;/span&gt; shared(std_range, broadcastable&lt;span class="op"&gt;=&lt;/span&gt;(&lt;span class="va"&gt;False&lt;/span&gt;, &lt;span class="va"&gt;True&lt;/span&gt;))&lt;/span&gt;
&lt;span id="cb11-8"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb11-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb11-9"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb11-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="cf"&gt;with&lt;/span&gt; pm.Model() &lt;span class="im"&gt;as&lt;/span&gt; model:&lt;/span&gt;
&lt;span id="cb11-10"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb11-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    alpha &lt;span class="op"&gt;=&lt;/span&gt; pm.Normal(&lt;span class="st"&gt;'alpha'&lt;/span&gt;, &lt;span class="fl"&gt;0.&lt;/span&gt;, &lt;span class="fl"&gt;5.&lt;/span&gt;, shape&lt;span class="op"&gt;=&lt;/span&gt;K)&lt;/span&gt;
&lt;span id="cb11-11"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb11-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    beta &lt;span class="op"&gt;=&lt;/span&gt; pm.Normal(&lt;span class="st"&gt;'beta'&lt;/span&gt;, &lt;span class="fl"&gt;0.&lt;/span&gt;, &lt;span class="fl"&gt;5.&lt;/span&gt;, shape&lt;span class="op"&gt;=&lt;/span&gt;K)&lt;/span&gt;
&lt;span id="cb11-12"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb11-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    v &lt;span class="op"&gt;=&lt;/span&gt; norm_cdf(alpha &lt;span class="op"&gt;+&lt;/span&gt; beta &lt;span class="op"&gt;*&lt;/span&gt; x_lidar)&lt;/span&gt;
&lt;span id="cb11-13"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb11-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    w &lt;span class="op"&gt;=&lt;/span&gt; pm.Deterministic(&lt;span class="st"&gt;'w'&lt;/span&gt;, stick_breaking(v))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We have defined &lt;code&gt;x_lidar&lt;/code&gt; as a &lt;code&gt;theano&lt;/code&gt; &lt;a href="http://deeplearning.net/software/theano/library/compile/shared.html"&gt;&lt;code&gt;shared&lt;/code&gt;&lt;/a&gt; variable in order to use &lt;code&gt;pymc3&lt;/code&gt;’s posterior prediction capabilities later.&lt;/p&gt;
&lt;p&gt;While the dependent density regression model theoretically has infinitely many components, we must truncate the model to finitely many components (in this case, twenty) in order to express it using &lt;code&gt;pymc3&lt;/code&gt;. After sampling from the model, we will verify that truncation did not unduly influence our results.&lt;/p&gt;
&lt;p&gt;Since the LIDAR data seems to have several linear components, we use the linear models&lt;/p&gt;
&lt;p&gt;&lt;span class="math display"&gt;\[
\begin{align*}
\mu_i\ |\ x
    &amp;amp; \sim \gamma_i + \delta_i x \\
\gamma_i
    &amp;amp; \sim N(0, 10^2) \\
\delta_i
    &amp;amp; \sim N(0, 10^2)
\end{align*}
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;for the conditional component means.&lt;/p&gt;
&lt;div class="sourceCode" id="cb12"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb12-1"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb12-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="cf"&gt;with&lt;/span&gt; model:&lt;/span&gt;
&lt;span id="cb12-2"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb12-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    gamma &lt;span class="op"&gt;=&lt;/span&gt; pm.Normal(&lt;span class="st"&gt;'gamma'&lt;/span&gt;, &lt;span class="fl"&gt;0.&lt;/span&gt;, &lt;span class="fl"&gt;10.&lt;/span&gt;, shape&lt;span class="op"&gt;=&lt;/span&gt;K)&lt;/span&gt;
&lt;span id="cb12-3"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb12-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    delta &lt;span class="op"&gt;=&lt;/span&gt; pm.Normal(&lt;span class="st"&gt;'delta'&lt;/span&gt;, &lt;span class="fl"&gt;0.&lt;/span&gt;, &lt;span class="fl"&gt;10.&lt;/span&gt;, shape&lt;span class="op"&gt;=&lt;/span&gt;K)&lt;/span&gt;
&lt;span id="cb12-4"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb12-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    mu &lt;span class="op"&gt;=&lt;/span&gt; pm.Deterministic(&lt;span class="st"&gt;'mu'&lt;/span&gt;, gamma &lt;span class="op"&gt;+&lt;/span&gt; delta &lt;span class="op"&gt;*&lt;/span&gt; x_lidar)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Finally, we place the prior &lt;span class="math inline"&gt;\(\tau_i \sim \textrm{Gamma}(1, 1)\)&lt;/span&gt; on the component precisions.&lt;/p&gt;
&lt;div class="sourceCode" id="cb13"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb13-1"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb13-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="cf"&gt;with&lt;/span&gt; model:&lt;/span&gt;
&lt;span id="cb13-2"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb13-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    tau &lt;span class="op"&gt;=&lt;/span&gt; pm.Gamma(&lt;span class="st"&gt;'tau'&lt;/span&gt;, &lt;span class="fl"&gt;1.&lt;/span&gt;, &lt;span class="fl"&gt;1.&lt;/span&gt;, shape&lt;span class="op"&gt;=&lt;/span&gt;K)&lt;/span&gt;
&lt;span id="cb13-3"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb13-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    obs &lt;span class="op"&gt;=&lt;/span&gt; pm.NormalMixture(&lt;span class="st"&gt;'obs'&lt;/span&gt;, w, mu, tau&lt;span class="op"&gt;=&lt;/span&gt;tau, observed&lt;span class="op"&gt;=&lt;/span&gt;std_logratio)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We now draw sample from the dependent density regression model.&lt;/p&gt;
&lt;div class="sourceCode" id="cb14"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb14-1"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb14-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;SAMPLES &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dv"&gt;20000&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-2"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb14-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;BURN &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dv"&gt;10000&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-3"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb14-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;THIN &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dv"&gt;10&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-4"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb14-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb14-5"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb14-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="cf"&gt;with&lt;/span&gt; model:&lt;/span&gt;
&lt;span id="cb14-6"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb14-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    step &lt;span class="op"&gt;=&lt;/span&gt; pm.Metropolis()&lt;/span&gt;
&lt;span id="cb14-7"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb14-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    trace_ &lt;span class="op"&gt;=&lt;/span&gt; pm.sample(SAMPLES, step, random_seed&lt;span class="op"&gt;=&lt;/span&gt;SEED)&lt;/span&gt;
&lt;span id="cb14-8"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb14-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id="cb14-9"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb14-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;trace &lt;span class="op"&gt;=&lt;/span&gt; trace_[BURN::THIN]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;100%|██████████| 20000/20000 [01:30&amp;lt;00:00, 204.48it/s]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To verify that truncation did not unduly influence our results, we plot the largest posterior expected mixture weight for each component. (In this model, each point has a mixture weight for each component, so we plot the maximum mixture weight for each component across all data points in order to judge if the component exerts any influence on the posterior.)&lt;/p&gt;
&lt;div class="sourceCode" id="cb16"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb16-1"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb16-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;fig, ax &lt;span class="op"&gt;=&lt;/span&gt; plt.subplots(figsize&lt;span class="op"&gt;=&lt;/span&gt;(&lt;span class="dv"&gt;8&lt;/span&gt;, &lt;span class="dv"&gt;6&lt;/span&gt;))&lt;/span&gt;
&lt;span id="cb16-2"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb16-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb16-3"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb16-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.bar(np.arange(K) &lt;span class="op"&gt;+&lt;/span&gt; &lt;span class="dv"&gt;1&lt;/span&gt; &lt;span class="op"&gt;-&lt;/span&gt; &lt;span class="fl"&gt;0.4&lt;/span&gt;,&lt;/span&gt;
&lt;span id="cb16-4"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb16-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;       trace[&lt;span class="st"&gt;'w'&lt;/span&gt;].mean(axis&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;0&lt;/span&gt;).&lt;span class="bu"&gt;max&lt;/span&gt;(axis&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;0&lt;/span&gt;))&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb16-5"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb16-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb16-6"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb16-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.set_xlim(&lt;span class="dv"&gt;1&lt;/span&gt; &lt;span class="op"&gt;-&lt;/span&gt; &lt;span class="fl"&gt;0.5&lt;/span&gt;, K &lt;span class="op"&gt;+&lt;/span&gt; &lt;span class="fl"&gt;0.5&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb16-7"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb16-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.set_xlabel(&lt;span class="st"&gt;'Mixture component'&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb16-8"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb16-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb16-9"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb16-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.set_ylabel(&lt;span class="st"&gt;'Largest posterior expected&lt;/span&gt;&lt;span class="ch"&gt;\n&lt;/span&gt;&lt;span class="st"&gt;mixture weight'&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;center&gt;
&lt;img src="https://austinrochford.com/resources/ddp/Dependent%20Density%20Regression%20with%20PyMC3_24_0.png" title="fig:" alt="png"&gt;
&lt;/center&gt;
&lt;p&gt;Since only three mixture components have appreciable posterior expected weight for any data point, we can be fairly certain that truncation did not unduly influence our results. (If most components had appreciable posterior expected weight, truncation may have influenced the results, and we would have increased the number of components and sampled again.)&lt;/p&gt;
&lt;p&gt;Visually, it is reasonable that the LIDAR data has three linear components, so these posterior expected weights seem to have identified the structure of the data well. We now sample from the posterior predictive distribution to get a better understand the model’s performance.&lt;/p&gt;
&lt;div class="sourceCode" id="cb17"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb17-1"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb17-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;PP_SAMPLES &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dv"&gt;5000&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb17-2"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb17-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb17-3"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb17-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;lidar_pp_x &lt;span class="op"&gt;=&lt;/span&gt; np.linspace(std_range.&lt;span class="bu"&gt;min&lt;/span&gt;() &lt;span class="op"&gt;-&lt;/span&gt; &lt;span class="fl"&gt;0.05&lt;/span&gt;, std_range.&lt;span class="bu"&gt;max&lt;/span&gt;() &lt;span class="op"&gt;+&lt;/span&gt; &lt;span class="fl"&gt;0.05&lt;/span&gt;, &lt;span class="dv"&gt;100&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb17-4"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb17-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;x_lidar.set_value(lidar_pp_x[:, np.newaxis])&lt;/span&gt;
&lt;span id="cb17-5"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb17-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb17-6"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb17-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="cf"&gt;with&lt;/span&gt; model:&lt;/span&gt;
&lt;span id="cb17-7"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb17-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    pp_trace &lt;span class="op"&gt;=&lt;/span&gt; pm.sample_ppc(trace, PP_SAMPLES, random_seed&lt;span class="op"&gt;=&lt;/span&gt;SEED)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;100%|██████████| 5000/5000 [01:18&amp;lt;00:00, 66.54it/s]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Below we plot the posterior expected value and the 95% posterior credible interval.&lt;/p&gt;
&lt;div class="sourceCode" id="cb19"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb19-1"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb19-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;fig, ax &lt;span class="op"&gt;=&lt;/span&gt; plt.subplots()&lt;/span&gt;
&lt;span id="cb19-2"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb19-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb19-3"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb19-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.scatter(df.std_range, df.std_logratio,&lt;/span&gt;
&lt;span id="cb19-4"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb19-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;           c&lt;span class="op"&gt;=&lt;/span&gt;blue, zorder&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;10&lt;/span&gt;,&lt;/span&gt;
&lt;span id="cb19-5"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb19-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;           label&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="va"&gt;None&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb19-6"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb19-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb19-7"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb19-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;low, high &lt;span class="op"&gt;=&lt;/span&gt; np.percentile(pp_trace[&lt;span class="st"&gt;'obs'&lt;/span&gt;], [&lt;span class="fl"&gt;2.5&lt;/span&gt;, &lt;span class="fl"&gt;97.5&lt;/span&gt;], axis&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;0&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb19-8"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb19-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.fill_between(lidar_pp_x, low, high,&lt;/span&gt;
&lt;span id="cb19-9"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb19-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;                color&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'k'&lt;/span&gt;, alpha&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="fl"&gt;0.35&lt;/span&gt;, zorder&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;5&lt;/span&gt;,&lt;/span&gt;
&lt;span id="cb19-10"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb19-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;                label&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'95% posterior credible interval'&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb19-11"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb19-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb19-12"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb19-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.plot(lidar_pp_x, pp_trace[&lt;span class="st"&gt;'obs'&lt;/span&gt;].mean(axis&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;0&lt;/span&gt;),&lt;/span&gt;
&lt;span id="cb19-13"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb19-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        c&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'k'&lt;/span&gt;, zorder&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;6&lt;/span&gt;,&lt;/span&gt;
&lt;span id="cb19-14"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb19-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        label&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'Posterior expected value'&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb19-15"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb19-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb19-16"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb19-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.set_xticklabels([])&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb19-17"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb19-17" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.set_xlabel(&lt;span class="st"&gt;'Standardized range'&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb19-18"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb19-18" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb19-19"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb19-19" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.set_yticklabels([])&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb19-20"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb19-20" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.set_ylabel(&lt;span class="st"&gt;'Standardized log ratio'&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb19-21"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb19-21" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb19-22"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb19-22" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb19-23"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb19-23" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.legend(loc&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb19-24"&gt;&lt;a href="https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html#cb19-24" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.set_title(&lt;span class="st"&gt;'LIDAR Data'&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;center&gt;
&lt;img src="https://austinrochford.com/resources/ddp/Dependent%20Density%20Regression%20with%20PyMC3_28_0.png" title="fig:" alt="png"&gt;
&lt;/center&gt;
&lt;p&gt;The model has fit the linear components of the data well, and also accomodated its heteroskedasticity. This flexibility, along with the ability to modularly specify the conditional mixture weights and conditional component densities, makes dependent density regression an extremely useful nonparametric Bayesian model.&lt;/p&gt;
&lt;p&gt;To learn more about depdendent density regression and related models, consult &lt;a href="http://www.stat.columbia.edu/~gelman/book/"&gt;&lt;em&gt;Bayesian Data Analysis&lt;/em&gt;&lt;/a&gt;, &lt;a href="http://www.springer.com/us/book/9783319189673"&gt;&lt;em&gt;Bayesian Nonparametric Data Analysis&lt;/em&gt;&lt;/a&gt;, or &lt;a href="https://www.google.com/webhp?sourceid=chrome-instant&amp;amp;ion=1&amp;amp;espv=2&amp;amp;ie=UTF-8#q=bayesian+nonparametrics+book"&gt;&lt;em&gt;Bayesian Nonparametrics&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This post is available as a Jupyter notebook &lt;a href="https://nbviewer.jupyter.org/gist/AustinRochford/0d6926e9953e8b8093a110863fc0487f"&gt;here&lt;/a&gt;.&lt;/p&gt;</description><category>Bayesian Nonparametric Statistics</category><category>Bayesian Statistics</category><category>Dirichlet Processes</category><category>Nonparametric Statistics</category><category>PyMC3</category><guid>https://austinrochford.com/posts/2017-01-18-ddp-pymc3.html</guid><pubDate>Wed, 18 Jan 2017 05:00:00 GMT</pubDate></item><item><title>Density Estimation with Dirichlet Process Mixtures using PyMC3</title><link>https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html</link><dc:creator>Austin Rochford</dc:creator><description>&lt;p&gt;I have been intrigued by the flexibility of &lt;a href="https://en.wikipedia.org/wiki/Nonparametric_statistics"&gt;nonparametric statistics&lt;/a&gt; for many years. As I have developed an understanding and appreciation of Bayesian modeling both personally and professionally over the last two or three years, I naturally developed an interest in Bayesian nonparametric statistics. I am pleased to begin a planned series of posts on Bayesian nonparametrics with this post on Dirichlet process mixtures for density estimation.&lt;/p&gt;
&lt;h4 id="dirichlet-processes"&gt;Dirichlet processes&lt;/h4&gt;
&lt;p&gt;The &lt;a href="https://en.wikipedia.org/wiki/Dirichlet_process"&gt;Dirichlet process&lt;/a&gt; is a flexible probability distribution over the space of distributions. Most generally, a probability distribution, &lt;span class="math inline"&gt;\(P\)&lt;/span&gt;, on a set &lt;span class="math inline"&gt;\(\Omega\)&lt;/span&gt; is a &lt;a href="https://en.wikipedia.org/wiki/Measure_(mathematics)"&gt;measure&lt;/a&gt; that assigns measure one to the entire space (&lt;span class="math inline"&gt;\(P(\Omega) = 1\)&lt;/span&gt;). A Dirichlet process &lt;span class="math inline"&gt;\(P \sim \textrm{DP}(\alpha, P_0)\)&lt;/span&gt; is a measure that has the property that, for every finite &lt;a href="https://en.wikipedia.org/wiki/Disjoint_sets"&gt;disjoint&lt;/a&gt; partition &lt;span class="math inline"&gt;\(S_1, \ldots, S_n\)&lt;/span&gt; of &lt;span class="math inline"&gt;\(\Omega\)&lt;/span&gt;,&lt;/p&gt;
&lt;p&gt;&lt;span class="math display"&gt;\[(P(S_1), \ldots, P(S_n)) \sim \textrm{Dir}(\alpha P_0(S_1), \ldots, \alpha P_0(S_n)).\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Here &lt;span class="math inline"&gt;\(P_0\)&lt;/span&gt; is the base probability measure on the space &lt;span class="math inline"&gt;\(\Omega\)&lt;/span&gt;. The precision parameter &lt;span class="math inline"&gt;\(\alpha &amp;gt; 0\)&lt;/span&gt; controls how close samples from the Dirichlet process are to the base measure, &lt;span class="math inline"&gt;\(P_0\)&lt;/span&gt;. As &lt;span class="math inline"&gt;\(\alpha \to \infty\)&lt;/span&gt;, samples from the Dirichlet process approach the base measure &lt;span class="math inline"&gt;\(P_0\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Dirichlet processes have several properties that make then quite suitable to &lt;a href="https://en.wikipedia.org/wiki/Markov_chain_Monte_Carlo"&gt;MCMC&lt;/a&gt; simulation.&lt;/p&gt;
&lt;ol type="1"&gt;
&lt;li&gt;&lt;p&gt;The posterior given &lt;a href="https://en.wikipedia.org/wiki/Independent_and_identically_distributed_random_variables"&gt;i.i.d.&lt;/a&gt; observations &lt;span class="math inline"&gt;\(\omega_1, \ldots, \omega_n\)&lt;/span&gt; from a Dirichlet process &lt;span class="math inline"&gt;\(P \sim \textrm{DP}(\alpha, P_0)\)&lt;/span&gt; is also a Dirichlet process with&lt;/p&gt;
&lt;p&gt;&lt;span class="math display"&gt;\[P\ |\ \omega_1, \ldots, \omega_n \sim \textrm{DP}\left(\alpha + n, \frac{\alpha}{\alpha + n} P_0 + \frac{1}{\alpha + n} \sum_{i = 1}^n \delta_{\omega_i}\right),\]&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;where &lt;span class="math inline"&gt;\(\delta\)&lt;/span&gt; is the &lt;a href="https://en.wikipedia.org/wiki/Dirac_delta_function"&gt;Dirac delta measure&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="math display"&gt;\[\begin{align*}
    \delta_{\omega}(S)
        &amp;amp; = \begin{cases}
                1 &amp;amp; \textrm{if } \omega \in S \\
                0 &amp;amp; \textrm{if } \omega \not \in S
            \end{cases}
\end{align*}.\]&lt;/span&gt;&lt;/p&gt;
&lt;ol start="2" type="1"&gt;
&lt;li&gt;&lt;p&gt;The posterior predictive distribution of a new observation is a compromise between the base measure and the observations,&lt;/p&gt;
&lt;p&gt;&lt;span class="math display"&gt;\[\omega\ |\ \omega_1, \ldots, \omega_n \sim \frac{\alpha}{\alpha + n} P_0 + \frac{1}{\alpha + n} \sum_{i = 1}^n \delta_{\omega_i}.\]&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;We see that the prior precision &lt;span class="math inline"&gt;\(\alpha\)&lt;/span&gt; can naturally be interpreted as a prior sample size. The form of this posterior predictive distribution also lends itself to Gibbs sampling.&lt;/p&gt;
&lt;ol start="2" type="1"&gt;
&lt;li&gt;&lt;p&gt;Samples, &lt;span class="math inline"&gt;\(P \sim \textrm{DP}(\alpha, P_0)\)&lt;/span&gt;, from a Dirichlet process are discrete with probability one. That is, there are elements &lt;span class="math inline"&gt;\(\omega_1, \omega_2, \ldots\)&lt;/span&gt; in &lt;span class="math inline"&gt;\(\Omega\)&lt;/span&gt; and weights &lt;span class="math inline"&gt;\(w_1, w_2, \ldots\)&lt;/span&gt; with &lt;span class="math inline"&gt;\(\sum_{i = 1}^{\infty} w_i = 1\)&lt;/span&gt; such that&lt;/p&gt;
&lt;p&gt;&lt;span class="math display"&gt;\[P = \sum_{i = 1}^\infty w_i \delta_{\omega_i}.\]&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;a href="https://en.wikipedia.org/wiki/Dirichlet_process#The_stick-breaking_process"&gt;stick-breaking process&lt;/a&gt; gives an explicit construction of the weights &lt;span class="math inline"&gt;\(w_i\)&lt;/span&gt; and samples &lt;span class="math inline"&gt;\(\omega_i\)&lt;/span&gt; above that is straightforward to sample from. If &lt;span class="math inline"&gt;\(\beta_1, \beta_2, \ldots \sim \textrm{Beta}(1, \alpha)\)&lt;/span&gt;, then &lt;span class="math inline"&gt;\(w_i = \beta_i \prod_{j = 1}^{j - 1} (1 - \beta_j)\)&lt;/span&gt;. The relationship between this representation and stick breaking may be illustrated as follows:&lt;/p&gt;
&lt;ol type="1"&gt;
&lt;li&gt;Start with a stick of length one.&lt;/li&gt;
&lt;li&gt;Break the stick into two portions, the first of proportion &lt;span class="math inline"&gt;\(w_1 = \beta_1\)&lt;/span&gt; and the second of proportion &lt;span class="math inline"&gt;\(1 - w_1\)&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;Further break the second portion into two portions, the first of proportion &lt;span class="math inline"&gt;\(\beta_2\)&lt;/span&gt; and the second of proportion &lt;span class="math inline"&gt;\(1 - \beta_2\)&lt;/span&gt;. The length of the first portion of this stick is &lt;span class="math inline"&gt;\(\beta_2 (1 - \beta_1)\)&lt;/span&gt;; the length of the second portion is &lt;span class="math inline"&gt;\((1 - \beta_1) (1 - \beta_2)\)&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;Continue breaking the second portion from the previous break in this manner forever. If &lt;span class="math inline"&gt;\(\omega_1, \omega_2, \ldots \sim P_0\)&lt;/span&gt;, then&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;span class="math display"&gt;\[P = \sum_{i = 1}^\infty w_i \delta_{\omega_i} \sim \textrm{DP}(\alpha, P_0).\]&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;We can use the stick-breaking process above to easily sample from a Dirichlet process in Python. For this example, &lt;span class="math inline"&gt;\(\alpha = 2\)&lt;/span&gt; and the base distribution is &lt;span class="math inline"&gt;\(N(0, 1)\)&lt;/span&gt;.&lt;/p&gt;
&lt;div class="sourceCode" id="cb1"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb1-1"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb1-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;%&lt;/span&gt;matplotlib inline&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="sourceCode" id="cb2"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb2-1"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb2-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="im"&gt;from&lt;/span&gt; __future__ &lt;span class="im"&gt;import&lt;/span&gt; division&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="sourceCode" id="cb3"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb3-1"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb3-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="im"&gt;from&lt;/span&gt; matplotlib &lt;span class="im"&gt;import&lt;/span&gt; pyplot &lt;span class="im"&gt;as&lt;/span&gt; plt&lt;/span&gt;
&lt;span id="cb3-2"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb3-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="im"&gt;import&lt;/span&gt; numpy &lt;span class="im"&gt;as&lt;/span&gt; np&lt;/span&gt;
&lt;span id="cb3-3"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb3-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="im"&gt;import&lt;/span&gt; pymc3 &lt;span class="im"&gt;as&lt;/span&gt; pm&lt;/span&gt;
&lt;span id="cb3-4"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb3-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="im"&gt;import&lt;/span&gt; scipy &lt;span class="im"&gt;as&lt;/span&gt; sp&lt;/span&gt;
&lt;span id="cb3-5"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb3-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="im"&gt;import&lt;/span&gt; seaborn &lt;span class="im"&gt;as&lt;/span&gt; sns&lt;/span&gt;
&lt;span id="cb3-6"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb3-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="im"&gt;from&lt;/span&gt; statsmodels.datasets &lt;span class="im"&gt;import&lt;/span&gt; get_rdataset&lt;/span&gt;
&lt;span id="cb3-7"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb3-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="im"&gt;from&lt;/span&gt; theano &lt;span class="im"&gt;import&lt;/span&gt; tensor &lt;span class="im"&gt;as&lt;/span&gt; T&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;Couldn't import dot_parser, loading of dot files will not be possible.&lt;/code&gt;&lt;/pre&gt;
&lt;div class="sourceCode" id="cb5"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb5-1"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb5-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;blue &lt;span class="op"&gt;=&lt;/span&gt; sns.color_palette()[&lt;span class="dv"&gt;0&lt;/span&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="sourceCode" id="cb6"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb6-1"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb6-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;np.random.seed(&lt;span class="dv"&gt;462233&lt;/span&gt;) &lt;span class="co"&gt;# from random.org&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="sourceCode" id="cb7"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb7-1"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb7-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;N &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dv"&gt;20&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-2"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb7-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;K &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dv"&gt;30&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-3"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb7-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb7-4"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb7-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;alpha &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="fl"&gt;2.&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb7-5"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb7-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;P0 &lt;span class="op"&gt;=&lt;/span&gt; sp.stats.norm&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We draw and plot samples from the stick-breaking process.&lt;/p&gt;
&lt;div class="sourceCode" id="cb8"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb8-1"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb8-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;beta &lt;span class="op"&gt;=&lt;/span&gt; sp.stats.beta.rvs(&lt;span class="dv"&gt;1&lt;/span&gt;, alpha, size&lt;span class="op"&gt;=&lt;/span&gt;(N, K))&lt;/span&gt;
&lt;span id="cb8-2"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb8-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;w &lt;span class="op"&gt;=&lt;/span&gt; np.empty_like(beta)&lt;/span&gt;
&lt;span id="cb8-3"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb8-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;w[:, &lt;span class="dv"&gt;0&lt;/span&gt;] &lt;span class="op"&gt;=&lt;/span&gt; beta[:, &lt;span class="dv"&gt;0&lt;/span&gt;]&lt;/span&gt;
&lt;span id="cb8-4"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb8-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;w[:, &lt;span class="dv"&gt;1&lt;/span&gt;:] &lt;span class="op"&gt;=&lt;/span&gt; beta[:, &lt;span class="dv"&gt;1&lt;/span&gt;:] &lt;span class="op"&gt;*&lt;/span&gt; (&lt;span class="dv"&gt;1&lt;/span&gt; &lt;span class="op"&gt;-&lt;/span&gt; beta[:, :&lt;span class="op"&gt;-&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;]).cumprod(axis&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb8-5"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb8-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb8-6"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb8-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;omega &lt;span class="op"&gt;=&lt;/span&gt; P0.rvs(size&lt;span class="op"&gt;=&lt;/span&gt;(N, K))&lt;/span&gt;
&lt;span id="cb8-7"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb8-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb8-8"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb8-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;x_plot &lt;span class="op"&gt;=&lt;/span&gt; np.linspace(&lt;span class="op"&gt;-&lt;/span&gt;&lt;span class="dv"&gt;3&lt;/span&gt;, &lt;span class="dv"&gt;3&lt;/span&gt;, &lt;span class="dv"&gt;200&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb8-9"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb8-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb8-10"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb8-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;sample_cdfs &lt;span class="op"&gt;=&lt;/span&gt; (w[..., np.newaxis] &lt;span class="op"&gt;*&lt;/span&gt; np.less.outer(omega, x_plot)).&lt;span class="bu"&gt;sum&lt;/span&gt;(axis&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="sourceCode" id="cb9"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb9-1"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb9-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;fig, ax &lt;span class="op"&gt;=&lt;/span&gt; plt.subplots(figsize&lt;span class="op"&gt;=&lt;/span&gt;(&lt;span class="dv"&gt;8&lt;/span&gt;, &lt;span class="dv"&gt;6&lt;/span&gt;))&lt;/span&gt;
&lt;span id="cb9-2"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb9-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb9-3"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb9-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.plot(x_plot, sample_cdfs[&lt;span class="dv"&gt;0&lt;/span&gt;], c&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'gray'&lt;/span&gt;, alpha&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="fl"&gt;0.75&lt;/span&gt;,&lt;/span&gt;
&lt;span id="cb9-4"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb9-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        label&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'DP sample CDFs'&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-5"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb9-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.plot(x_plot, sample_cdfs[&lt;span class="dv"&gt;1&lt;/span&gt;:].T, c&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'gray'&lt;/span&gt;, alpha&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="fl"&gt;0.75&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-6"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb9-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.plot(x_plot, P0.cdf(x_plot), c&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'k'&lt;/span&gt;, label&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'Base CDF'&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-7"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb9-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb9-8"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb9-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.set_title(&lt;span class="vs"&gt;r'$\alpha = &lt;/span&gt;&lt;span class="sc"&gt;{}&lt;/span&gt;&lt;span class="vs"&gt;$'&lt;/span&gt;.&lt;span class="bu"&gt;format&lt;/span&gt;(alpha))&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb9-9"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb9-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.legend(loc&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;2&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;center&gt;
&lt;img src="https://austinrochford.com/resources/dpm_density/Density%20Estimation%20with%20Dirichlet%20Process%20Mixtures%20using%20PyMC3_10_0.png"&gt;
&lt;/center&gt;
&lt;p&gt;As stated above, as &lt;span class="math inline"&gt;\(\alpha \to \infty\)&lt;/span&gt;, samples from the Dirichlet process converge to the base distribution.&lt;/p&gt;
&lt;div class="sourceCode" id="cb10"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb10-1"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;fig, (l_ax, r_ax) &lt;span class="op"&gt;=&lt;/span&gt; plt.subplots(ncols&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;2&lt;/span&gt;, sharex&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="va"&gt;True&lt;/span&gt;, sharey&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="va"&gt;True&lt;/span&gt;, figsize&lt;span class="op"&gt;=&lt;/span&gt;(&lt;span class="dv"&gt;16&lt;/span&gt;, &lt;span class="dv"&gt;6&lt;/span&gt;))&lt;/span&gt;
&lt;span id="cb10-2"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb10-3"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;K &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dv"&gt;50&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-4"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;alpha &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="fl"&gt;10.&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-5"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb10-6"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;beta &lt;span class="op"&gt;=&lt;/span&gt; sp.stats.beta.rvs(&lt;span class="dv"&gt;1&lt;/span&gt;, alpha, size&lt;span class="op"&gt;=&lt;/span&gt;(N, K))&lt;/span&gt;
&lt;span id="cb10-7"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;w &lt;span class="op"&gt;=&lt;/span&gt; np.empty_like(beta)&lt;/span&gt;
&lt;span id="cb10-8"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;w[:, &lt;span class="dv"&gt;0&lt;/span&gt;] &lt;span class="op"&gt;=&lt;/span&gt; beta[:, &lt;span class="dv"&gt;0&lt;/span&gt;]&lt;/span&gt;
&lt;span id="cb10-9"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;w[:, &lt;span class="dv"&gt;1&lt;/span&gt;:] &lt;span class="op"&gt;=&lt;/span&gt; beta[:, &lt;span class="dv"&gt;1&lt;/span&gt;:] &lt;span class="op"&gt;*&lt;/span&gt; (&lt;span class="dv"&gt;1&lt;/span&gt; &lt;span class="op"&gt;-&lt;/span&gt; beta[:, :&lt;span class="op"&gt;-&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;]).cumprod(axis&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb10-10"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb10-11"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;omega &lt;span class="op"&gt;=&lt;/span&gt; P0.rvs(size&lt;span class="op"&gt;=&lt;/span&gt;(N, K))&lt;/span&gt;
&lt;span id="cb10-12"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb10-13"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;sample_cdfs &lt;span class="op"&gt;=&lt;/span&gt; (w[..., np.newaxis] &lt;span class="op"&gt;*&lt;/span&gt; np.less.outer(omega, x_plot)).&lt;span class="bu"&gt;sum&lt;/span&gt;(axis&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb10-14"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb10-15"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;l_ax.plot(x_plot, sample_cdfs[&lt;span class="dv"&gt;0&lt;/span&gt;], c&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'gray'&lt;/span&gt;, alpha&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="fl"&gt;0.75&lt;/span&gt;,&lt;/span&gt;
&lt;span id="cb10-16"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;          label&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'DP sample CDFs'&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-17"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-17" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;l_ax.plot(x_plot, sample_cdfs[&lt;span class="dv"&gt;1&lt;/span&gt;:].T, c&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'gray'&lt;/span&gt;, alpha&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="fl"&gt;0.75&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-18"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-18" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;l_ax.plot(x_plot, P0.cdf(x_plot), c&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'k'&lt;/span&gt;, label&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'Base CDF'&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-19"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-19" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb10-20"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-20" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;l_ax.set_title(&lt;span class="vs"&gt;r'$\alpha = &lt;/span&gt;&lt;span class="sc"&gt;{}&lt;/span&gt;&lt;span class="vs"&gt;$'&lt;/span&gt;.&lt;span class="bu"&gt;format&lt;/span&gt;(alpha))&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-21"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-21" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;l_ax.legend(loc&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;2&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-22"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-22" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb10-23"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-23" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;K &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dv"&gt;200&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-24"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-24" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;alpha &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="fl"&gt;50.&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-25"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-25" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb10-26"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-26" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;beta &lt;span class="op"&gt;=&lt;/span&gt; sp.stats.beta.rvs(&lt;span class="dv"&gt;1&lt;/span&gt;, alpha, size&lt;span class="op"&gt;=&lt;/span&gt;(N, K))&lt;/span&gt;
&lt;span id="cb10-27"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-27" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;w &lt;span class="op"&gt;=&lt;/span&gt; np.empty_like(beta)&lt;/span&gt;
&lt;span id="cb10-28"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-28" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;w[:, &lt;span class="dv"&gt;0&lt;/span&gt;] &lt;span class="op"&gt;=&lt;/span&gt; beta[:, &lt;span class="dv"&gt;0&lt;/span&gt;]&lt;/span&gt;
&lt;span id="cb10-29"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-29" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;w[:, &lt;span class="dv"&gt;1&lt;/span&gt;:] &lt;span class="op"&gt;=&lt;/span&gt; beta[:, &lt;span class="dv"&gt;1&lt;/span&gt;:] &lt;span class="op"&gt;*&lt;/span&gt; (&lt;span class="dv"&gt;1&lt;/span&gt; &lt;span class="op"&gt;-&lt;/span&gt; beta[:, :&lt;span class="op"&gt;-&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;]).cumprod(axis&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb10-30"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-30" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb10-31"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-31" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;omega &lt;span class="op"&gt;=&lt;/span&gt; P0.rvs(size&lt;span class="op"&gt;=&lt;/span&gt;(N, K))&lt;/span&gt;
&lt;span id="cb10-32"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-32" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb10-33"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-33" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;sample_cdfs &lt;span class="op"&gt;=&lt;/span&gt; (w[..., np.newaxis] &lt;span class="op"&gt;*&lt;/span&gt; np.less.outer(omega, x_plot)).&lt;span class="bu"&gt;sum&lt;/span&gt;(axis&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb10-34"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-34" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb10-35"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-35" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;r_ax.plot(x_plot, sample_cdfs[&lt;span class="dv"&gt;0&lt;/span&gt;], c&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'gray'&lt;/span&gt;, alpha&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="fl"&gt;0.75&lt;/span&gt;,&lt;/span&gt;
&lt;span id="cb10-36"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-36" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;          label&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'DP sample CDFs'&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-37"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-37" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;r_ax.plot(x_plot, sample_cdfs[&lt;span class="dv"&gt;1&lt;/span&gt;:].T, c&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'gray'&lt;/span&gt;, alpha&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="fl"&gt;0.75&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-38"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-38" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;r_ax.plot(x_plot, P0.cdf(x_plot), c&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'k'&lt;/span&gt;, label&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'Base CDF'&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-39"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-39" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb10-40"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-40" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;r_ax.set_title(&lt;span class="vs"&gt;r'$\alpha = &lt;/span&gt;&lt;span class="sc"&gt;{}&lt;/span&gt;&lt;span class="vs"&gt;$'&lt;/span&gt;.&lt;span class="bu"&gt;format&lt;/span&gt;(alpha))&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb10-41"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb10-41" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;r_ax.legend(loc&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;2&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;center&gt;
&lt;img src="https://austinrochford.com/resources/dpm_density/Density%20Estimation%20with%20Dirichlet%20Process%20Mixtures%20using%20PyMC3_12_0.png"&gt;
&lt;/center&gt;
&lt;h3 id="dirichlet-process-mixtures"&gt;Dirichlet process mixtures&lt;/h3&gt;
&lt;p&gt;For the task of density estimation, the (almost sure) discreteness of samples from the Dirichlet process is a significant drawback. This problem can be solved with another level of indirection by using Dirichlet process mixtures for density estimation. A Dirichlet process mixture uses component densities from a parametric family &lt;span class="math inline"&gt;\(\mathcal{F} = \{f_{\theta}\ |\ \theta \in \Theta\}\)&lt;/span&gt; and represents the mixture weights as a Dirichlet process. If &lt;span class="math inline"&gt;\(P_0\)&lt;/span&gt; is a probability measure on the parameter space &lt;span class="math inline"&gt;\(\Theta\)&lt;/span&gt;, a Dirichlet process mixture is the hierarchical model&lt;/p&gt;
&lt;p&gt;&lt;span class="math display"&gt;\[
\begin{align*}
    x_i\ |\ \theta_i
        &amp;amp; \sim f_{\theta_i} \\
    \theta_1, \ldots, \theta_n
        &amp;amp; \sim P \\
    P
        &amp;amp; \sim \textrm{DP}(\alpha, P_0).
\end{align*}
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;To illustrate this model, we simulate draws from a Dirichlet process mixture with &lt;span class="math inline"&gt;\(\alpha = 2\)&lt;/span&gt;, &lt;span class="math inline"&gt;\(\theta \sim N(0, 1)\)&lt;/span&gt;, &lt;span class="math inline"&gt;\(x\ |\ \theta \sim N(\theta, (0.3)^2)\)&lt;/span&gt;.&lt;/p&gt;
&lt;div class="sourceCode" id="cb11"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb11-1"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb11-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;N &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dv"&gt;5&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-2"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb11-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;K &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dv"&gt;30&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-3"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb11-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb11-4"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb11-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;alpha &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dv"&gt;2&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-5"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb11-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;P0 &lt;span class="op"&gt;=&lt;/span&gt; sp.stats.norm&lt;/span&gt;
&lt;span id="cb11-6"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb11-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;f &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="kw"&gt;lambda&lt;/span&gt; x, theta: sp.stats.norm.pdf(x, theta, &lt;span class="fl"&gt;0.3&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="sourceCode" id="cb12"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb12-1"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb12-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;beta &lt;span class="op"&gt;=&lt;/span&gt; sp.stats.beta.rvs(&lt;span class="dv"&gt;1&lt;/span&gt;, alpha, size&lt;span class="op"&gt;=&lt;/span&gt;(N, K))&lt;/span&gt;
&lt;span id="cb12-2"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb12-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;w &lt;span class="op"&gt;=&lt;/span&gt; np.empty_like(beta)&lt;/span&gt;
&lt;span id="cb12-3"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb12-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;w[:, &lt;span class="dv"&gt;0&lt;/span&gt;] &lt;span class="op"&gt;=&lt;/span&gt; beta[:, &lt;span class="dv"&gt;0&lt;/span&gt;]&lt;/span&gt;
&lt;span id="cb12-4"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb12-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;w[:, &lt;span class="dv"&gt;1&lt;/span&gt;:] &lt;span class="op"&gt;=&lt;/span&gt; beta[:, &lt;span class="dv"&gt;1&lt;/span&gt;:] &lt;span class="op"&gt;*&lt;/span&gt; (&lt;span class="dv"&gt;1&lt;/span&gt; &lt;span class="op"&gt;-&lt;/span&gt; beta[:, :&lt;span class="op"&gt;-&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;]).cumprod(axis&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb12-5"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb12-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb12-6"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb12-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;theta &lt;span class="op"&gt;=&lt;/span&gt; P0.rvs(size&lt;span class="op"&gt;=&lt;/span&gt;(N, K))&lt;/span&gt;
&lt;span id="cb12-7"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb12-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb12-8"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb12-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;dpm_pdf_components &lt;span class="op"&gt;=&lt;/span&gt; f(x_plot[np.newaxis, np.newaxis, :], theta[..., np.newaxis])&lt;/span&gt;
&lt;span id="cb12-9"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb12-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;dpm_pdfs &lt;span class="op"&gt;=&lt;/span&gt; (w[..., np.newaxis] &lt;span class="op"&gt;*&lt;/span&gt; dpm_pdf_components).&lt;span class="bu"&gt;sum&lt;/span&gt;(axis&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="sourceCode" id="cb13"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb13-1"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb13-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;fig, ax &lt;span class="op"&gt;=&lt;/span&gt; plt.subplots(figsize&lt;span class="op"&gt;=&lt;/span&gt;(&lt;span class="dv"&gt;8&lt;/span&gt;, &lt;span class="dv"&gt;6&lt;/span&gt;))&lt;/span&gt;
&lt;span id="cb13-2"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb13-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb13-3"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb13-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.plot(x_plot, dpm_pdfs.T, c&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'gray'&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-4"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb13-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb13-5"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb13-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.set_yticklabels([])&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;center&gt;
&lt;img src="https://austinrochford.com/resources/dpm_density/Density%20Estimation%20with%20Dirichlet%20Process%20Mixtures%20using%20PyMC3_16_0.png"&gt;
&lt;/center&gt;
&lt;p&gt;We now focus on a single mixture and decompose it into its individual (weighted) mixture components.&lt;/p&gt;
&lt;div class="sourceCode" id="cb14"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb14-1"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb14-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;fig, ax &lt;span class="op"&gt;=&lt;/span&gt; plt.subplots(figsize&lt;span class="op"&gt;=&lt;/span&gt;(&lt;span class="dv"&gt;8&lt;/span&gt;, &lt;span class="dv"&gt;6&lt;/span&gt;))&lt;/span&gt;
&lt;span id="cb14-2"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb14-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb14-3"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb14-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ix &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dv"&gt;1&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-4"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb14-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb14-5"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb14-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.plot(x_plot, dpm_pdfs[ix], c&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'k'&lt;/span&gt;, label&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'Density'&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-6"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb14-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.plot(x_plot, (w[..., np.newaxis] &lt;span class="op"&gt;*&lt;/span&gt; dpm_pdf_components)[ix, &lt;span class="dv"&gt;0&lt;/span&gt;],&lt;/span&gt;
&lt;span id="cb14-7"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb14-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="st"&gt;'--'&lt;/span&gt;, c&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'k'&lt;/span&gt;, label&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'Mixture components (weighted)'&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-8"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb14-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.plot(x_plot, (w[..., np.newaxis] &lt;span class="op"&gt;*&lt;/span&gt; dpm_pdf_components)[ix].T,&lt;/span&gt;
&lt;span id="cb14-9"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb14-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="st"&gt;'--'&lt;/span&gt;, c&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'k'&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-10"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb14-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb14-11"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb14-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.set_yticklabels([])&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb14-12"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb14-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.legend(loc&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;center&gt;
&lt;img src="https://austinrochford.com/resources/dpm_density/Density%20Estimation%20with%20Dirichlet%20Process%20Mixtures%20using%20PyMC3_18_0.png"&gt;
&lt;/center&gt;
&lt;p&gt;Sampling from these stochastic processes is fun, but these ideas become truly useful when we fit them to data. The discreteness of samples and the stick-breaking representation of the Dirichlet process lend themselves nicely to Markov chain Monte Carlo simulation of posterior distributions. We will perform this sampling using &lt;a href="https://pymc-devs.github.io/pymc3/"&gt;&lt;code&gt;pymc3&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Our first example uses a Dirichlet process mixture to estimate the density of waiting times between eruptions of the &lt;a href="https://en.wikipedia.org/wiki/Old_Faithful"&gt;Old Faithful&lt;/a&gt; geyser in &lt;a href="https://en.wikipedia.org/wiki/Yellowstone_National_Park"&gt;Yellowstone National Park&lt;/a&gt;.&lt;/p&gt;
&lt;div class="sourceCode" id="cb15"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb15-1"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb15-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;old_faithful_df &lt;span class="op"&gt;=&lt;/span&gt; get_rdataset(&lt;span class="st"&gt;'faithful'&lt;/span&gt;, cache&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="va"&gt;True&lt;/span&gt;).data[[&lt;span class="st"&gt;'waiting'&lt;/span&gt;]]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For convenience in specifying the prior, we standardize the waiting time between eruptions.&lt;/p&gt;
&lt;div class="sourceCode" id="cb16"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb16-1"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb16-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;old_faithful_df[&lt;span class="st"&gt;'std_waiting'&lt;/span&gt;] &lt;span class="op"&gt;=&lt;/span&gt; (old_faithful_df.waiting &lt;span class="op"&gt;-&lt;/span&gt; old_faithful_df.waiting.mean()) &lt;span class="op"&gt;/&lt;/span&gt; old_faithful_df.waiting.std()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="sourceCode" id="cb17"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb17-1"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb17-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;old_faithful_df.head()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;center&gt;
&lt;div&gt;
&lt;table border="1" class="dataframe"&gt;
&lt;thead&gt;
&lt;tr style="text-align: right;"&gt;
&lt;th&gt;
&lt;/th&gt;
&lt;th&gt;
waiting
&lt;/th&gt;
&lt;th&gt;
std_waiting
&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;
0
&lt;/th&gt;
&lt;td&gt;
79
&lt;/td&gt;
&lt;td&gt;
0.596025
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;
1
&lt;/th&gt;
&lt;td&gt;
54
&lt;/td&gt;
&lt;td&gt;
-1.242890
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;
2
&lt;/th&gt;
&lt;td&gt;
74
&lt;/td&gt;
&lt;td&gt;
0.228242
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;
3
&lt;/th&gt;
&lt;td&gt;
62
&lt;/td&gt;
&lt;td&gt;
-0.654437
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;
4
&lt;/th&gt;
&lt;td&gt;
85
&lt;/td&gt;
&lt;td&gt;
1.037364
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/center&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;div class="sourceCode" id="cb18"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb18-1"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb18-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;fig, ax &lt;span class="op"&gt;=&lt;/span&gt; plt.subplots(figsize&lt;span class="op"&gt;=&lt;/span&gt;(&lt;span class="dv"&gt;8&lt;/span&gt;, &lt;span class="dv"&gt;6&lt;/span&gt;))&lt;/span&gt;
&lt;span id="cb18-2"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb18-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb18-3"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb18-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;n_bins &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dv"&gt;20&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb18-4"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb18-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.hist(old_faithful_df.std_waiting, bins&lt;span class="op"&gt;=&lt;/span&gt;n_bins, color&lt;span class="op"&gt;=&lt;/span&gt;blue, lw&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;0&lt;/span&gt;, alpha&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="fl"&gt;0.5&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb18-5"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb18-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb18-6"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb18-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.set_xlabel(&lt;span class="st"&gt;'Standardized waiting time between eruptions'&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb18-7"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb18-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.set_ylabel(&lt;span class="st"&gt;'Number of eruptions'&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;center&gt;
&lt;img src="https://austinrochford.com/resources/dpm_density/Density%20Estimation%20with%20Dirichlet%20Process%20Mixtures%20using%20PyMC3_24_0.png"&gt;
&lt;/center&gt;
&lt;p&gt;Observant readers will have noted that we have not been continuing the stick-breaking process indefinitely as indicated by its definition, but rather have been truncating this process after a finite number of breaks. Obviously, when computing with Dirichlet processes, it is necessary to only store a finite number of its point masses and weights in memory. This restriction is not terribly onerous, since with a finite number of observations, it seems quite likely that the number of mixture components that contribute non-neglible mass to the mixture will grow slower than the number of samples. This intuition can be formalized to show that the (expected) number of components that contribute non-negligible mass to the mixture approaches &lt;span class="math inline"&gt;\(\alpha \log N\)&lt;/span&gt;, where &lt;span class="math inline"&gt;\(N\)&lt;/span&gt; is the sample size.&lt;/p&gt;
&lt;p&gt;There are various clever &lt;a href="https://en.wikipedia.org/wiki/Gibbs_sampling"&gt;Gibbs sampling&lt;/a&gt; techniques for Dirichlet processes that allow the number of components stored to grow as needed. &lt;a href="http://danroy.org/papers/RoyManGooTen-ICMLNPB-2008.pdf"&gt;Stochastic memoization&lt;/a&gt; is another powerful technique for simulating Dirichlet processes while only storing finitely many components in memory. In this introductory post, we take the much less sophistocated approach of simple truncating the Dirichlet process components that are stored after a fixed number, &lt;span class="math inline"&gt;\(K\)&lt;/span&gt;, of components. Importantly, this approach is compatible with some of &lt;code&gt;pymc3&lt;/code&gt;’s (current) technical limitations. &lt;a href="http://fisher.osu.edu/~schroeder.9/AMIS900/Ohlssen2006.pdf"&gt;Ohlssen, et al.&lt;/a&gt; provide justification for truncation, showing that &lt;span class="math inline"&gt;\(K &amp;gt; 5 \alpha + 2\)&lt;/span&gt; is most likely sufficient to capture almost all of the mixture weights (&lt;span class="math inline"&gt;\(\sum_{i = 1}^{K} w_i &amp;gt; 0.99\)&lt;/span&gt;). We can practically verify the suitability of our truncated approximation to the Dirichlet process by checking the number of components that contribute non-negligible mass to the mixture. If, in our simulations, all components contribute non-negligible mass to the mixture, we have truncated our Dirichlet process too early.&lt;/p&gt;
&lt;p&gt;Our Dirichlet process mixture model for the standardized waiting times is&lt;/p&gt;
&lt;p&gt;&lt;span class="math display"&gt;\[
\begin{align*}
    x_i\ |\ \mu_i, \lambda_i, \tau_i
        &amp;amp; \sim N\left(\mu, (\lambda_i \tau_i)^{-1}\right) \\
    \mu_i\ |\ \lambda_i, \tau_i
        &amp;amp; \sim N\left(0, (\lambda_i \tau_i)^{-1}\right) \\
    (\lambda_1, \tau_1), (\lambda_2, \tau_2), \ldots
        &amp;amp; \sim P \\
    P
        &amp;amp; \sim \textrm{DP}(\alpha, U(0, 5) \times \textrm{Gamma}(1, 1)) \\
    \alpha
        &amp;amp; \sim \textrm{Gamma}(1, 1).
\end{align*}
\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Note that instead of fixing a value of &lt;span class="math inline"&gt;\(\alpha\)&lt;/span&gt;, as in our previous simulations, we specify a prior on &lt;span class="math inline"&gt;\(\alpha\)&lt;/span&gt;, so that we may learn its posterior distribution from the observations. This model is therefore actually a mixture of Dirichlet process mixtures, since each fixed value of &lt;span class="math inline"&gt;\(\alpha\)&lt;/span&gt; results in a Dirichlet process mixture.&lt;/p&gt;
&lt;p&gt;We now construct this model using &lt;code&gt;pymc3&lt;/code&gt;.&lt;/p&gt;
&lt;div class="sourceCode" id="cb19"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb19-1"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb19-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;N &lt;span class="op"&gt;=&lt;/span&gt; old_faithful_df.shape[&lt;span class="dv"&gt;0&lt;/span&gt;]&lt;/span&gt;
&lt;span id="cb19-2"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb19-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb19-3"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb19-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;K &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dv"&gt;30&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="sourceCode" id="cb20"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb20-1"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb20-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="cf"&gt;with&lt;/span&gt; pm.Model() &lt;span class="im"&gt;as&lt;/span&gt; model:&lt;/span&gt;
&lt;span id="cb20-2"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb20-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    alpha &lt;span class="op"&gt;=&lt;/span&gt; pm.Gamma(&lt;span class="st"&gt;'alpha'&lt;/span&gt;, &lt;span class="fl"&gt;1.&lt;/span&gt;, &lt;span class="fl"&gt;1.&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb20-3"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb20-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    beta &lt;span class="op"&gt;=&lt;/span&gt; pm.Beta(&lt;span class="st"&gt;'beta'&lt;/span&gt;, &lt;span class="fl"&gt;1.&lt;/span&gt;, alpha, shape&lt;span class="op"&gt;=&lt;/span&gt;K)&lt;/span&gt;
&lt;span id="cb20-4"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb20-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    w &lt;span class="op"&gt;=&lt;/span&gt; pm.Deterministic(&lt;span class="st"&gt;'w'&lt;/span&gt;, beta &lt;span class="op"&gt;*&lt;/span&gt; T.concatenate([[&lt;span class="dv"&gt;1&lt;/span&gt;], T.extra_ops.cumprod(&lt;span class="dv"&gt;1&lt;/span&gt; &lt;span class="op"&gt;-&lt;/span&gt; beta)[:&lt;span class="op"&gt;-&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;]]))&lt;/span&gt;
&lt;span id="cb20-5"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb20-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    component &lt;span class="op"&gt;=&lt;/span&gt; pm.Categorical(&lt;span class="st"&gt;'component'&lt;/span&gt;, w, shape&lt;span class="op"&gt;=&lt;/span&gt;N)&lt;/span&gt;
&lt;span id="cb20-6"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb20-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb20-7"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb20-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    tau &lt;span class="op"&gt;=&lt;/span&gt; pm.Gamma(&lt;span class="st"&gt;'tau'&lt;/span&gt;, &lt;span class="fl"&gt;1.&lt;/span&gt;, &lt;span class="fl"&gt;1.&lt;/span&gt;, shape&lt;span class="op"&gt;=&lt;/span&gt;K)&lt;/span&gt;
&lt;span id="cb20-8"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb20-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    lambda_ &lt;span class="op"&gt;=&lt;/span&gt; pm.Uniform(&lt;span class="st"&gt;'lambda'&lt;/span&gt;, &lt;span class="dv"&gt;0&lt;/span&gt;, &lt;span class="dv"&gt;5&lt;/span&gt;, shape&lt;span class="op"&gt;=&lt;/span&gt;K)&lt;/span&gt;
&lt;span id="cb20-9"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb20-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    mu &lt;span class="op"&gt;=&lt;/span&gt; pm.Normal(&lt;span class="st"&gt;'mu'&lt;/span&gt;, &lt;span class="dv"&gt;0&lt;/span&gt;, lambda_ &lt;span class="op"&gt;*&lt;/span&gt; tau, shape&lt;span class="op"&gt;=&lt;/span&gt;K)&lt;/span&gt;
&lt;span id="cb20-10"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb20-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    obs &lt;span class="op"&gt;=&lt;/span&gt; pm.Normal(&lt;span class="st"&gt;'obs'&lt;/span&gt;, mu[component], lambda_[component] &lt;span class="op"&gt;*&lt;/span&gt; tau[component],&lt;/span&gt;
&lt;span id="cb20-11"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb20-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;                    observed&lt;span class="op"&gt;=&lt;/span&gt;old_faithful_df.std_waiting.values)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;Applied log-transform to alpha and added transformed alpha_log to model.
Applied logodds-transform to beta and added transformed beta_logodds to model.
Applied log-transform to tau and added transformed tau_log to model.
Applied interval-transform to lambda and added transformed lambda_interval to model.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We sample from the posterior distribution 20,000 times, burn the first 10,000 samples, and thin to every tenth sample.&lt;/p&gt;
&lt;div class="sourceCode" id="cb22"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb22-1"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb22-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="cf"&gt;with&lt;/span&gt; model:&lt;/span&gt;
&lt;span id="cb22-2"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb22-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    step1 &lt;span class="op"&gt;=&lt;/span&gt; pm.Metropolis(&lt;span class="bu"&gt;vars&lt;/span&gt;&lt;span class="op"&gt;=&lt;/span&gt;[alpha, beta, w, lambda_, tau, mu, obs])&lt;/span&gt;
&lt;span id="cb22-3"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb22-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    step2 &lt;span class="op"&gt;=&lt;/span&gt; pm.ElemwiseCategoricalStep([component], np.arange(K))&lt;/span&gt;
&lt;span id="cb22-4"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb22-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id="cb22-5"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb22-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    trace_ &lt;span class="op"&gt;=&lt;/span&gt; pm.sample(&lt;span class="dv"&gt;20000&lt;/span&gt;, [step1, step2])&lt;/span&gt;
&lt;span id="cb22-6"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb22-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb22-7"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb22-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;trace &lt;span class="op"&gt;=&lt;/span&gt; trace_[&lt;span class="dv"&gt;10000&lt;/span&gt;::&lt;span class="dv"&gt;10&lt;/span&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt; [-----------------100%-----------------] 20000 of 20000 complete in 139.3 sec&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The posterior distribution of &lt;span class="math inline"&gt;\(\alpha\)&lt;/span&gt; is concentrated between 0.4 and 1.75.&lt;/p&gt;
&lt;div class="sourceCode" id="cb24"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb24-1"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb24-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;pm.traceplot(trace, varnames&lt;span class="op"&gt;=&lt;/span&gt;[&lt;span class="st"&gt;'alpha'&lt;/span&gt;])&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;center&gt;
&lt;img src="https://austinrochford.com/resources/dpm_density/Density%20Estimation%20with%20Dirichlet%20Process%20Mixtures%20using%20PyMC3_31_0.png"&gt;
&lt;/center&gt;
&lt;p&gt;To verify that our truncation point is not biasing our results, we plot the distribution of the number of mixture components used.&lt;/p&gt;
&lt;div class="sourceCode" id="cb25"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb25-1"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb25-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;n_components_used &lt;span class="op"&gt;=&lt;/span&gt; np.apply_along_axis(&lt;span class="kw"&gt;lambda&lt;/span&gt; x: np.unique(x).size, &lt;span class="dv"&gt;1&lt;/span&gt;, trace[&lt;span class="st"&gt;'component'&lt;/span&gt;])&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="sourceCode" id="cb26"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb26-1"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb26-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;fig, ax &lt;span class="op"&gt;=&lt;/span&gt; plt.subplots(figsize&lt;span class="op"&gt;=&lt;/span&gt;(&lt;span class="dv"&gt;8&lt;/span&gt;, &lt;span class="dv"&gt;6&lt;/span&gt;))&lt;/span&gt;
&lt;span id="cb26-2"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb26-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb26-3"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb26-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;bins &lt;span class="op"&gt;=&lt;/span&gt; np.arange(n_components_used.&lt;span class="bu"&gt;min&lt;/span&gt;(), n_components_used.&lt;span class="bu"&gt;max&lt;/span&gt;() &lt;span class="op"&gt;+&lt;/span&gt; &lt;span class="dv"&gt;1&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb26-4"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb26-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.hist(n_components_used &lt;span class="op"&gt;+&lt;/span&gt; &lt;span class="dv"&gt;1&lt;/span&gt;, bins&lt;span class="op"&gt;=&lt;/span&gt;bins, normed&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="va"&gt;True&lt;/span&gt;, lw&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;0&lt;/span&gt;, alpha&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="fl"&gt;0.75&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb26-5"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb26-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb26-6"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb26-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.set_xticks(bins &lt;span class="op"&gt;+&lt;/span&gt; &lt;span class="fl"&gt;0.5&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb26-7"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb26-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.set_xticklabels(bins)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb26-8"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb26-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.set_xlim(bins.&lt;span class="bu"&gt;min&lt;/span&gt;(), bins.&lt;span class="bu"&gt;max&lt;/span&gt;() &lt;span class="op"&gt;+&lt;/span&gt; &lt;span class="dv"&gt;1&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb26-9"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb26-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.set_xlabel(&lt;span class="st"&gt;'Number of mixture components used'&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb26-10"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb26-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb26-11"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb26-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.set_ylabel(&lt;span class="st"&gt;'Posterior probability'&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;center&gt;
&lt;img src="https://austinrochford.com/resources/dpm_density/Density%20Estimation%20with%20Dirichlet%20Process%20Mixtures%20using%20PyMC3_34_0.png"&gt;
&lt;/center&gt;
&lt;p&gt;We see that the vast majority of samples use five mixture components, and the largest number of mixture components used by any sample is eight. Since we truncated our Dirichlet process mixture at thirty components, we can be quite sure that truncation did not bias our results.&lt;/p&gt;
&lt;p&gt;We now compute and plot our posterior density estimate.&lt;/p&gt;
&lt;div class="sourceCode" id="cb27"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb27-1"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb27-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;post_pdf_contribs &lt;span class="op"&gt;=&lt;/span&gt; sp.stats.norm.pdf(np.atleast_3d(x_plot),&lt;/span&gt;
&lt;span id="cb27-2"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb27-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;                                      trace[&lt;span class="st"&gt;'mu'&lt;/span&gt;][:, np.newaxis, :],&lt;/span&gt;
&lt;span id="cb27-3"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb27-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;                                      &lt;span class="fl"&gt;1.&lt;/span&gt; &lt;span class="op"&gt;/&lt;/span&gt; np.sqrt(trace[&lt;span class="st"&gt;'lambda'&lt;/span&gt;] &lt;span class="op"&gt;*&lt;/span&gt; trace[&lt;span class="st"&gt;'tau'&lt;/span&gt;])[:, np.newaxis, :])&lt;/span&gt;
&lt;span id="cb27-4"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb27-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;post_pdfs &lt;span class="op"&gt;=&lt;/span&gt; (trace[&lt;span class="st"&gt;'w'&lt;/span&gt;][:, np.newaxis, :] &lt;span class="op"&gt;*&lt;/span&gt; post_pdf_contribs).&lt;span class="bu"&gt;sum&lt;/span&gt;(axis&lt;span class="op"&gt;=-&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb27-5"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb27-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb27-6"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb27-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;post_pdf_low, post_pdf_high &lt;span class="op"&gt;=&lt;/span&gt; np.percentile(post_pdfs, [&lt;span class="fl"&gt;2.5&lt;/span&gt;, &lt;span class="fl"&gt;97.5&lt;/span&gt;], axis&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;0&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="sourceCode" id="cb28"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb28-1"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb28-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;fig, ax &lt;span class="op"&gt;=&lt;/span&gt; plt.subplots(figsize&lt;span class="op"&gt;=&lt;/span&gt;(&lt;span class="dv"&gt;8&lt;/span&gt;, &lt;span class="dv"&gt;6&lt;/span&gt;))&lt;/span&gt;
&lt;span id="cb28-2"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb28-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb28-3"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb28-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;n_bins &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dv"&gt;20&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb28-4"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb28-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.hist(old_faithful_df.std_waiting.values, bins&lt;span class="op"&gt;=&lt;/span&gt;n_bins, normed&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="va"&gt;True&lt;/span&gt;,&lt;/span&gt;
&lt;span id="cb28-5"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb28-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        color&lt;span class="op"&gt;=&lt;/span&gt;blue, lw&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;0&lt;/span&gt;, alpha&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="fl"&gt;0.5&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb28-6"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb28-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb28-7"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb28-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.fill_between(x_plot, post_pdf_low, post_pdf_high,&lt;/span&gt;
&lt;span id="cb28-8"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb28-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;                color&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'gray'&lt;/span&gt;, alpha&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="fl"&gt;0.45&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb28-9"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb28-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.plot(x_plot, post_pdfs[&lt;span class="dv"&gt;0&lt;/span&gt;],&lt;/span&gt;
&lt;span id="cb28-10"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb28-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        c&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'gray'&lt;/span&gt;, label&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'Posterior sample densities'&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb28-11"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb28-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.plot(x_plot, post_pdfs[::&lt;span class="dv"&gt;100&lt;/span&gt;].T, c&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'gray'&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb28-12"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb28-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.plot(x_plot, post_pdfs.mean(axis&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;0&lt;/span&gt;),&lt;/span&gt;
&lt;span id="cb28-13"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb28-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        c&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'k'&lt;/span&gt;, label&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'Posterior expected density'&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb28-14"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb28-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb28-15"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb28-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.set_xlabel(&lt;span class="st"&gt;'Standardized waiting time between eruptions'&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb28-16"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb28-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb28-17"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb28-17" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.set_yticklabels([])&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb28-18"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb28-18" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.set_ylabel(&lt;span class="st"&gt;'Density'&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb28-19"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb28-19" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb28-20"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb28-20" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.legend(loc&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;2&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;center&gt;
&lt;img src="https://austinrochford.com/resources/dpm_density/Density%20Estimation%20with%20Dirichlet%20Process%20Mixtures%20using%20PyMC3_37_0.png"&gt;
&lt;/center&gt;
&lt;p&gt;As above, we can decompose this density estimate into its (weighted) mixture components.&lt;/p&gt;
&lt;div class="sourceCode" id="cb29"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb29-1"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb29-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;fig, ax &lt;span class="op"&gt;=&lt;/span&gt; plt.subplots(figsize&lt;span class="op"&gt;=&lt;/span&gt;(&lt;span class="dv"&gt;8&lt;/span&gt;, &lt;span class="dv"&gt;6&lt;/span&gt;))&lt;/span&gt;
&lt;span id="cb29-2"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb29-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb29-3"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb29-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;n_bins &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dv"&gt;20&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb29-4"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb29-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.hist(old_faithful_df.std_waiting.values, bins&lt;span class="op"&gt;=&lt;/span&gt;n_bins, normed&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="va"&gt;True&lt;/span&gt;,&lt;/span&gt;
&lt;span id="cb29-5"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb29-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        color&lt;span class="op"&gt;=&lt;/span&gt;blue, lw&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;0&lt;/span&gt;, alpha&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="fl"&gt;0.5&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb29-6"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb29-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb29-7"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb29-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.plot(x_plot, post_pdfs.mean(axis&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;0&lt;/span&gt;),&lt;/span&gt;
&lt;span id="cb29-8"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb29-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        c&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'k'&lt;/span&gt;, label&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'Posterior expected density'&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb29-9"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb29-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.plot(x_plot, (trace[&lt;span class="st"&gt;'w'&lt;/span&gt;][:, np.newaxis, :] &lt;span class="op"&gt;*&lt;/span&gt; post_pdf_contribs).mean(axis&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;0&lt;/span&gt;)[:, &lt;span class="dv"&gt;0&lt;/span&gt;],&lt;/span&gt;
&lt;span id="cb29-10"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb29-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="st"&gt;'--'&lt;/span&gt;, c&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'k'&lt;/span&gt;, label&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'Posterior expected mixture&lt;/span&gt;&lt;span class="ch"&gt;\n&lt;/span&gt;&lt;span class="st"&gt;components&lt;/span&gt;&lt;span class="ch"&gt;\n&lt;/span&gt;&lt;span class="st"&gt;(weighted)'&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb29-11"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb29-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.plot(x_plot, (trace[&lt;span class="st"&gt;'w'&lt;/span&gt;][:, np.newaxis, :] &lt;span class="op"&gt;*&lt;/span&gt; post_pdf_contribs).mean(axis&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;0&lt;/span&gt;),&lt;/span&gt;
&lt;span id="cb29-12"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb29-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="st"&gt;'--'&lt;/span&gt;, c&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'k'&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb29-13"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb29-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb29-14"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb29-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.set_xlabel(&lt;span class="st"&gt;'Standardized waiting time between eruptions'&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb29-15"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb29-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb29-16"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb29-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.set_yticklabels([])&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb29-17"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb29-17" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.set_ylabel(&lt;span class="st"&gt;'Density'&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb29-18"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb29-18" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb29-19"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb29-19" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.legend(loc&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;2&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;center&gt;
&lt;img src="https://austinrochford.com/resources/dpm_density/Density%20Estimation%20with%20Dirichlet%20Process%20Mixtures%20using%20PyMC3_39_0.png"&gt;
&lt;/center&gt;
&lt;p&gt;The Dirichlet process mixture model is incredibly flexible in terms of the family of parametric component distributions &lt;span class="math inline"&gt;\(\{f_{\theta}\ |\ f_{\theta} \in \Theta\}\)&lt;/span&gt;. We illustrate this flexibility below by using Poisson component distributions to estimate the density of sunspots per year.&lt;/p&gt;
&lt;div class="sourceCode" id="cb30"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb30-1"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb30-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;sunspot_df &lt;span class="op"&gt;=&lt;/span&gt; get_rdataset(&lt;span class="st"&gt;'sunspot.year'&lt;/span&gt;, cache&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="va"&gt;True&lt;/span&gt;).data&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="sourceCode" id="cb31"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb31-1"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb31-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;sunspot_df.head()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;center&gt;
&lt;div&gt;
&lt;table border="1" class="dataframe"&gt;
&lt;thead&gt;
&lt;tr style="text-align: right;"&gt;
&lt;th&gt;
&lt;/th&gt;
&lt;th&gt;
time
&lt;/th&gt;
&lt;th&gt;
sunspot.year
&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;
0
&lt;/th&gt;
&lt;td&gt;
1700
&lt;/td&gt;
&lt;td&gt;
5
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;
1
&lt;/th&gt;
&lt;td&gt;
1701
&lt;/td&gt;
&lt;td&gt;
11
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;
2
&lt;/th&gt;
&lt;td&gt;
1702
&lt;/td&gt;
&lt;td&gt;
16
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;
3
&lt;/th&gt;
&lt;td&gt;
1703
&lt;/td&gt;
&lt;td&gt;
23
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;
4
&lt;/th&gt;
&lt;td&gt;
1704
&lt;/td&gt;
&lt;td&gt;
36
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/center&gt;
&lt;p&gt;For this problem, the model is&lt;/p&gt;
&lt;p&gt;&lt;span class="math display"&gt;\[
\begin{align*}
    x_i\ |\ \lambda_i
        &amp;amp; \sim \textrm{Poisson}(\lambda_i) \\
    \lambda_1, \lambda_2, \ldots
        &amp;amp; \sim P \\
    P
        &amp;amp; \sim \textrm{DP}(\alpha, U(0, 300)) \\
    \alpha
        &amp;amp; \sim \textrm{Gamma}(1, 1).
\end{align*}
\]&lt;/span&gt;&lt;/p&gt;
&lt;div class="sourceCode" id="cb32"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb32-1"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb32-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;N &lt;span class="op"&gt;=&lt;/span&gt; sunspot_df.shape[&lt;span class="dv"&gt;0&lt;/span&gt;]&lt;/span&gt;
&lt;span id="cb32-2"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb32-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb32-3"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb32-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;K &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dv"&gt;30&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="sourceCode" id="cb33"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb33-1"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb33-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="cf"&gt;with&lt;/span&gt; pm.Model() &lt;span class="im"&gt;as&lt;/span&gt; model:&lt;/span&gt;
&lt;span id="cb33-2"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb33-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    alpha &lt;span class="op"&gt;=&lt;/span&gt; pm.Gamma(&lt;span class="st"&gt;'alpha'&lt;/span&gt;, &lt;span class="fl"&gt;1.&lt;/span&gt;, &lt;span class="fl"&gt;1.&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb33-3"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb33-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    beta &lt;span class="op"&gt;=&lt;/span&gt; pm.Beta(&lt;span class="st"&gt;'beta'&lt;/span&gt;, &lt;span class="dv"&gt;1&lt;/span&gt;, alpha, shape&lt;span class="op"&gt;=&lt;/span&gt;K)&lt;/span&gt;
&lt;span id="cb33-4"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb33-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    w &lt;span class="op"&gt;=&lt;/span&gt; pm.Deterministic(&lt;span class="st"&gt;'beta'&lt;/span&gt;, beta &lt;span class="op"&gt;*&lt;/span&gt; T.concatenate([[&lt;span class="dv"&gt;1&lt;/span&gt;], T.extra_ops.cumprod(&lt;span class="dv"&gt;1&lt;/span&gt; &lt;span class="op"&gt;-&lt;/span&gt; beta[:&lt;span class="op"&gt;-&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;])]))&lt;/span&gt;
&lt;span id="cb33-5"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb33-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    component &lt;span class="op"&gt;=&lt;/span&gt; pm.Categorical(&lt;span class="st"&gt;'component'&lt;/span&gt;, w, shape&lt;span class="op"&gt;=&lt;/span&gt;N)&lt;/span&gt;
&lt;span id="cb33-6"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb33-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id="cb33-7"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb33-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    mu &lt;span class="op"&gt;=&lt;/span&gt; pm.Uniform(&lt;span class="st"&gt;'mu'&lt;/span&gt;, &lt;span class="fl"&gt;0.&lt;/span&gt;, &lt;span class="fl"&gt;300.&lt;/span&gt;, shape&lt;span class="op"&gt;=&lt;/span&gt;K)&lt;/span&gt;
&lt;span id="cb33-8"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb33-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    obs &lt;span class="op"&gt;=&lt;/span&gt; pm.Poisson(&lt;span class="st"&gt;'obs'&lt;/span&gt;, mu[component], observed&lt;span class="op"&gt;=&lt;/span&gt;sunspot_df[&lt;span class="st"&gt;'sunspot.year'&lt;/span&gt;])&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;Applied log-transform to alpha and added transformed alpha_log to model.
Applied logodds-transform to beta and added transformed beta_logodds to model.
Applied interval-transform to mu and added transformed mu_interval to model.&lt;/code&gt;&lt;/pre&gt;
&lt;div class="sourceCode" id="cb35"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb35-1"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb35-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="cf"&gt;with&lt;/span&gt; model:&lt;/span&gt;
&lt;span id="cb35-2"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb35-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    step1 &lt;span class="op"&gt;=&lt;/span&gt; pm.Metropolis(&lt;span class="bu"&gt;vars&lt;/span&gt;&lt;span class="op"&gt;=&lt;/span&gt;[alpha, beta, w, mu, obs])&lt;/span&gt;
&lt;span id="cb35-3"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb35-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    step2 &lt;span class="op"&gt;=&lt;/span&gt; pm.ElemwiseCategoricalStep([component], np.arange(K))&lt;/span&gt;
&lt;span id="cb35-4"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb35-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id="cb35-5"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb35-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    trace_ &lt;span class="op"&gt;=&lt;/span&gt; pm.sample(&lt;span class="dv"&gt;20000&lt;/span&gt;, [step1, step2])&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt; [-----------------100%-----------------] 20000 of 20000 complete in 111.9 sec&lt;/code&gt;&lt;/pre&gt;
&lt;div class="sourceCode" id="cb37"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb37-1"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb37-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;trace &lt;span class="op"&gt;=&lt;/span&gt; trace_[&lt;span class="dv"&gt;10000&lt;/span&gt;::&lt;span class="dv"&gt;10&lt;/span&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For the sunspot model, the posterior distribution of &lt;span class="math inline"&gt;\(\alpha\)&lt;/span&gt; is concentrated between one and three, indicating that we should expect more components to contribute non-negligible amounts to the mixture than for the Old Faithful waiting time model.&lt;/p&gt;
&lt;div class="sourceCode" id="cb38"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb38-1"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb38-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;pm.traceplot(trace, varnames&lt;span class="op"&gt;=&lt;/span&gt;[&lt;span class="st"&gt;'alpha'&lt;/span&gt;])&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;center&gt;
&lt;img src="https://austinrochford.com/resources/dpm_density/Density%20Estimation%20with%20Dirichlet%20Process%20Mixtures%20using%20PyMC3_49_0.png"&gt;
&lt;/center&gt;
&lt;p&gt;Indeed, we see that there are (on average) about ten to fifteen components used by this model.&lt;/p&gt;
&lt;div class="sourceCode" id="cb39"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb39-1"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb39-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;n_components_used &lt;span class="op"&gt;=&lt;/span&gt; np.apply_along_axis(&lt;span class="kw"&gt;lambda&lt;/span&gt; x: np.unique(x).size, &lt;span class="dv"&gt;1&lt;/span&gt;, trace[&lt;span class="st"&gt;'component'&lt;/span&gt;])&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="sourceCode" id="cb40"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb40-1"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb40-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;fig, ax &lt;span class="op"&gt;=&lt;/span&gt; plt.subplots(figsize&lt;span class="op"&gt;=&lt;/span&gt;(&lt;span class="dv"&gt;8&lt;/span&gt;, &lt;span class="dv"&gt;6&lt;/span&gt;))&lt;/span&gt;
&lt;span id="cb40-2"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb40-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb40-3"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb40-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;bins &lt;span class="op"&gt;=&lt;/span&gt; np.arange(n_components_used.&lt;span class="bu"&gt;min&lt;/span&gt;(), n_components_used.&lt;span class="bu"&gt;max&lt;/span&gt;() &lt;span class="op"&gt;+&lt;/span&gt; &lt;span class="dv"&gt;1&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb40-4"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb40-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.hist(n_components_used &lt;span class="op"&gt;+&lt;/span&gt; &lt;span class="dv"&gt;1&lt;/span&gt;, bins&lt;span class="op"&gt;=&lt;/span&gt;bins, normed&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="va"&gt;True&lt;/span&gt;, lw&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;0&lt;/span&gt;, alpha&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="fl"&gt;0.75&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb40-5"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb40-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb40-6"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb40-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.set_xticks(bins &lt;span class="op"&gt;+&lt;/span&gt; &lt;span class="fl"&gt;0.5&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb40-7"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb40-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.set_xticklabels(bins)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb40-8"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb40-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.set_xlim(bins.&lt;span class="bu"&gt;min&lt;/span&gt;(), bins.&lt;span class="bu"&gt;max&lt;/span&gt;() &lt;span class="op"&gt;+&lt;/span&gt; &lt;span class="dv"&gt;1&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb40-9"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb40-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.set_xlabel(&lt;span class="st"&gt;'Number of mixture components used'&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb40-10"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb40-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb40-11"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb40-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.set_ylabel(&lt;span class="st"&gt;'Posterior probability'&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;center&gt;
&lt;img src="https://austinrochford.com/resources/dpm_density/Density%20Estimation%20with%20Dirichlet%20Process%20Mixtures%20using%20PyMC3_52_0.png"&gt;
&lt;/center&gt;
&lt;p&gt;We now calculate and plot the fitted density estimate.&lt;/p&gt;
&lt;div class="sourceCode" id="cb41"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb41-1"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb41-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;x_plot &lt;span class="op"&gt;=&lt;/span&gt; np.arange(&lt;span class="dv"&gt;250&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="sourceCode" id="cb42"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb42-1"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb42-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;post_pmf_contribs &lt;span class="op"&gt;=&lt;/span&gt; sp.stats.poisson.pmf(np.atleast_3d(x_plot),&lt;/span&gt;
&lt;span id="cb42-2"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb42-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;                                         trace[&lt;span class="st"&gt;'mu'&lt;/span&gt;][:, np.newaxis, :])&lt;/span&gt;
&lt;span id="cb42-3"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb42-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;post_pmfs &lt;span class="op"&gt;=&lt;/span&gt; (trace[&lt;span class="st"&gt;'beta'&lt;/span&gt;][:, np.newaxis, :] &lt;span class="op"&gt;*&lt;/span&gt; post_pmf_contribs).&lt;span class="bu"&gt;sum&lt;/span&gt;(axis&lt;span class="op"&gt;=-&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb42-4"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb42-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb42-5"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb42-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;post_pmf_low, post_pmf_high &lt;span class="op"&gt;=&lt;/span&gt; np.percentile(post_pmfs, [&lt;span class="fl"&gt;2.5&lt;/span&gt;, &lt;span class="fl"&gt;97.5&lt;/span&gt;], axis&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;0&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="sourceCode" id="cb43"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb43-1"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb43-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;fig, ax &lt;span class="op"&gt;=&lt;/span&gt; plt.subplots(figsize&lt;span class="op"&gt;=&lt;/span&gt;(&lt;span class="dv"&gt;8&lt;/span&gt;, &lt;span class="dv"&gt;6&lt;/span&gt;))&lt;/span&gt;
&lt;span id="cb43-2"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb43-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb43-3"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb43-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.hist(sunspot_df[&lt;span class="st"&gt;'sunspot.year'&lt;/span&gt;].values, bins&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;40&lt;/span&gt;, normed&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="va"&gt;True&lt;/span&gt;, lw&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;0&lt;/span&gt;, alpha&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="fl"&gt;0.75&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb43-4"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb43-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb43-5"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb43-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.fill_between(x_plot, post_pmf_low, post_pmf_high,&lt;/span&gt;
&lt;span id="cb43-6"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb43-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;                 color&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'gray'&lt;/span&gt;, alpha&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="fl"&gt;0.45&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb43-7"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb43-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.plot(x_plot, post_pmfs[&lt;span class="dv"&gt;0&lt;/span&gt;],&lt;/span&gt;
&lt;span id="cb43-8"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb43-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        c&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'gray'&lt;/span&gt;, label&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'Posterior sample densities'&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb43-9"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb43-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.plot(x_plot, post_pmfs[::&lt;span class="dv"&gt;200&lt;/span&gt;].T, c&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'gray'&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb43-10"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb43-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.plot(x_plot, post_pmfs.mean(axis&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;0&lt;/span&gt;),&lt;/span&gt;
&lt;span id="cb43-11"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb43-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        c&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'k'&lt;/span&gt;, label&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'Posterior expected density'&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb43-12"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb43-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb43-13"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb43-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.legend(loc&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;center&gt;
&lt;img src="https://austinrochford.com/resources/dpm_density/Density%20Estimation%20with%20Dirichlet%20Process%20Mixtures%20using%20PyMC3_56_0.png"&gt;
&lt;/center&gt;
&lt;p&gt;Again, we can decompose the posterior expected density into weighted mixture densities.&lt;/p&gt;
&lt;div class="sourceCode" id="cb44"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb44-1"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb44-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;fig, ax &lt;span class="op"&gt;=&lt;/span&gt; plt.subplots(figsize&lt;span class="op"&gt;=&lt;/span&gt;(&lt;span class="dv"&gt;8&lt;/span&gt;, &lt;span class="dv"&gt;6&lt;/span&gt;))&lt;/span&gt;
&lt;span id="cb44-2"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb44-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb44-3"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb44-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.hist(sunspot_df[&lt;span class="st"&gt;'sunspot.year'&lt;/span&gt;].values, bins&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;40&lt;/span&gt;, normed&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="va"&gt;True&lt;/span&gt;, lw&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;0&lt;/span&gt;, alpha&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="fl"&gt;0.75&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb44-4"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb44-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.plot(x_plot, post_pmfs.mean(axis&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;0&lt;/span&gt;),&lt;/span&gt;
&lt;span id="cb44-5"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb44-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        c&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'k'&lt;/span&gt;, label&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'Posterior expected density'&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb44-6"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb44-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.plot(x_plot, (trace[&lt;span class="st"&gt;'beta'&lt;/span&gt;][:, np.newaxis, :] &lt;span class="op"&gt;*&lt;/span&gt; post_pmf_contribs).mean(axis&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;0&lt;/span&gt;)[:, &lt;span class="dv"&gt;0&lt;/span&gt;],&lt;/span&gt;
&lt;span id="cb44-7"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb44-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="st"&gt;'--'&lt;/span&gt;, c&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'k'&lt;/span&gt;, label&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'Posterior expected&lt;/span&gt;&lt;span class="ch"&gt;\n&lt;/span&gt;&lt;span class="st"&gt;mixture components&lt;/span&gt;&lt;span class="ch"&gt;\n&lt;/span&gt;&lt;span class="st"&gt;(weighted)'&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb44-8"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb44-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.plot(x_plot, (trace[&lt;span class="st"&gt;'beta'&lt;/span&gt;][:, np.newaxis, :] &lt;span class="op"&gt;*&lt;/span&gt; post_pmf_contribs).mean(axis&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;0&lt;/span&gt;),&lt;/span&gt;
&lt;span id="cb44-9"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb44-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="st"&gt;'--'&lt;/span&gt;, c&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'k'&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb44-10"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb44-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb44-11"&gt;&lt;a href="https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html#cb44-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;ax.legend(loc&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;center&gt;
&lt;img src="https://austinrochford.com/resources/dpm_density/Density%20Estimation%20with%20Dirichlet%20Process%20Mixtures%20using%20PyMC3_58_0.png"&gt;
&lt;/center&gt;
&lt;p&gt;We have only scratched the surface in terms of applications of the Dirichlet process and Bayesian nonparametric statistics in general. This post is the first in a series I have planned on Bayesian nonparametrics, so stay tuned.&lt;/p&gt;
&lt;p&gt;This post is available as an &lt;a href="http://ipython.org/"&gt;IPython&lt;/a&gt; notebook &lt;a href="https://nbviewer.jupyter.org/gist/AustinRochford/62c283a3f0fae90b5e39"&gt;here&lt;/a&gt;.&lt;/p&gt;</description><category>Bayesian Nonparametric Statistics</category><category>Bayesian Statistics</category><category>Dirichlet Processes</category><category>Nonparametric Statistics</category><category>PyMC3</category><guid>https://austinrochford.com/posts/2016-02-25-density-estimation-dpm.html</guid><pubDate>Thu, 25 Feb 2016 05:00:00 GMT</pubDate></item><item><title>Nonparametric Bayesian Regression with Gaussian Processes</title><link>https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html</link><dc:creator>Austin Rochford</dc:creator><description>&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Non-parametric_statistics"&gt;Nonparametric statistics&lt;/a&gt; is a branch of statistics concerned with analyzing data without assuming that the data are generated from any particular probability distribution. Since they make fewer assumptions about the process that generated the data, nonparametric tests are often more generally applicable than their parametric counterparts. Nonparametric methods are also generally more &lt;a href="http://en.wikipedia.org/wiki/Robust_statistics"&gt;robust&lt;/a&gt; than their parametric counterparts. These advantages are balanced by the fact that when the data are generated by a known probability distribution, the appropriate parametric tests are more &lt;a href="http://en.wikipedia.org/wiki/Parametric_statistics"&gt;powerful&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In this post, we’ll explore a Bayesian approach to nonparametric regression, which allows us to model complex functions with relatively weak assumptions.&lt;/p&gt;
&lt;h4 id="a-prior-on-functions"&gt;A Prior on Functions&lt;/h4&gt;
&lt;p&gt;We will study the model &lt;span class="math inline"&gt;\(y = f(x) + \varepsilon\)&lt;/span&gt;, where &lt;span class="math inline"&gt;\(f\)&lt;/span&gt; is the true regression function we wish to model, and &lt;span class="math inline"&gt;\(\varepsilon\)&lt;/span&gt; is Gaussian noise. Given observations &lt;span class="math inline"&gt;\((x_1, y_1), \ldots, (x_n, y_n)\)&lt;/span&gt; from this model, we wish to predict the value of &lt;span class="math inline"&gt;\(f\)&lt;/span&gt; at new &lt;span class="math inline"&gt;\(x\)&lt;/span&gt;-values. Let &lt;span class="math inline"&gt;\(X = (x_1, \ldots, x_n)^\top\)&lt;/span&gt; be the column vector of the observed &lt;span class="math inline"&gt;\(x\)&lt;/span&gt;-values, and similarly let &lt;span class="math inline"&gt;\(Y = (y_1, \ldots, y_n)^\top\)&lt;/span&gt;. Our goal is to use these observations to predict the value of &lt;span class="math inline"&gt;\(f\)&lt;/span&gt; at any given point with as much accuracy as possible.&lt;/p&gt;
&lt;p&gt;The Bayesian approach to this problem is to calculate the &lt;a href="http://en.wikipedia.org/wiki/Posterior_predictive_distribution"&gt;posterior predictive distribution&lt;/a&gt;, &lt;span class="math inline"&gt;\(p(f_* | X, Y, x_*)\)&lt;/span&gt; of the value of &lt;span class="math inline"&gt;\(f\)&lt;/span&gt; at a point &lt;span class="math inline"&gt;\(x_*\)&lt;/span&gt;. With this distribution in hand, we, if necessary, employ &lt;a href="http://en.wikipedia.org/wiki/Decision_theory"&gt;decision-theoretic&lt;/a&gt; machinery to produce point estimates for the value of &lt;span class="math inline"&gt;\(f\)&lt;/span&gt; at &lt;span class="math inline"&gt;\(x_*\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;As the nonparametric approach makes as few assumptions about the regression function as possible, a natural first step would seem to be to place a prior distribution &lt;span class="math inline"&gt;\(\pi(f)\)&lt;/span&gt; on all possible regression functions. In this case, the posterior predictive distribution is&lt;/p&gt;
&lt;p&gt;&lt;span class="math display"&gt;\[\begin{align*}
p(f_* | X, Y, x_*)
    &amp;amp; = \int_f p(f_* | f, x_*)\ p(f | X, Y)\ df \\
    &amp;amp; \propto \int_f p(f_* | f, x_*)\ p(Y | f, X)\ \pi(f) df.
\end{align*}\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Observant readers have certainly noticed that above we integrate with respect to an unspecified measure &lt;span class="math inline"&gt;\(df\)&lt;/span&gt;. If we make the often-reasonable assumption that &lt;span class="math inline"&gt;\(f\)&lt;/span&gt; is continuous on a compact interval &lt;span class="math inline"&gt;\([0, T]\)&lt;/span&gt; (for &lt;span class="math inline"&gt;\(T &amp;lt; \infty\)&lt;/span&gt;), we may choose &lt;span class="math inline"&gt;\(df\)&lt;/span&gt; to be the &lt;a href="http://en.wikipedia.org/wiki/Classical_Wiener_space#Classical_Wiener_measure"&gt;Weiner measure&lt;/a&gt;, which is closely related to &lt;a href="http://en.wikipedia.org/wiki/Brownian_motion"&gt;Brownian motion&lt;/a&gt;. Unfortunately, this approach has a few drawbacks. First, it may be difficult to choose a decent prior on the contiuous functions on the interval &lt;span class="math inline"&gt;\([0, T]\)&lt;/span&gt; (even the uniform prior will be improper). Even if we manage to choose a good prior, the integral with respect to the Weiner measure may not be easy (or even possible) to calculate or approximate.&lt;/p&gt;
&lt;h4 id="gaussian-processes"&gt;Gaussian Processes&lt;/h4&gt;
&lt;p&gt;The key realization about this situation that allows us to sidestep the difficulty in calculating the posterior predictive distribution in the manner detailed above is to consider the joint distribution of the observed and predicted values of &lt;span class="math inline"&gt;\(f\)&lt;/span&gt;. Suppose that given our observations, we want to predict the value of &lt;span class="math inline"&gt;\(f\)&lt;/span&gt; at the points &lt;span class="math inline"&gt;\(x_{*, 1}, \ldots x_{*, m}\)&lt;/span&gt;. Again, let &lt;span class="math inline"&gt;\(X_* = (x_{*, 1}, \ldots, x_{*, m})^\top\)&lt;/span&gt; and &lt;span class="math inline"&gt;\(Y_* = (f(x_{*, 1}), \ldots, f(x_{*, m}))^\top\)&lt;/span&gt;. With this notation, we want to model the joint distribution of the random variables &lt;span class="math inline"&gt;\(Y\)&lt;/span&gt; and &lt;span class="math inline"&gt;\(Y_*\)&lt;/span&gt;. After choosing a joint distribution, we can condition on the observed value of &lt;span class="math inline"&gt;\(Y\)&lt;/span&gt; (and &lt;span class="math inline"&gt;\(X\)&lt;/span&gt; and &lt;span class="math inline"&gt;\(X_*\)&lt;/span&gt;) to obtain a posterior predictive distribution for &lt;span class="math inline"&gt;\(Y_*\)&lt;/span&gt;. In this approach, specifying the joint distribution of &lt;span class="math inline"&gt;\(Y\)&lt;/span&gt; and &lt;span class="math inline"&gt;\(Y_*\)&lt;/span&gt; has taken the place of specifying a prior distribution on regression functions.&lt;/p&gt;
&lt;p&gt;We obtain a flexible model for the joint distribution of &lt;span class="math inline"&gt;\(Y\)&lt;/span&gt; and &lt;span class="math inline"&gt;\(Y_*\)&lt;/span&gt; by considering the set &lt;span class="math inline"&gt;\(\{f(x) | x \in \mathbb{R}\}\)&lt;/span&gt; to be a &lt;a href="http://en.wikipedia.org/wiki/Gaussian_process"&gt;Gaussian Process&lt;/a&gt;. That is, for any finite number of points &lt;span class="math inline"&gt;\(x_1, \ldots, x_n \in \mathbb{R}\)&lt;/span&gt;, the random variables &lt;span class="math inline"&gt;\(f(x_1), \ldots, f(x_n)\)&lt;/span&gt; have a &lt;a href="http://en.wikipedia.org/wiki/Multivariate_normal_distribution"&gt;multivariate normal distribution&lt;/a&gt;. While at first it may seem that modelling &lt;span class="math inline"&gt;\(f\)&lt;/span&gt; with a Gaussian process is a parametric approach to the problem, mean vector and covarience matrix of the multivariate normal (generally) depend explicitly on the points &lt;span class="math inline"&gt;\(x_1, \ldots, x_n\)&lt;/span&gt;, making this approach quite flexible and nonparametric. The Gaussian process for &lt;span class="math inline"&gt;\(f\)&lt;/span&gt; is specified by a mean function &lt;span class="math inline"&gt;\(m(x)\)&lt;/span&gt; and a covariance function &lt;span class="math inline"&gt;\(k(x, x')\)&lt;/span&gt;. In this context, we write that &lt;span class="math inline"&gt;\(f \sim GP(m, k)\)&lt;/span&gt;. The advantage of this approach is that the Gaussian process model is quite flexible, due to the ability to specify different mean and covariance functions, while still allowing for exact calculation of the predictions.&lt;/p&gt;
&lt;p&gt;For the purposes of this post, we will assume that the mean of our Gaussian process is zero; we will see later that this is not a terribly restrictive assumption. Much more important than the choice of a mean function is the choice of a covariance function, &lt;span class="math inline"&gt;\(k\)&lt;/span&gt;. In general, &lt;span class="math inline"&gt;\(k\)&lt;/span&gt; must be &lt;a href="http://en.wikipedia.org/wiki/Positive-definite_matrix"&gt;positive-definite&lt;/a&gt; in the sense that for any &lt;span class="math inline"&gt;\(X = (x_1, \ldots x_n)\)&lt;/span&gt;, &lt;span class="math inline"&gt;\(k(X, X) = (k(x_i, x_j))_{i, j}\)&lt;/span&gt; is a positive-definite matrix. This restriction is necessary in order for the covariance matrices of the multivariate normal distributions obtained from the Gaussian process to be sensible. There are &lt;a href="http://en.wikipedia.org/wiki/Gaussian_process#Usual_covariance_functions"&gt;far too many&lt;/a&gt; choices of covariance function to list in detail here. In this post, we will use the common squared-exponential covariance function,&lt;/p&gt;
&lt;p&gt;&lt;span class="math display"&gt;\[k(x, x') = \exp\left(-\frac{(x - x')^2}{2 \ell^2}\right).\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The parameter &lt;span class="math inline"&gt;\(\ell\)&lt;/span&gt; controls how quickly the function &lt;span class="math inline"&gt;\(f\)&lt;/span&gt; may fluctuate. Small values of &lt;span class="math inline"&gt;\(\ell\)&lt;/span&gt; allow &lt;span class="math inline"&gt;\(f\)&lt;/span&gt; to fluctuate rapidly, while large values of &lt;span class="math inline"&gt;\(\ell\)&lt;/span&gt; allow &lt;span class="math inline"&gt;\(f\)&lt;/span&gt; to fluctuate slowly. The following diagram shows samples from Gaussian processes with different values of &lt;span class="math inline"&gt;\(\ell\)&lt;/span&gt;.&lt;/p&gt;
&lt;div class="sourceCode" id="cb1"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb1-1"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb1-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;def&lt;/span&gt; k(x1, x2, l&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="fl"&gt;1.0&lt;/span&gt;):&lt;/span&gt;
&lt;span id="cb1-2"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb1-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="cf"&gt;return&lt;/span&gt; np.exp(&lt;span class="op"&gt;-&lt;/span&gt;np.subtract.outer(x1, x2)&lt;span class="op"&gt;**&lt;/span&gt;&lt;span class="dv"&gt;2&lt;/span&gt; &lt;span class="op"&gt;/&lt;/span&gt; (&lt;span class="dv"&gt;2&lt;/span&gt; &lt;span class="op"&gt;*&lt;/span&gt; l&lt;span class="op"&gt;**&lt;/span&gt;&lt;span class="dv"&gt;2&lt;/span&gt;))&lt;/span&gt;
&lt;span id="cb1-3"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb1-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb1-4"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb1-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;def&lt;/span&gt; sample_gp(xs, m&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="va"&gt;None&lt;/span&gt;, k&lt;span class="op"&gt;=&lt;/span&gt;k, l&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="fl"&gt;1.0&lt;/span&gt;, size&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="dv"&gt;1&lt;/span&gt;):&lt;/span&gt;
&lt;span id="cb1-5"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb1-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="cf"&gt;if&lt;/span&gt; m &lt;span class="kw"&gt;is&lt;/span&gt; &lt;span class="va"&gt;None&lt;/span&gt;:&lt;/span&gt;
&lt;span id="cb1-6"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb1-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        mean &lt;span class="op"&gt;=&lt;/span&gt; np.zeros_like(xs)&lt;/span&gt;
&lt;span id="cb1-7"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb1-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="cf"&gt;else&lt;/span&gt;:&lt;/span&gt;
&lt;span id="cb1-8"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb1-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        mean &lt;span class="op"&gt;=&lt;/span&gt; m(xs)&lt;/span&gt;
&lt;span id="cb1-9"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb1-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id="cb1-10"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb1-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    cov &lt;span class="op"&gt;=&lt;/span&gt; k(xs, xs, l)&lt;/span&gt;
&lt;span id="cb1-11"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb1-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;/span&gt;
&lt;span id="cb1-12"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb1-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    samples &lt;span class="op"&gt;=&lt;/span&gt; np.random.multivariate_normal(mean, cov, size&lt;span class="op"&gt;=&lt;/span&gt;size)&lt;/span&gt;
&lt;span id="cb1-13"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb1-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id="cb1-14"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb1-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="cf"&gt;if&lt;/span&gt; size &lt;span class="op"&gt;==&lt;/span&gt; &lt;span class="dv"&gt;1&lt;/span&gt;:&lt;/span&gt;
&lt;span id="cb1-15"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb1-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="cf"&gt;return&lt;/span&gt; samples[&lt;span class="dv"&gt;0&lt;/span&gt;]&lt;/span&gt;
&lt;span id="cb1-16"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb1-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="cf"&gt;else&lt;/span&gt;:&lt;/span&gt;
&lt;span id="cb1-17"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb1-17" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="cf"&gt;return&lt;/span&gt; samples&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;center&gt;
&lt;img src="https://austinrochford.com/resources/bayesian-nonparametric-gp/samples.png" title="fig:" alt="png"&gt;
&lt;/center&gt;
&lt;h4 id="gaussian-process-regression"&gt;Gaussian Process Regression&lt;/h4&gt;
&lt;p&gt;Now that we have introducted the basics of Gaussian processes, it is time to use them for regression. Using the notation from above, the joint distribution of &lt;span class="math inline"&gt;\(Y\)&lt;/span&gt;, the values of &lt;span class="math inline"&gt;\(f\)&lt;/span&gt; at the observed points, and &lt;span class="math inline"&gt;\(Y_*\)&lt;/span&gt;, the values of &lt;span class="math inline"&gt;\(f\)&lt;/span&gt; at the points to be predicted, is normal with mean zero and covariance matrix&lt;/p&gt;
&lt;p&gt;&lt;span class="math display"&gt;\[\Sigma = \begin{pmatrix}
k(X, X) + \sigma^2 I &amp;amp; k(X, X_*) \\
k(X_*, X) &amp;amp; k(X_*, X_*)
\end{pmatrix}.\]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;In &lt;span class="math inline"&gt;\(\Sigma\)&lt;/span&gt;, only the top left block contains a noise term. The top right and bottom left blocks have no noise term because the entries of &lt;span class="math inline"&gt;\(Y\)&lt;/span&gt; and &lt;span class="math inline"&gt;\(Y_*\)&lt;/span&gt; are uncorrelated (since the noise is i.i.d). The bottom right block has no noise term because we want to predict the actual value of &lt;span class="math inline"&gt;\(f\)&lt;/span&gt; at each point &lt;span class="math inline"&gt;\(x_*, i\)&lt;/span&gt;, not its value plus noise.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Multivariate_normal_distribution#Conditional_distributions"&gt;Conditioning&lt;/a&gt; on the observations &lt;span class="math inline"&gt;\(Y = y\)&lt;/span&gt;, we get that &lt;span class="math inline"&gt;\(Y_* | Y = y\)&lt;/span&gt; is normal with mean &lt;span class="math inline"&gt;\(\mu_y = k(X_*, X) (k(X, X) + \sigma^2 I)^{-1} y\)&lt;/span&gt; and covariance &lt;span class="math inline"&gt;\(\Sigma_y = k(X_*, X_*) - k(X_*, X) (k(X, X) + \sigma^2 I)^{-1} k(X, X_*)\)&lt;/span&gt;.&lt;/p&gt;
&lt;h4 id="a-toy-example"&gt;A Toy Example&lt;/h4&gt;
&lt;p&gt;As a toy example, we will use Gaussian process regression to model the function &lt;span class="math inline"&gt;\(f(x) = 5 \sin x + \sin 5 x\)&lt;/span&gt; on the interval &lt;span class="math inline"&gt;\([0, \pi]\)&lt;/span&gt;, with i.i.d. Gaussian noise with standard deviation &lt;span class="math inline"&gt;\(\sigma = 0.2\)&lt;/span&gt; using twenty samples.&lt;/p&gt;
&lt;div class="sourceCode" id="cb2"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb2-1"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb2-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;def&lt;/span&gt; f(x):&lt;/span&gt;
&lt;span id="cb2-2"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb2-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="cf"&gt;return&lt;/span&gt; &lt;span class="dv"&gt;5&lt;/span&gt; &lt;span class="op"&gt;*&lt;/span&gt; np.sin(x) &lt;span class="op"&gt;+&lt;/span&gt; np.sin(&lt;span class="dv"&gt;5&lt;/span&gt; &lt;span class="op"&gt;*&lt;/span&gt; x)&lt;/span&gt;
&lt;span id="cb2-3"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb2-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-4"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb2-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-5"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb2-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;n &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dv"&gt;20&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-6"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb2-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;sigma &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="fl"&gt;0.2&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-7"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb2-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-8"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb2-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;sample_xs &lt;span class="op"&gt;=&lt;/span&gt; sp.stats.uniform.rvs(scale&lt;span class="op"&gt;=&lt;/span&gt;np.pi, size&lt;span class="op"&gt;=&lt;/span&gt;n)&lt;/span&gt;
&lt;span id="cb2-9"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb2-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;sample_ys &lt;span class="op"&gt;=&lt;/span&gt; f(sample_xs) &lt;span class="op"&gt;+&lt;/span&gt; sp.stats.norm.rvs(scale&lt;span class="op"&gt;=&lt;/span&gt;sigma, size&lt;span class="op"&gt;=&lt;/span&gt;n)&lt;/span&gt;
&lt;span id="cb2-10"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb2-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-11"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb2-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;xs &lt;span class="op"&gt;=&lt;/span&gt; np.linspace(&lt;span class="dv"&gt;0&lt;/span&gt;, np.pi, &lt;span class="dv"&gt;100&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;center&gt;
&lt;img src="https://austinrochford.com/resources/bayesian-nonparametric-gp/function.png" title="fig:" alt="png"&gt;
&lt;/center&gt;
&lt;p&gt;The following class implements this approach to Gaussian process regression as a sublcass of &lt;code&gt;scikit-learn&lt;/code&gt;’s &lt;a href="http://scikit-learn.org/dev/modules/generated/sklearn.base.BaseEstimator.html"&gt;&lt;code&gt;sklearn.base.BaseEstimator&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;div class="sourceCode" id="cb3"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb3-1"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb3-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;class&lt;/span&gt; GPRegression(BaseEstimator):&lt;/span&gt;
&lt;span id="cb3-2"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb3-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;__init__&lt;/span&gt;(&lt;span class="va"&gt;self&lt;/span&gt;, l&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="fl"&gt;1.0&lt;/span&gt;, sigma&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="fl"&gt;0.0&lt;/span&gt;):&lt;/span&gt;
&lt;span id="cb3-3"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb3-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="va"&gt;self&lt;/span&gt;.l &lt;span class="op"&gt;=&lt;/span&gt; l&lt;/span&gt;
&lt;span id="cb3-4"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb3-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="va"&gt;self&lt;/span&gt;.sigma &lt;span class="op"&gt;=&lt;/span&gt; sigma&lt;/span&gt;
&lt;span id="cb3-5"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb3-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id="cb3-6"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb3-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;def&lt;/span&gt; confidence_band(&lt;span class="va"&gt;self&lt;/span&gt;, X, alpha&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="fl"&gt;0.05&lt;/span&gt;):&lt;/span&gt;
&lt;span id="cb3-7"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb3-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="co"&gt;"""&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-8"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb3-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;        Calculates pointwise confidence bands with coverage 1 - alpha&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-9"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb3-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;        """&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-10"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb3-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        mean &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="va"&gt;self&lt;/span&gt;.mean(X)&lt;/span&gt;
&lt;span id="cb3-11"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb3-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        cov &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="va"&gt;self&lt;/span&gt;.cov(X)&lt;/span&gt;
&lt;span id="cb3-12"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb3-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        std &lt;span class="op"&gt;=&lt;/span&gt; np.sqrt(np.diag(cov))&lt;/span&gt;
&lt;span id="cb3-13"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb3-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;/span&gt;
&lt;span id="cb3-14"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb3-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        upper &lt;span class="op"&gt;=&lt;/span&gt; mean &lt;span class="op"&gt;+&lt;/span&gt; std &lt;span class="op"&gt;*&lt;/span&gt; sp.stats.norm.isf(alpha &lt;span class="op"&gt;/&lt;/span&gt; &lt;span class="dv"&gt;2&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb3-15"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb3-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        lower &lt;span class="op"&gt;=&lt;/span&gt; mean &lt;span class="op"&gt;-&lt;/span&gt; std &lt;span class="op"&gt;*&lt;/span&gt; sp.stats.norm.isf(alpha &lt;span class="op"&gt;/&lt;/span&gt; &lt;span class="dv"&gt;2&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb3-16"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb3-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;/span&gt;
&lt;span id="cb3-17"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb3-17" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="cf"&gt;return&lt;/span&gt; lower, upper&lt;/span&gt;
&lt;span id="cb3-18"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb3-18" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id="cb3-19"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb3-19" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;def&lt;/span&gt; cov(&lt;span class="va"&gt;self&lt;/span&gt;, X):&lt;/span&gt;
&lt;span id="cb3-20"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb3-20" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="cf"&gt;return&lt;/span&gt; k(X, X, &lt;span class="va"&gt;self&lt;/span&gt;.l) &lt;span class="op"&gt;-&lt;/span&gt; np.dot(k(X, &lt;span class="va"&gt;self&lt;/span&gt;.X, &lt;span class="va"&gt;self&lt;/span&gt;.l), &lt;/span&gt;
&lt;span id="cb3-21"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb3-21" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;                                 np.dot(np.linalg.inv(k(&lt;span class="va"&gt;self&lt;/span&gt;.X, &lt;span class="va"&gt;self&lt;/span&gt;.X, &lt;span class="va"&gt;self&lt;/span&gt;.l) &lt;/span&gt;
&lt;span id="cb3-22"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb3-22" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;                                                      &lt;span class="op"&gt;+&lt;/span&gt; &lt;span class="va"&gt;self&lt;/span&gt;.sigma&lt;span class="op"&gt;**&lt;/span&gt;&lt;span class="dv"&gt;2&lt;/span&gt; &lt;span class="op"&gt;*&lt;/span&gt; np.eye(&lt;span class="va"&gt;self&lt;/span&gt;.X.size)),&lt;/span&gt;
&lt;span id="cb3-23"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb3-23" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;                                        k(&lt;span class="va"&gt;self&lt;/span&gt;.X, X, &lt;span class="va"&gt;self&lt;/span&gt;.l)))&lt;/span&gt;
&lt;span id="cb3-24"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb3-24" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id="cb3-25"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb3-25" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;def&lt;/span&gt; fit(&lt;span class="va"&gt;self&lt;/span&gt;, X, y):&lt;/span&gt;
&lt;span id="cb3-26"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb3-26" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="va"&gt;self&lt;/span&gt;.X &lt;span class="op"&gt;=&lt;/span&gt; X&lt;/span&gt;
&lt;span id="cb3-27"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb3-27" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="va"&gt;self&lt;/span&gt;.y &lt;span class="op"&gt;=&lt;/span&gt; y&lt;/span&gt;
&lt;span id="cb3-28"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb3-28" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id="cb3-29"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb3-29" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;def&lt;/span&gt; mean(&lt;span class="va"&gt;self&lt;/span&gt;, X):&lt;/span&gt;
&lt;span id="cb3-30"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb3-30" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="cf"&gt;return&lt;/span&gt; np.dot(k(X, &lt;span class="va"&gt;self&lt;/span&gt;.X, &lt;span class="va"&gt;self&lt;/span&gt;.l),&lt;/span&gt;
&lt;span id="cb3-31"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb3-31" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;               np.dot(np.linalg.inv(k(&lt;span class="va"&gt;self&lt;/span&gt;.X, &lt;span class="va"&gt;self&lt;/span&gt;.X, &lt;span class="va"&gt;self&lt;/span&gt;.l)&lt;/span&gt;
&lt;span id="cb3-32"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb3-32" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;                        &lt;span class="op"&gt;+&lt;/span&gt; &lt;span class="va"&gt;self&lt;/span&gt;.sigma&lt;span class="op"&gt;**&lt;/span&gt;&lt;span class="dv"&gt;2&lt;/span&gt; &lt;span class="op"&gt;*&lt;/span&gt; np.eye(&lt;span class="va"&gt;self&lt;/span&gt;.X.size)),&lt;/span&gt;
&lt;span id="cb3-33"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb3-33" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;                      &lt;span class="va"&gt;self&lt;/span&gt;.y))&lt;/span&gt;
&lt;span id="cb3-34"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb3-34" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id="cb3-35"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb3-35" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="kw"&gt;def&lt;/span&gt; predict(&lt;span class="va"&gt;self&lt;/span&gt;, X):&lt;/span&gt;
&lt;span id="cb3-36"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb3-36" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="cf"&gt;return&lt;/span&gt; &lt;span class="va"&gt;self&lt;/span&gt;.mean(X)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Subclassing &lt;code&gt;BaseEstimator&lt;/code&gt; allows us to use &lt;code&gt;scikit-learn&lt;/code&gt;’s &lt;a href="http://scikit-learn.org/stable/model_selection.html"&gt;cross-validation tools&lt;/a&gt; to choose the values of the hyperparameters &lt;span class="math inline"&gt;\(\ell\)&lt;/span&gt; and &lt;span class="math inline"&gt;\(\sigma\)&lt;/span&gt;.&lt;/p&gt;
&lt;div class="sourceCode" id="cb4"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb4-1"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb4-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;gp &lt;span class="op"&gt;=&lt;/span&gt; GPRegression()&lt;/span&gt;
&lt;span id="cb4-2"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb4-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;param_grid &lt;span class="op"&gt;=&lt;/span&gt; {&lt;/span&gt;
&lt;span id="cb4-3"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb4-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;              &lt;span class="st"&gt;'l'&lt;/span&gt;: np.linspace(&lt;span class="fl"&gt;0.01&lt;/span&gt;, &lt;span class="fl"&gt;0.6&lt;/span&gt;, &lt;span class="dv"&gt;50&lt;/span&gt;),&lt;/span&gt;
&lt;span id="cb4-4"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb4-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;              &lt;span class="st"&gt;'sigma'&lt;/span&gt;: np.linspace(&lt;span class="dv"&gt;0&lt;/span&gt;, &lt;span class="fl"&gt;0.5&lt;/span&gt;, &lt;span class="dv"&gt;50&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb4-5"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb4-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;              }&lt;/span&gt;
&lt;span id="cb4-6"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb4-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb4-7"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb4-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;cv &lt;span class="op"&gt;=&lt;/span&gt; GridSearchCV(gp, param_grid, scoring&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;'mean_squared_error'&lt;/span&gt;)&lt;/span&gt;
&lt;span id="cb4-8"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb4-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;cv.fit(sample_xs, sample_ys)&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Cross-validation yields the following parameters, which produce a relatively small mean squared error.&lt;/p&gt;
&lt;div class="sourceCode" id="cb5"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb5-1"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb5-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;model &lt;span class="op"&gt;=&lt;/span&gt; GPRegression(&lt;span class="op"&gt;**&lt;/span&gt;cv.best_params_)&lt;/span&gt;
&lt;span id="cb5-2"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb5-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;model.fit(sample_xs, sample_ys)&lt;/span&gt;
&lt;span id="cb5-3"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb5-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;cv.best_params_&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="sourceCode" id="cb6"&gt;&lt;pre class="sourceCode python"&gt;&lt;code class="sourceCode python"&gt;&lt;span id="cb6-1"&gt;&lt;a href="https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html#cb6-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;{&lt;span class="st"&gt;'l'&lt;/span&gt;: &lt;span class="fl"&gt;0.40734693877551015&lt;/span&gt;, &lt;span class="st"&gt;'sigma'&lt;/span&gt;: &lt;span class="fl"&gt;0.1020408163265306&lt;/span&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The figure below shows the true regression function, &lt;span class="math inline"&gt;\(f(x) = 5 \sin x + \sin 5 x\)&lt;/span&gt; along with our Gaussian process regression estimate. It also shows a 95% pointwise confidence band around the estimated regression function.&lt;/p&gt;
&lt;center&gt;
&lt;img src="https://austinrochford.com/resources/bayesian-nonparametric-gp/fit.png" title="fig:" alt="png"&gt;
&lt;/center&gt;
&lt;p&gt;Note now near observed points, the confidence band shrinks drastically, while away from observed points it expands rapidly.&lt;/p&gt;
&lt;h4 id="section"&gt;&lt;/h4&gt;
&lt;h4 id="properties-of-gaussian-process-regression"&gt;Properties of Gaussian Process Regression&lt;/h4&gt;
&lt;p&gt;As our toy example shows, Gaussian processes are powerful and flexible tools for regression. Although we have only just scratched the surface of this vast field, some remarks about the general properties and utility of Gaussian process regression are in order. For a much more extensive introduction to Gaussian process consult the excellent book &lt;a href="http://www.gaussianprocess.org/gpml/"&gt;&lt;em&gt;Gaussian Processes for Machine Learning&lt;/em&gt;&lt;/a&gt;, which is freely available online.&lt;/p&gt;
&lt;p&gt;In general, Gaussian process regression is only effective when the covariance function and its parameters are appropriately chosen. Although we have used cross-validation to choose the parameter values in our toy example, for more serious problems, it is often much quicker to maximize the marginal likelihood directly by calculating its gradient.&lt;/p&gt;
&lt;p&gt;Our implementation of Gaussian process regression is numerically unstable, as it directly inverts the matrix &lt;span class="math inline"&gt;\(k(X, X) + \sigma^2 I\)&lt;/span&gt;. A more stable approach is to calculate the &lt;a href="http://en.wikipedia.org/wiki/Cholesky_decomposition"&gt;Cholesky decomposition&lt;/a&gt; of this matrix. Unfortuantely, calculating the Cholesky decomposition of an &lt;span class="math inline"&gt;\(n\)&lt;/span&gt;-dimensional matrix takes &lt;span class="math inline"&gt;\(O(n^3)\)&lt;/span&gt; time. In the context of Gaussian process regression, &lt;span class="math inline"&gt;\(n\)&lt;/span&gt; is the number of observations. If the number of training points is significant, the cubic complexity may be prohibitive. A number of approaches have been developed to approximate the results of Gaussian process regression with larger training sets. For more details on these approximations, consult Chapter 8 of &lt;em&gt;Gaussian Processes for Machine Learning&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;This post is &lt;a href="https://austinrochford.com/resources/bayesian-nonparametric-gp/notebook.ipynb"&gt;available&lt;/a&gt; as an IPython notebook.&lt;/p&gt;</description><category>Bayesian Statistics</category><category>Gaussian Processes</category><category>Nonparametric Statistics</category><guid>https://austinrochford.com/posts/2014-03-23-bayesian-nonparamtric-regression-gp.html</guid><pubDate>Sun, 23 Mar 2014 04:00:00 GMT</pubDate></item></channel></rss>