<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Inductio Ex Machina</title>
    <link href="http://mark.reid.name/blog/atom.xml" rel="self" />
    <link href="http://mark.reid.name" />
    <id>http://mark.reid.name/blog/atom.xml</id>
    <author>
        <name>Mark Reid</name>
        <email>mark@reid.name</email>
    </author>
    <updated>2013-05-14T00:00:00Z</updated>
    <entry>
    <title>Bayesian Updating as Regularised Optimisation</title>
    <link href="http://mark.reid.name/blog/bayesian-updating-as-optimisation.html" />
    <id>http://mark.reid.name/blog/bayesian-updating-as-optimisation.html</id>
    <published>2013-05-14T00:00:00Z</published>
    <updated>2013-05-14T00:00:00Z</updated>
    <summary type="html"><![CDATA[<div id="page">

<h1 class="emphnext">Bayesian Updating as Regularised Optimisation</h1>

<p>I recently attended a workshop at <a href="http://www.tsinghua.edu.cn/publish/csen/">Tsinghua University</a> in Beijing on social networking and machine learning. One of the more machine learning focused talks by <a href="http://www.ml-thu.net/~jun/">Jun Zhu</a> caught my attention with a simple but surprising generalisation of Bayesian updating which he and his co-authors call “Regularized Bayesian Inference” or <a href="http://www.ml-thu.net/~jun/research.shtml">RegBayes</a>.</p>
<p>The core idea is very simple: express classical Bayesian updating as an optimisation problem (see below) and then add constraints and regularisers to the posterior distribution. The advantage to this approach is that it affords an extra way to encode domain knowledge about problems.</p>
<p>The closest thing I’d seen to something like output regularisation was in a 2007 JMLR paper, <em><a href="http://jmlr.csail.mit.edu/papers/v8/rifkin07a.html">Value Regularization and Fenchel Duality</a></em> by Rifkin &amp; Lippert.<sup><a href="#fn1" class="footnoteRef" id="fnref1">1</a></sup> However, RegBayes specifically starts with Bayesian updating and regularises distributions instead of just values.</p>
<p>I really like seeing new takes on old ideas, so I thought I’d work through the representation of updating as optimisation. The derivation below is an expansion of what is worked through in Section 3.1 of a recent paper by Zhu, Chen, and Xing titled <em><a href="http://arxiv.org/abs/1210.1766v2">Bayesian Inference with Posterior Regularization and Infinite Latent SVMs</a></em>. Interested readers can also find an extended discussion, applications and connections with earlier work there.</p>
<h2 id="bayesian-updating-as-divergence-optimisation">Bayesian Updating as Divergence Optimisation</h2>
<p>We’ll start by letting <span class="math">\(\mathcal{M}\)</span> be a set of models and <span class="math">\(\Delta_\mathcal{M}\)</span> the set of distributions over <span class="math">\(\mathcal{M}\)</span>. If <span class="math">\(\pi(M)\)</span> denotes the prior probability of a model <span class="math">\(M \in \mathcal{M}\)</span> and <span class="math">\(p(D|M)\)</span> denote the data likelihood for <span class="math">\(D\)</span> given <span class="math">\(M\)</span> then, as everyone knows, Bayes’ rule states that the posterior <span class="math">\(p(M|D)\)</span> can be computed via <span class="math">\[
	p(M|D) = \frac{\pi(M) p(D|M)}{p(D)}
\]</span> where <span class="math">\(p(D)\)</span> is the marginal distribution over the data.</p>
<p>Now, it is well known that the <a href="http://en.wikipedia.org/wiki/Kullback–Leibler_divergence">KL divergence</a> from a distribution <span class="math">\(p\)</span> to a distribution <span class="math">\(q\)</span> — denoted <span class="math">\(KL(q\|p)\)</span> — is minimised and equal to zero when, and only when, <span class="math">\(q = p\)</span> (almost everywhere). This means that if we had some arbitrary distribution <span class="math">\(q(M)\)</span> over models and wanted to ensure it was equal to the posterior distribution <span class="math">\(p(M|D)\)</span> obtained by updating a prior <span class="math">\(\pi\)</span> with data <span class="math">\(D\)</span> we could do so in a round-about sort of way by solving the following optimisation problem: <span class="math">\[ \begin{equation} \inf_{q(M)}\ KL(q(M)\|p(M|D))\quad \text{s.t.}\quad  q \in \Delta_\mathcal{M}.\label{eq:kl} \end{equation}
\]</span> Although this is not a particularly interesting optimisation problem, things get a little more interesting if we expand the KL divergence term. Letting <span class="math">\(p_L = p(D|M)\)</span> denote the data likelihood and <span class="math">\(p_D = p(D)\)</span> the data marginal we see that <span class="math">\[ 
	KL\left(q\|\frac{\pi p_L}{p_D}\right) 
	= \mathbb{E}_q\left[\ln\frac{q}{\pi p_L / p_D}\right]
	= \mathbb{E}_q\left[\ln \frac{q}{\pi} - \ln p_L + \ln p_D\right]
\]</span> and so the <span class="math">\(KL\)</span> term in the optimisation problem above can be written as <span class="math">\[ \begin{align*} KL(q(M)\|p(M|D)) &amp;= KL(q(M)\|\pi(M) p(D|M) / p(D)) \\ &amp;= KL(q(M)\|\pi(M)) - \mathbb{E}_{M\sim q}\left[ \ln p(D|M) \right] + \ln p(D) \end{align*} \]</span> since <span class="math">\(p(D)\)</span> does not depend on <span class="math">\(M\)</span>. The <span class="math">\(\ln p(D)\)</span> term is also irrelevant for the optimisation in \eqref{eq:kl} so we can now express that problem as <span class="math">\[
	\inf_{q(M)}\ 
		\underbrace{KL(q(M)\|\pi(M))}_{\text{closeness to prior}} 
		+ 
		\underbrace{\mathbb{E}_{M\sim q}\left[ -\ln p(D|M) \right]}_{\text{fit to data}}
		\quad 
		\text{s.t.}\quad  q \in \Delta_\mathcal{M}.
\]</span></p>
<p>The nice thing about expressing the posterior as the solution of the above problem is that we can see the Bayesian updating as a trade-off between staying close to the prior and fitting the data. The KL term keeps the posterior close to the prior while the other term measures the expected log loss of the model’s ability to predict the data.</p>
<h2 id="adding-in-regularisation">Adding in Regularisation</h2>
<p>The interesting insight Jun and his co-authors had was that the above optimisation problem can be tweaked slightly by adding either extra constraints to where <span class="math">\(q\)</span> can lie in <span class="math">\(\Delta_\mathcal{M}\)</span> or by adding an additional regularisation term <span class="math">\(U(q)\)</span> which may or may not depend on the data. In its most general setting, updating a prior <span class="math">\(\pi\)</span> given data <span class="math">\(D\)</span> can be written as <span class="math">\[
	\inf_{q(M)}\ KL(q(M)\|\pi(M)) + \mathbb{E}_q\left[-\ln p(D|M)\right] + U(q(M))
	\quad
	\text{s.t.}\quad q\in\mathcal{Q}\]</span> where <span class="math">\(U\)</span> is a regulariser and <span class="math">\(\mathcal{Q}\subseteq \Delta_\mathcal{M}\)</span> are the allowable distributions. The distribution <span class="math">\(q(M)\)</span> solving the above problem is called the “post-data distribution” to distinguish it from the traditional posterior distribution.</p>
<h2 id="questions">Questions</h2>
<p>One question that sprung to mind when I first saw this was whether this setting is strictly more general than normal Bayesian updating. The regularisation and constraints control which post-data distribution is selected but could such a post-data distribution be achieved as the posterior of normal Bayesian updating for a different prior?</p>
<p>It turns out the answer is “no”. Since the regulariser <span class="math">\(U\)</span> can depend on the data, it is possible to create updating schemes that are not doing strict Bayesian updating. I’m not sure whether the same holds if <span class="math">\(U\)</span> and <span class="math">\(\mathcal{Q}\)</span> are not allowed to depend on the data but I suspect RegBayes would still be more general.</p>
<p>Some other questions that came up in my discussions with Jun included:</p>
<ul>
<li>What sort of convergence and consistency guarantees can be given for this scheme?</li>
<li>Could there be connections between RegBayes and PAC-Bayesian theory?</li>
<li>Could KL divergence and log loss be replaced by other <a href="http://jmlr.csail.mit.edu/papers/v12/reid11a.html">loss/divergence pairs</a>?</li>
<li>Do some choices of regulariser yield updates for non-standard uncertainty calculi?</li>
</ul>
<p>I haven’t yet spent much time thinking about these but I find this approach a fascinating way to couch the problem of managing uncertainty.</p>
<div class="footnotes">
<hr />
<ol>
<li id="fn1"><p>In <a href="http://arxiv.org/abs/1210.1766v2">their paper</a>, Jun Zhu et al. point out a number of other, earlier works that inspired RegBayes but I had either not seen them or made the connection to Bayesian updating before.<a href="#fnref1">↩</a></p></li>
</ol>
</div>

<address class="signature">
  <a class="author" href="http://mark.reid.name">Mark Reid</a> 
  <span class="date">May 14, 2013</span>
  <span class="location">Canberra, Australia</span>
</address>

</div>

<!-- Disqus Comments -->
<div id="disqus_thread"></div>

<!-- Enable Disqus comments -->
<script type="text/javascript">
        var disqus_iframe_css = "http://mark.reid.name/css/screen.css";
        var disqus_title = "Bayesian Updating as Regularised Optimisation";
        var disqus_message = "A brief description and discussion of Zhu et al.'s RegBayes framework for generalising Bayesian updating.";
</script>
<script type="text/javascript" src="http://disqus.com/forums/markreid/embed.js"></script>

<noscript>
    <a href="http://markreid.disqus.com/?url=ref">View the discussion thread.</a>
</noscript>

]]></summary>
</entry>
<entry>
    <title>Machine Learning Research Jobs at NICTA</title>
    <link href="http://mark.reid.name/blog/machine-learning-jobs-at-nicta.html" />
    <id>http://mark.reid.name/blog/machine-learning-jobs-at-nicta.html</id>
    <published>2013-04-16T00:00:00Z</published>
    <updated>2013-04-16T00:00:00Z</updated>
    <summary type="html"><![CDATA[<div id="page">

<h1 class="emphnext">Machine Learning Research Jobs at NICTA</h1>

<p>This is just a short note to say that the <a href="http://nicta.com.au/research/machine_learning">machine learning group</a> that I am a part of at <a href="http://nicta.com.au/">NICTA</a> is <a href="http://nicta.com.au/research/machine_learning/job_opportunities">looking to hire</a> several new machine learning researchers. The full details of the positions can be found <a href="http://nicta.com.au/research/machine_learning/job_opportunities">here</a> and the links therein.</p>
<p>To summarise:</p>
<ul>
<li>Several full-time research positions in machine learning at NICTA are available.</li>
<li>Positions can be taken up in either the Sydney or Canberra labs.</li>
<li>Appointments are up to 3 years with the possibility of extension.</li>
<li>Includes adjunct status at either the <a href="http://cs.anu.edu.au/">Australian National University</a> or the <a href="http://sydney.edu.au/engineering/it/">University of Sydney</a>, with the ability to supervise PhD students.</li>
<li>Salaries from $85,000 to $100,000 (AUD) per annum.</li>
<li><strong>Application closing date: May 26th, 2013</strong>.</li>
</ul>
<p>On a personal note, I’ve been an ANU-contributed researcher at NICTA for the last four years and find it an excellent place to work. We’ve got a great collection of people with diverse interests across machine learning, lots of challenging theoretical and applied problems, fantastic students, and a solid publishing record at NIPS, ICML, COLT, and JMLR.</p>
<p>I’m happy to answer any questions about the research environment here. If you want more details about the position and how to apply, please <a href="http://nicta.com.au/research/machine_learning/job_opportunities">read the advertisement</a> and/or email <a href="http://www.nicta.com.au/people/williamsonb">Bob Williamson</a> (ML group leader) at <script type="text/javascript">
<!--
h='&#110;&#x69;&#x63;&#116;&#x61;&#46;&#x63;&#x6f;&#x6d;&#46;&#x61;&#x75;';a='&#64;';n='&#98;&#x6f;&#98;&#46;&#x77;&#x69;&#108;&#108;&#x69;&#x61;&#x6d;&#x73;&#x6f;&#110;';e=n+a+h;
document.write('<a h'+'ref'+'="ma'+'ilto'+':'+e+'">'+e+'<\/'+'a'+'>');
// -->
</script><noscript>&#98;&#x6f;&#98;&#46;&#x77;&#x69;&#108;&#108;&#x69;&#x61;&#x6d;&#x73;&#x6f;&#110;&#32;&#x61;&#116;&#32;&#110;&#x69;&#x63;&#116;&#x61;&#32;&#100;&#x6f;&#116;&#32;&#x63;&#x6f;&#x6d;&#32;&#100;&#x6f;&#116;&#32;&#x61;&#x75;</noscript>.</p>
<p>I hope you can join us!</p>

<address class="signature">
  <a class="author" href="http://mark.reid.name">Mark Reid</a> 
  <span class="date">April 16, 2013</span>
  <span class="location">Canberra, Australia</span>
</address>

</div>

<!-- Disqus Comments -->
<div id="disqus_thread"></div>

<!-- Enable Disqus comments -->
<script type="text/javascript">
        var disqus_iframe_css = "http://mark.reid.name/css/screen.css";
        var disqus_title = "Machine Learning Research Jobs at NICTA";
        var disqus_message = "Spreading the word about a number of machine learning research jobs at NICTA.";
</script>
<script type="text/javascript" src="http://disqus.com/forums/markreid/embed.js"></script>

<noscript>
    <a href="http://markreid.disqus.com/?url=ref">View the discussion thread.</a>
</noscript>

]]></summary>
</entry>
<entry>
    <title>Switching from Jekyll to Hakyll</title>
    <link href="http://mark.reid.name/blog/switching-to-hakyll.html" />
    <id>http://mark.reid.name/blog/switching-to-hakyll.html</id>
    <published>2013-03-26T00:00:00Z</published>
    <updated>2013-03-26T00:00:00Z</updated>
    <summary type="html"><![CDATA[<div id="page">

<h1 class="emphnext">Switching from Jekyll to Hakyll</h1>

<p>This is a non-machine learning-related post about a recent change to how I run this blog and the rest of my site. As you will notice, the design and content has largely stayed the same. However, I’ve made several changes under the hood that will make it easier for me to continue to develop my site.</p>
<p>The biggest change in my set up was shifting from using <a href="https://github.com/mojombo/jekyll">Jekyll</a> to generate my site to using <a href="http://jaspervdj.be/hakyll/">Hakyll</a>. I thought I would write up my experiences in case any one else in interested in making this switch.</p>
<h2 id="leaving-jekyll">Leaving Jekyll</h2>
<p>I’ll get this out of the way up front: Jekyll is fantastic and I would heartily recommend it to anyone wanting to set up a new statically generated site. It is easy to set up (especially if you use <a href="http://octopress.org">Octopress</a> or <a href="http://jekyllbootstrap.com">Jekyll Bootstrap</a>), has an activity community of developers led by the impressive <a href="http://tom.preston-werner.com">Tom Preston-Werner</a>, and you can easily host your site using <a href="http://pages.github.com">Github Pages</a>.</p>
<p>So why make the switch to Hakyll? The main reason is that I am using <a href="http://johnmacfarlane.net/pandoc/">Pandoc</a> as my main tool for rendering Markdown and wanted my site to do the same. Less crucially: I wanted an excuse to get back into using Haskell.</p>
<p>Yes, there is a <a href="https://github.com/dsanson/jekyll-pandoc-plugin">Jekyll plugin for pandoc</a> but I wasn’t keen on bringing another dependency into my already hard to maintain ruby environment. Also, after a bit of preliminary playing around with Hakyll I noticed it was substantially faster at generating my site than my Jekyll set up.</p>
<h2 id="using-hakyll">Using Hakyll</h2>
<p>As the name suggests, Hakyll is inspired by Jekyll but written in Haskell. Both systems are built around the idea of taking a folder full of blog posts written in markdown (or some other human-friendly markup language) and generating HTML by rendering their content and wrapping templates around them.</p>
<p>Jekyll follows the general ruby philosophy of “convention of configuration” and, out of the box, will look for specially named files (e.g., <code>*.md</code>) and folders (e.g., <code>_posts</code> and <code>_layouts</code>) to find the content and templates needed to build you site.</p>
<p>In constrast, Hakyll requires you to write a small Haskell program to describe how you want pages to be rendered using a very flexible “Rules” language. For example, in my <a href="https://github.com/mreid/markreidname-hakyll/blob/master/site.hs"><code>site.hs</code></a> file I use the following code to set up my CSS files and render and wrap my blog posts.</p>
<pre class="sourceCode haskell"><code class="sourceCode haskell">main <span class="fu">=</span> hakyllWith siteConfig <span class="fu">$</span> <span class="kw">do</span>
  <span class="co">-- CSS</span>
  match <span class="st">&quot;css/**&quot;</span> <span class="fu">$</span> <span class="kw">do</span>
    route   <span class="fu">$</span> idRoute
    compile <span class="fu">$</span> compressCssCompiler

  <span class="co">-- Posts</span>
  match <span class="st">&quot;blog/posts/*&quot;</span> <span class="fu">$</span> <span class="kw">do</span>
    route   <span class="fu">$</span> gsubRoute <span class="st">&quot;posts&quot;</span> (<span class="fu">const</span> <span class="st">&quot;&quot;</span>) <span class="ot">`composeRoutes`</span> rmDateRoute
    compile <span class="fu">$</span> blogPostCompiler <span class="kw">True</span>
  
<span class="co">-- Blog post compiler</span>
blogPostCompiler snapshot <span class="fu">=</span> mathJaxRenderer
  <span class="fu">&gt;&gt;=</span> loadAndApplyTemplate <span class="st">&quot;_templates/post/full.html&quot;</span> postCtx
  <span class="fu">&gt;&gt;=</span> (<span class="kw">if</span> snapshot <span class="kw">then</span> (saveSnapshot <span class="st">&quot;content&quot;</span>) <span class="kw">else</span> <span class="fu">return</span> <span class="fu">.</span> <span class="fu">id</span>)
  <span class="fu">&gt;&gt;=</span> loadAndApplyTemplate <span class="st">&quot;_templates/nav/blog.html&quot;</span> postCtx
  <span class="fu">&gt;&gt;=</span> loadAndApplyTemplate <span class="st">&quot;_templates/default.html&quot;</span> postCtx
  <span class="fu">&gt;&gt;=</span> relativizeUrls

<span class="co">-- Blog context</span>
postCtx <span class="fu">=</span>
  dateField <span class="st">&quot;date&quot;</span> <span class="st">&quot;%B %e, %Y&quot;</span> <span class="ot">`mappend`</span>
  dateField <span class="st">&quot;shortdate&quot;</span> <span class="st">&quot;%e %b %y&quot;</span> <span class="ot">`mappend`</span> 
  constField <span class="st">&quot;top&quot;</span> <span class="st">&quot;Inductio Ex Machina &amp;larr; Mark Reid&quot;</span> <span class="ot">`mappend`</span>
  constField <span class="st">&quot;section&quot;</span> <span class="st">&quot;Blog&quot;</span> <span class="ot">`mappend`</span>
  defaultContext

<span class="co">-- Take out the post/YYYY-MM-DD part from the post URL</span>
rmDateRoute <span class="fu">=</span> 
  gsubRoute <span class="st">&quot;/[0-9]{4}-[0-9]{2}-[0-9]{2}-&quot;</span> (<span class="fu">const</span> <span class="st">&quot;/&quot;</span>)
  <span class="ot">`composeRoutes`</span> setExtension <span class="st">&quot;html&quot;</span></code></pre>
<p>The <code>route</code> rule describes how the pattern in the <code>match</code> argument is converted into a URL. The <code>compile</code> rule describes how the items matching the pattern should be processed to build resource on your site.</p>
<p>In the case of the CSS files, each one is one through a (Hakyll provided) function that compresses the CSS by stripping whitespace.</p>
<p>Each of my blog posts starts life as a text file in my <code>blog/posts/</code> directory and has a name of the form <code>YYYY-MM-DD-title.md</code>. The <code>YYYY-MM-DD</code> part specifies the post’s creation date and the title is used to form the URL. The <code>route</code> that handles blog posts first strips out the <code>posts</code> part from the file’s path and removes the data part of the the filename. The <code>blogPostCompiler</code> then runs its contents through a Pandoc renderer with MathJax output enabled then runs it through a pipeline that wraps various bits of HTML around it (<code>div</code> blocks, navigation elements, and finally <code>head</code> and <code>body</code> elements).</p>
<p>The blog template I use looks like this:</p>
<pre class="sourceCode html"><code class="sourceCode html"><span class="kw">&lt;div</span><span class="ot"> id=</span><span class="st">&quot;page&quot;</span><span class="kw">&gt;</span>

<span class="kw">&lt;h1</span><span class="ot"> class=</span><span class="st">&quot;emphnext&quot;</span><span class="kw">&gt;</span>$title$<span class="kw">&lt;/h1&gt;</span>

$body$

<span class="kw">&lt;address</span><span class="ot"> class=</span><span class="st">&quot;signature&quot;</span><span class="kw">&gt;</span>
  <span class="kw">&lt;a</span><span class="ot"> class=</span><span class="st">&quot;author&quot;</span><span class="ot"> href=</span><span class="st">&quot;http://mark.reid.name&quot;</span><span class="kw">&gt;</span>Mark Reid<span class="kw">&lt;/a&gt;</span> 
  <span class="kw">&lt;span</span><span class="ot"> class=</span><span class="st">&quot;date&quot;</span><span class="kw">&gt;</span>$date$<span class="kw">&lt;/span&gt;</span>
  <span class="kw">&lt;span</span><span class="ot"> class=</span><span class="st">&quot;location&quot;</span><span class="kw">&gt;</span>$location$<span class="kw">&lt;/span&gt;</span>
<span class="kw">&lt;/address&gt;</span>

<span class="kw">&lt;/div&gt;</span></code></pre>
<p>The <code>$keywords$</code> in the template specify per-post values that are substituted in. In Hakyll, these are set using “Context” functions. In my case, the <code>postCtx</code> function sets the <code>$date$</code> keyword in a “Month Day, Year” format and grabs the title and other values from the metadata at the top of each post using Hakyll’s built in functions.</p>
<p>As you can see from the above, configuring a Hakyll site boils down to explicitly writing code for how you want things processed. It is certainly more complicated than Jekyll. Fortunately, what Hakyll provides is a great “mini-language” of sorts that takes care of many of the fiddly bits (e.g., reading files, managing dependencies, rendering markdown). Anything that isn’t provided by Hakyll you can write yourself using Haskell.</p>
<p>It’s the difference between getting a ready-made meal versus buying good ingredients and making it yourself. In the latter case, you can easily stray from a recipe and tweak things to your own taste.</p>
<h2 id="housekeeping-redirects-and-comments">Housekeeping: Redirects and Comments</h2>
<p>Once I had Hakyll generating my site I had to make a couple of final changes to finish the transition.</p>
<p>The first, and easiest, was remapping some URLs. Because I merged my <em>Inductio ex Machina</em> and <em>Structure &amp; Process</em> blogs, which were previously at <code>/iem/</code> and <code>/sap/</code> respectively, into a single blog at <code>/blog/</code> I had to ensure posts from the old URLs were sent to the new one.</p>
<p>I did this using <code>RedirectMatch</code> directives in my <code>.htaccess</code> file:</p>
<pre><code>RedirectMatch 301 ^/iem/(.*)$ /blog/$1
RedirectMatch 301 ^/sap/(.*)$ /blog/$1</code></pre>
<p>These simply match any post location from the old URLs and map them to the corresponding place under the new scheme. For example, my <a href="/blog/behold-jensens-inequality.html">Behold! Jensen’s Inequality</a> post used to be at <code>/iem/behold-jensens-inequality.hml</code> but is now at <code>/blog/behold-jensens-inequality.hml</code>. The <code>301</code> in the commands above tell any browsers that the posts have “<a href="http://en.wikipedia.org/wiki/HTTP_301">Moved Permanently</a>”.</p>
<p>The other main job I had was migrating my comments over to the new URL scheme. I use <a href="http://disqus.com">Disqus</a> to host the comments for this site. The way Disqus works means the comments for each post are associated with the URL of that post. Changing the post URLs meant all the comments for the posts were no longer appearing.</p>
<p>Fortunately, Disqus provides an incredibly simple migration tool to solve this problem. Because I had set up the 301 redirects, all I had to do was click a button in Disqus’ admin panel for my site to tell its crawlers to go over my site, find the posts which had been 301ed, and update its database accordingly.</p>
<p>It worked like a charm.</p>
<p>Well… except for the Atom/RSS feed I accidentally regenerated with all my posts in it, thereby filling up many people’s feed readers with my old posts. Sorry about that.</p>
<h2 id="pros-and-cons">Pros and Cons</h2>
<p>So was the switch worth it?</p>
<p>For the purpose of regaining some of my Haskell-fu I can definitely say “yes”. I struggled quite a bit with remembering various idioms after a 12 year hiatus. Now I feel much more comfortable coding in Haskell and am probably more proficent than when I last did it.</p>
<p>I really like working in Pandoc’s style of markdown. It does (almost) everything <a href="http://maruku.rubyforge.org/">Maruku</a>, the previous renderer I used, did but it is much, much faster and has significantly better error reporting. I do miss Maruku’s syntax for <code>div</code> block, but apart from that I’m much happier with Pandoc.</p>
<p>Writing configuration code in Hakyll is much more time consuming, especially at first. However, given the fairly bespoke nature of my site and the even more arcane changes I have planned, I was already bending Jekyll a lot (through configuration, templates, and hacks) to get it to do what I wanted. Being able to drop down to Haskell and write code to specify how I want pages built is much easier in Hakyll.</p>
<p>That said, the templating in Hakyll is very basic and I had to put a lot more thought into how I wrote them in order to get the results I wanted.</p>
<p>Overall though, I am happy with this new set up and am looking forward to putting more content up on my site again.</p>

<address class="signature">
  <a class="author" href="http://mark.reid.name">Mark Reid</a> 
  <span class="date">March 26, 2013</span>
  <span class="location">Canberra, Australia</span>
</address>

</div>

<!-- Disqus Comments -->
<div id="disqus_thread"></div>

<!-- Enable Disqus comments -->
<script type="text/javascript">
        var disqus_iframe_css = "http://mark.reid.name/css/screen.css";
        var disqus_title = "Switching from Jekyll to Hakyll";
        var disqus_message = "A brief operational note on how and why I shifted my site and this blog from Jekyll to Hakyll.";
</script>
<script type="text/javascript" src="http://disqus.com/forums/markreid/embed.js"></script>

<noscript>
    <a href="http://markreid.disqus.com/?url=ref">View the discussion thread.</a>
</noscript>

]]></summary>
</entry>
<entry>
    <title>Gun Deaths vs. Gun Ownership</title>
    <link href="http://mark.reid.name/blog/gun-deaths-vs-gun-ownership.html" />
    <id>http://mark.reid.name/blog/gun-deaths-vs-gun-ownership.html</id>
    <published>2012-12-17T00:00:00Z</published>
    <updated>2012-12-17T00:00:00Z</updated>
    <summary type="html"><![CDATA[<div id="page">

<h1 class="emphnext">Gun Deaths vs. Gun Ownership</h1>

<p>In the wake of the <a href="http://en.wikipedia.org/wiki/Sandy_Hook_Elementary_School_shooting">tragic shooting</a> at Sandy Hook Elementary School there was a flurry of discussion about gun control in my Twitter and Facebook feeds. One statistic from an April 2012 <a href="http://www.newyorker.com/reporting/2012/04/23/120423fa_fact_lepore?currentPage=all&amp;mobify=0">New Yorker article</a> caught my attention:</p>
<blockquote>
<p>The United States is the country with the highest rate of civilian gun ownership in the world. (The second highest is Yemen, where the rate is nevertheless only half that of the U.S.) No civilian population is more powerfully armed.</p>
</blockquote>
<p>I posted this quote on Facebook and was asked whether there was any correlation between rates of gun ownership and gun-related deaths. After 20 minutes of grabbing some data on worldwide <a href="http://en.wikipedia.org/wiki/Number_of_guns_per_capita_by_country">gun ownership</a> and <a href="http://en.wikipedia.org/wiki/List_of_countries_by_firearm-related_death_rate">gun deaths</a> from Wikipedia and running it through <a href="http://www.r-project.org">R</a> I produced the following graph.</p>
<dl class="figure">
<dd>
<img alt="Gun deaths vs. Gun Ownership for OECD countries" src="/pics/figures/deaths-vs-guns.png" width="90%"/>
</dd>
<dt>
Gun-related deaths per capita vs. gun ownership per capita in OECD countries.
</dt>
</dl>

<div class="note">
<strong>Update - 19 Dec. 2012</strong>: The above graph was correct for the data I obtained for Wikipedia on the 17th. It has since been updated. See the update at the end of this post for details.
</div>

<p>I posted this graph on Twitter late on Sunday night and woke up this morning to find it had been retweeted over 200 times. In addition, there were a large number of questions and requests for different graphs.</p>
<blockquote class="twitter-tweet tw-align-center"><p>
Out of curiosity, I grabbed gun death and gun ownership data for OECD countries from Wikipedia and ran it through R: <a href="https://t.co/hgsOeQzp" title="https://dl.dropbox.com/u/38668/deaths-vs-guns.png">dl.dropbox.com/u/38668/deaths…</a>
</p>
— Mark Reid (@mdreid) <a href="https://twitter.com/mdreid/status/280269141942878208" data-datetime="2012-12-16T11:12:25+00:00">December 16, 2012</a>
</blockquote>

<script src="//platform.twitter.com/widgets.js" charset="utf-8">&nbsp;</script>

<p>So that others can analyse the data I used themselves, I thought I would write up how I created the graph.</p>
<h2 id="the-data">The Data</h2>
<p>The first step was finding data on gun ownership and gun-related deaths and getting it into R.</p>
<p>A quick search revealed Wikipedia articles on <a href="http://en.wikipedia.org/wiki/List_of_countries_by_firearm-related_death_rate">countries by firearm-related death rate</a> and <a href="http://en.wikipedia.org/wiki/Number_of_guns_per_capita_by_country">Number of guns per capita by country</a>. I cut and pasted the tables in these articles into a <a href="http://code.google.com/p/macvim/">text editor</a> and saved them as CSV files. I also grabbed a <a href="http://en.wikipedia.org/wiki/List_of_OECD_countries_by_GDP_per_capita">list of OECD countries</a> from Wikipedia and converted it. You can grab the resulting files here:</p>
<ul>
<li><a href="/bits/guns/data/deaths.csv">deaths.csv</a> (as of 17 Dec. 2012)</li>
<li><a href="/bits/guns/data/guns.csv">guns.csv</a> (as of 17 Dec. 2012)</li>
<li><a href="/bits/guns/data/oecd.csv">oecd.csv</a> (as of 17 Dec. 2012)</li>
</ul>
<div class="note">
<strong>Update - 19 Dec. 2012</strong>: The above data was what was available on Wikipedia when I wrote this post. It has since been changed. See the discussion at the end of this post for details.
</div>

<h2 id="the-code">The Code</h2>
<p>The R code I used to create the plot is given below. It simply reads in the data from the guns and deaths CSV files, merges them, adds a column denoting whether a country is in the OECD, and then plots the results.</p>
<pre><code>guns &lt;- read.table(&quot;data/guns.csv&quot;, sep=&quot;\t&quot;, header=TRUE)
deaths &lt;- read.table(&quot;data/deaths.csv&quot;, sep=&quot;\t&quot;, header=TRUE)
oecd &lt;- read.table(&quot;data/oecd.csv&quot;, sep=&quot;\t&quot;, header=TRUE)

data &lt;- merge(guns, deaths, by=&quot;Country&quot;)
data$OECD &lt;- data$Country %in% oecd$Country

with(subset(data, data$OECD == TRUE), {
	plot(Deaths ~ Guns,
		main=&quot;Gun Deaths vs Gun Ownership&quot;,
		xlab=&quot;Guns per 100 people&quot;,
		ylab=&quot;Gun deaths per 100k people&quot;,
		xlim=c(0,100)
	);
	text(Guns, Deaths, Country, pos=1)
})</code></pre>
<p>You can get all the code I used to generate the figures in this post here:</p>
<ul>
<li><a href="/bits/guns/guns.R">guns.R</a></li>
</ul>
<h2 id="other-graphs">Other Graphs</h2>
<p>I was asked a number of good questions about the graph I posted on Twitter. In particular, several people were surprised at the number of gun-related deaths for Switzerland. As the following graph of gun homicides vs. gun ownership shows, most of those deaths are actually suicides.</p>
<dl class="figure">
<dd>
<img alt="Gun homicides vs. Gun Ownership for OECD countries" src="/pics/figures/homicide-vs-guns.png" width="90%"/>
</dd>
<dt>
Gun homicides per capita vs. gun ownership per capita in OECD countries.
</dt>
</dl>

<dl class="figure">
<dd>
<img alt="Gun homicides vs. Gun Ownership for OECD countries (Detail)" src="/pics/figures/homicide-vs-guns-detail.png" width="90%"/>
</dd>
<dt>
Detail of gun homicides per capita vs. gun ownership per capita in OECD countries.
</dt>
</dl>

<p>Finally, here is a plot of homicide vs. ownership across all countries — not just those in the OECD. The mass of countries in the lower left corner is unreadble but you can see those countries with either high homicide rates or high gun ownership clearly.</p>
<dl class="figure">
<dd>
<img alt="Gun homicides vs. Gun Ownership for all countries" src="/pics/figures/homicide-vs-guns-all.png" width="90%"/>
</dd>
<dt>
Gun homicides per capita vs. gun ownership per capita in all countries.
</dt>
</dl>

<p>Just to be clear, I am not making any claims about the effect of gun ownership on shootings. I just wanted to show how easy it is to use freely available data to help answer reasonable questions about heated political issues like gun control.</p>
<p>I’ll leave you to draw your own conclusions.</p>
<h2 id="update-19th-dec.-2012">Update (19th Dec. 2012)</h2>
<p>The response and attention to these plots — both positive and negative — on Twitter, in the comments below, and via email has been a little overwhelming. So much so that my site went down yesterday due to me hitting the (usually sufficient) bandwidth cap my host provides.</p>
<h3 id="data-updates">Data Updates</h3>
<p>Several people noted that the data I plotted for Switzerland was inconsistent with what was on Wikipedia. If you look at the <a href="http://en.wikipedia.org/w/index.php?title=List_of_countries_by_firearm-related_death_rate&amp;action=history">edit history</a> for the firearm-related death rate page on Wikipedia you will see that someone updated the Switzerland data late on the 16th of December. Taking into account that Canberra, Australia is GMT+11 this update occurred after I scraped the page for the data I used here.</p>
<p>I have redone the OECD plots with data scraped from the same pages as of 3:30pm on the 19th. You can see the results and get the new data below.</p>
<dl class="figure" >
<dd>
<a href="/pics/figures/deaths-vs-guns-20121219.png"><img alt="Gun Deaths vs. Gun Ownership for OECD countries" src="/pics/figures/deaths-vs-guns-20121219.png" width="45%"/></a> <a href="/pics/figures/homicide-vs-guns-20121219.png"><img alt="Gun homicides vs. Gun Ownership for OECD countries" src="/pics/figures/homicide-vs-guns-20121219.png" width="45%"/></a>
</dd>
<dt>
Gun deaths (left) and homicides (right) per capita vs. gun ownership per capita in OECD countries (click to view larger images).
</dt>
</dl>

<p>The new data is here:</p>
<ul>
<li><a href="/bits/guns/data/guns-20121219.csv">guns–20121219.csv</a></li>
<li><a href="/bits/guns/data/deaths-20121219.csv">deaths–20121219.csv</a></li>
</ul>
<h3 id="other-analyses">Other Analyses</h3>
<p>A number of people pointed me to analyses they had done of similar data, criticisms of this post, and alternative sources of data. Here is a summary of some of those other contributions:</p>
<ul>
<li><p><a href="http://diegobasch.com">Diego Basch</a> redid some of the above plots with <a href="http://diegobasch.com/homicides-vs-gun-ownership">overall homicide data</a> (not just gun homicide).</p></li>
<li><p><a href="http://aphyr.com">aphyr</a> redid one of my plots on a log scale and also <a href="http://aphyr.com/posts/261-firearm-homicides-vs-gun-prevalence">compared gun homicide to income and wealth</a>.</p></li>
<li><p><a href="https://twitter.com/dominikus">Dominikus Baur</a> created a more <a href="http://do.minik.us/shorts/guns/guns.html">interactive version</a> of the above plots using d3.</p></li>
<li><p><a href="https://twitter.com/DataJunkie">Ryan Rosario</a> pointed me towards <a href="http://globalsociology.com/2012/12/15/on-the-guns-thing-i-would-just-like-to-point-out/">another analysis</a> of deaths vs. ownership.</p></li>
<li><p><a href="https://twitter.com/finemrespice">finem respice</a> has a <a href="http://www.finemrespice.com/node/120">very detailed response</a> to this post (and other reporting) that explains why the data I used for Switzerland in my initial graphs was incorrect.</p></li>
<li><p><a href="http://www.businessinsider.com/author/walter-hickey">Walter Hickey</a> at Business Insider <a href="http://www.businessinsider.com/shooting-gun-laws-2012-12">summarised my post</a>. There is a vigorous discussion in the comments there.</p></li>
<li><p><a href="http://www.levreyzin.com">Lev Reyzin</a> tweeted some plots of <a href="https://twitter.com/lreyzin/status/280773248629735424">homicides vs. percentage of gun ownership</a>, included one <a href="https://twitter.com/lreyzin/status/281106705746632704">broken down by US states</a>.</p></li>
<li><p><a href="https://twitter.com/cutflat">Tim Raupach</a> pointed me towards Nate Silver’s <a href="http://fivethirtyeight.blogs.nytimes.com/2012/12/18/in-gun-ownership-statistics-partisan-divide-is-sharp/">analysis of US gun ownership statistics</a>.</p></li>
</ul>
<h3 id="disclaimer">Disclaimer</h3>
<p>Finally, in light of some of the more vocal criticism I’ve received, I feel I should reiterate a few points:</p>
<ul>
<li><p>At no point have I ever claimed that this is even close to a rigorous analysis. In my original tweet and here I have made it clear that I have used data from Wikipedia. Since I thought it was common knowledge that Wikipedia should <em>never</em> be used as a primary source for any kind of real research, I didn’t expect people to confuse this post with a serious study.</p></li>
<li><p>I have not attempted to use these plots to draw any kind of conclusion about the relationship between gun ownership and gun deaths. Indeed, I do not think there exists a simple explanation. All I intended to do was attempt to shed some light on a question I was asked about a possible correlation.</p></li>
<li><p>I will not run any kind of statistical test on the above data (e.g., rank correlation coefficients). For any such quantity to be meaningful I would need to assume that the data I collected was much more carefully controlled for. Since I just grabbed it from Wikipedia, this is clearly not a valid assumption.</p></li>
<li><p>I do not intend to create more graphs showing other data or other statistics. Other people (see the links above) have already done so for a variety of alternative data. Also, I realise their are better sources of data out there than Wikipedia. However, as I’ve said before, my intention was not to do a definitive study but rather show how a readily accessible source (i.e., Wikipedia) can be used to quickly get an overview of a topic.</p></li>
</ul>
<p>I will probably not the last person to use Wikipedia for this sort of amateur analysis. Therefore, if you believe the data I have used is incorrect or out of date, I suggest you solve the problem at the source and update (with references) the relevant entries on Wikipedia.</p>
<p>If you have a question about other possible correlations or relationships, feel free to apply the code above to what ever sources of data you think might help answer it. I’d appreciate it if you link to what you find in the comments below.</p>

<address class="signature">
  <a class="author" href="http://mark.reid.name">Mark Reid</a> 
  <span class="date">December 17, 2012</span>
  <span class="location">Canberra, Australia</span>
</address>

</div>

<!-- Disqus Comments -->
<div id="disqus_thread"></div>

<!-- Enable Disqus comments -->
<script type="text/javascript">
        var disqus_iframe_css = "http://mark.reid.name/css/screen.css";
        var disqus_title = "Gun Deaths vs. Gun Ownership";
        var disqus_message = "Looking at some data on gun-related deaths and gun ownership worldwide in the wake of the Sandy Hook shooting.";
</script>
<script type="text/javascript" src="http://disqus.com/forums/markreid/embed.js"></script>

<noscript>
    <a href="http://markreid.disqus.com/?url=ref">View the discussion thread.</a>
</noscript>

]]></summary>
</entry>
<entry>
    <title>"Who is ML Hipster?"</title>
    <link href="http://mark.reid.name/blog/who-is-ml-hipster.html" />
    <id>http://mark.reid.name/blog/who-is-ml-hipster.html</id>
    <published>2012-10-24T00:00:00Z</published>
    <updated>2012-10-24T00:00:00Z</updated>
    <summary type="html"><![CDATA[<div id="page">

<h1 class="emphnext">"Who is ML Hipster?"</h1>

<p>To avoid keeping you in suspense, I’ll get this out of the way right up front: <a href="https://twitter.com/ML_Hipster">ML Hipster</a> is me!</p>
<h2 id="who-are-you-talking-about">Who are you talking about?</h2>
<p>I started the <a href="https://twitter.com/ML_Hipster">ML Hipster</a> account on a whim and found it fun to mash up clichés about hipsters and their attitude with jargon from machine learning and statistics.</p>
<blockquote class="twitter-tweet tw-align-center"><p>
Is this Bayesian? You know I’m a strict Bayesian, right?
</p>
— ML Hipster (@ML_Hipster) <a href="https://twitter.com/ML_Hipster/status/223712846092050432" data-datetime="2012-07-13T09:37:53+00:00">July 13, 2012</a>
</blockquote>

<p>I guess I was partially inspired by the rash of other technical novelty accounts out there such as <a href="https://twitter.com/PLT_Borat">PLT Borat</a> and <a href="https://twitter.com/hipsterhacker">Hipster Hacker</a>.</p>
<p>There was also the added enjoyment of obliquely poking fun at what some “old school” machine learning people might think of the recent, “big data”-driven incursion onto <strike>our</strike> (ahem) <em>their</em> turf.</p>
<blockquote class="twitter-tweet tw-align-center"><p>
Everyone is all big data this and online that. My methods are small batch: they only handle a few instances but really look at them, y’know?
</p>
— ML Hipster (@ML_Hipster) <a href="https://twitter.com/ML_Hipster/status/236227963002159104" data-datetime="2012-08-16T22:28:29+00:00">August 16, 2012</a>
</blockquote>

<p>Ultimately though, it was really just an excuse to make bad puns that only a select few would understand, let alone find amusing.</p>
<blockquote class="twitter-tweet tw-align-center"><p>
“Oh sure, going in that direction will totally minimize the objective function” —Sarcastic Gradient Descent.
</p>
— ML Hipster (@ML_Hipster) <a href="https://twitter.com/ML_Hipster/status/226448024224796673" data-datetime="2012-07-20T22:46:30+00:00">July 20, 2012</a>
</blockquote>

<h2 id="why-take-off-the-mask">Why take off the mask?</h2>
<p>To be honest, I had no idea the account would get so popular. So much so that shortly after starting it I promised myself that if it ever got more followers than my <a href="https://twitter.com/mdreid">main twitter account</a> I’d spill the beans.</p>
<p>Well, 103 days, 61 tweets, and 1,651 followers later, here I am presiding over scattered legumes.</p>
<h2 id="what-now">What now?</h2>
<p>I have no intention of abandoning <a href="https://twitter.com/ML_Hipster">ML Hipster</a> and will likely post there whenever I have yet another terrible, technical pun to inflict which I don’t want friends and family to hear.</p>
<blockquote class="twitter-tweet tw-align-center"><p>
I prefer Chervonenkis’ solo work.
</p>
— ML Hipster (@ML_Hipster) <a href="https://twitter.com/ML_Hipster/status/224027751655546880" data-datetime="2012-07-14T06:29:12+00:00">July 14, 2012</a>
</blockquote>

<p>I’m also not going to reveal who ML Hipster is via that account. I figure there are people following ML Hipster (but not this blog or my other account) who <a href="http://www.youtube.com/watch?v=om7O0MFkmpw">couldn’t care less</a> about who it actually is and I don’t want to spoil their fun.</p>
<p>Or mine.</p>
<script src="https://platform.twitter.com/widgets.js" charset="utf-8">&nbsp;</script>



<address class="signature">
  <a class="author" href="http://mark.reid.name">Mark Reid</a> 
  <span class="date">October 24, 2012</span>
  <span class="location">Canberra, Australia</span>
</address>

</div>

<!-- Disqus Comments -->
<div id="disqus_thread"></div>

<!-- Enable Disqus comments -->
<script type="text/javascript">
        var disqus_iframe_css = "http://mark.reid.name/css/screen.css";
        var disqus_title = ""Who is ML Hipster?"";
        var disqus_message = "The facts behind this mysterious Twitter account can finally be revealed!";
</script>
<script type="text/javascript" src="http://disqus.com/forums/markreid/embed.js"></script>

<noscript>
    <a href="http://markreid.disqus.com/?url=ref">View the discussion thread.</a>
</noscript>

]]></summary>
</entry>

</feed>
