<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>Toban Wiebe</title>
 <link href="https://tobanwiebe.com/atom.xml" rel="self"/>
 <link href="https://tobanwiebe.com"/>
 <updated>2024-11-24T14:29:18+00:00</updated>
 <id>https://tobanwiebe.com/</id>
 <author>
   <name>Toban Wiebe</name>
 </author>

 
 <entry>
   <title>Quantifying uncertainty in probability predictions</title>
   <link href="https://tobanwiebe.com/blog/2019/02/probability-prediction"/>
   <updated>2019-02-24T13:00:00+00:00</updated>
   <id>https://tobanwiebe.com/blog/2019/02/probability-prediction</id>
   <content type="html">&lt;p&gt;Suppose you’re interested in knowing the chances of an event \(X\) occuring (e.g., \(X =\) “&lt;em&gt;a nuclear strike over any populated area in the year 2019&lt;/em&gt;”).
When making predictions about events with binary outcomes (either the event happens or it doesn’t), people generally report a single probability (e.g., a 2% chance of \(X\) occurring).
But, you may wonder, why not report a confidence interval (e.g., 2% \(\pm\) 0.5%), or a distribution of probabilities (e.g., a Beta distribution) to reflect uncertainty?&lt;/p&gt;

&lt;p&gt;For example, this question comes up with prediction markets, where the market price can be interpreted as the best estimate of the probability of the event \(X\) occuring.
But there are no confidence intervals on this market price.
Or consider models for classification, such as logistic regression or other machine learning algorithms, which produce predicted probabilities for each possible class (e.g., \(X_i =\) “&lt;em&gt;transaction \(i\) is fraudulent&lt;/em&gt;”).
In both of these cases, we face the same issue with representing uncertainty — how does the market/model express confidence in its predicted probabilities?&lt;/p&gt;

&lt;p&gt;In this post, I’ll explain why this question stems from a fundamental confusion:
&lt;strong&gt;it’s a misconception to think that a predicted probability is a point estimate that doesn’t convey any uncertainty.&lt;/strong&gt;
Below, I’ll show that there are two distinct sources of uncertainty that are being conflated here, and that one or both can be used to express uncertainty.&lt;/p&gt;

&lt;h2 id=&quot;two-types-of-uncertainty&quot;&gt;Two types of uncertainty&lt;/h2&gt;

&lt;p&gt;The key distinction here is between:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Uncertainty over the outcome, \(X\) vs \(\neg X\)
    &lt;ul&gt;
      &lt;li&gt;Also known as &lt;a href=&quot;https://en.wikipedia.org/wiki/Uncertainty_quantification#Aleatoric_and_epistemic_uncertainty&quot;&gt;aleatoric uncertainty&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;(FYI: the symbol “\(\neg\)” is the negation operator and can be read as “not”)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Uncertainty over model parameters which are used to generate a prediction for the outcome
    &lt;ul&gt;
      &lt;li&gt;Also known as &lt;a href=&quot;https://en.wikipedia.org/wiki/Uncertainty_quantification#Aleatoric_and_epistemic_uncertainty&quot;&gt;epistemic uncertainty&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let’s unpack each case in depth.&lt;/p&gt;

&lt;h3 id=&quot;uncertainty-over-outcomes&quot;&gt;Uncertainty over outcomes&lt;/h3&gt;

&lt;p&gt;When we aren’t working with a model, we only have the first source of uncertainty to deal with.
But it isn’t obvious where the uncertainty lies: if we say \(Pr[X] = 0.02\), it may appear that we’ve just given a point estimate.
But recall that this is a binary outcome space, i.e., the only possible outcomes are \(X\) or \(\neg X\).
So the full probability distribution (over the two possible outcomes) can be summarized by one probability, \(p := Pr[X]\) (which implies \(1-p = Pr[\neg X]\)).
As we’ve provided a full probability distribution over the outcome space, it’s not possible to say anything more — any uncertainty must be embedded in this distribution.&lt;/p&gt;

&lt;p&gt;Intuitively, probabilities near 0 or 1 reflect a high degree of certainty.
A prediction without any uncertainty at all would just be a &lt;em&gt;yes or no&lt;/em&gt; answer, i.e., a predicted probability of 0 or 1.
It would just state which outcome will occur, with no notion of uncertainty or hedging.&lt;/p&gt;

&lt;p&gt;More precisely, confidence in a probability prediction is reflected by how extreme it is &lt;em&gt;relative to a baseline or prior belief&lt;/em&gt;.
To see this, suppose that there is an event \(X\) that is very likely to occur, and that a prediction market has given \(X\) a predicted probability of 0.97.
If you are maximally uncertain/ignorant about \(X\), what probability do you assign?
Intuitively, you &lt;em&gt;hedge your bets&lt;/em&gt; and stick to 0.97.
Here, 0.97 is the baseline, which you can treat as your prior probability.
Given this prior information, a prediction of 0.97 reflects maximal uncertainty.
(If you didn’t have any prior information whatsoever, you would go with 0.5.)&lt;/p&gt;

&lt;p&gt;Then, if you have some new information about \(X\), you can update your prior to get a posterior.
If your information provides strong evidence in favor of \(X\), then your posterior probability might jump up to, say, 0.997.
On the other hand, if your information strongly supports \(\neg X\), then your posterior might drop to, say, 0.78.
Thus, your degree of confidence is revealed by the degree to which your probability moves away from the baseline and toward 0 or 1.&lt;/p&gt;

&lt;p&gt;You can use Bayes’ Theorem to play with some numbers yourself.
Denote your prior by \(p := Pr[X]\), and assume you’ve used your information \(D\) to compute the likelihoods \(q(X) := Pr[D \mid X]\) and \(q(\neg X) := Pr[D \mid \neg X]\).
Denote the likelihood ratio by \(\lambda := q(X) / q(\neg X)\).&lt;/p&gt;

&lt;p&gt;Then compute the posterior and rearrange in terms of the likelihood ratio:&lt;/p&gt;

\[\begin{aligned}
Pr[X \mid D] &amp;amp;= \frac{p \cdot q(X)}{p \cdot q(X) + (1-p)q(\neg X))}\\
&amp;amp;= \frac{p \cdot q(X)/q(\neg X)}{p \cdot q(X)/q(\neg X) + (1-p)}\\
&amp;amp;= \frac{p \cdot \lambda}{p \cdot \lambda + (1-p)}
\end{aligned}\]

&lt;p&gt;Note that the posterior can be expressed purely in terms of the prior and the likelihood ratio (i.e., it doesn’t depend on the individual likelihoods).
This means that the magnitudes of the likelihoods don’t matter; all that matters is their ratio, which indicates how much the information \(D\) favors \(X\) &lt;em&gt;relative to&lt;/em&gt; \(\neg X\).&lt;/p&gt;

&lt;p&gt;If you play with this formula, you’ll get a sense of how the information in the likelihoods updates the prior to a posterior probability.
Notice that when \(\lambda = 1\), the posterior reduces to \(p\), the prior.
In other words, when \(D\) is uninformative about \(X\), it leaves your prior belief unchanged.
Furthermore, for any prior belief \(p\), if \(\lambda &amp;gt; 1\), then your posterior will be pushed upward from your prior (and vice versa for \(\lambda &amp;lt; 1\)).
That is, any information in favor of \(X\) will increase your confidence in \(X\) — even if \(p=0.999\)!&lt;/p&gt;

&lt;p&gt;Judging the quality of probability predictions is simple: just check that they’re &lt;a href=&quot;https://scikit-learn.org/stable/modules/calibration.html&quot;&gt;calibrated&lt;/a&gt;.
For example, predictions made with, 80% confidence should be correct 80% of the time.
With enough completed predictions, you can plot a &lt;a href=&quot;https://www.metoffice.gov.uk/research/climate/seasonal-to-decadal/gpc-outlooks/user-guide/interpret-reliability&quot;&gt;reliability diagram&lt;/a&gt; to assess the calibration of the predictions.&lt;/p&gt;

&lt;h3 id=&quot;uncertainty-over-models&quot;&gt;Uncertainty over models&lt;/h3&gt;

&lt;p&gt;When we &lt;em&gt;are&lt;/em&gt; working with a model, we also have a second source of uncertainty — that of the model.
This uncertainty is reflected in the posterior distribution over the parameters (at least for Bayesians — frequentists would use the sampling distribution of the parameter estimator to derive confidence intervals / standard errors).
Because these parameters are used to produce predictions, their uncertainty propagates through to produce additional uncertainty over the outcome.&lt;/p&gt;

&lt;p&gt;This is &lt;em&gt;meta&lt;/em&gt;-uncertainty: uncertainty over the model which produces the uncertain prediction of the outcome.
(In fact, you can have higher levels of meta-uncertainty by including uncertainty over any hyperparameters of the model.)&lt;/p&gt;

&lt;p&gt;For example, here’s a specification for a Bayesian logistic regression model, where I’ve put an informative prior on the model coefficients:&lt;/p&gt;

\[\begin{aligned}
y_i &amp;amp;\sim Bernoulli(p_i) \\
\log\left(\frac{p_i}{1 - p_i}\right) &amp;amp;= \beta_0 + x_{i1} \beta_1 + x_{i2} \beta_2 + \ldots + x_{iK} \beta_K \\
\beta_k &amp;amp;\sim \mathcal{N}(0,1.5), \; k = 1,2,\ldots,K
\end{aligned}\]

&lt;p&gt;You can see how the uncertainty from the model’s prior (Normal distribution) propagates through, adding to the uncertainty in the likelihood (Bernoulli distribution).
As a result, we get a full density for \(p_i\) over the interval \((0,1)\).
The spread of this density reflects model uncertainty, whereas the distance from the baseline probability reflects the degree of confidence in the prediction of the outcome.
The key thing to realize is that these two sources of uncertainty are orthogonal.&lt;/p&gt;

&lt;p&gt;For example, you could simultaneously have a very confident prediction of the outcome but with a lot of model uncertainty — a widely spread posterior distribution that is far away from the prior probability (where the prior is marked by the small X):&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  Confident prediction, uncertain model
⠀⢸⠀⠀⠀⠀⠀⠀⠀⢀⠤⠤⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸
⠀⢸⠀⠀⠀⠀⠀⠀⡔⠁⠀⠀⠀⠘⢄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸
⠀⢸⠀⠀⠀⠀⠀⡸⠀⠀⠀⠀⠀⠀⠀⠱⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸
⠀⢸⠀⠀⠀⠀⢰⠁⠀⠀⠀⠀⠀⠀⠀⠀⠘⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸
⠀⢸⠀⠀⠀⢀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸
⠀⢸⠀⠀⠀⡸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸
⠀⢸⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸
⠀⢸⠀⠀⢰⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⢄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸
⠀⢸⠀⠀⡎⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸
⠀⢸⠀⢀⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢣⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸
⠀⢸⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢣⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸
⠀⢸⠀⡎⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢢⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸
⠀⢸⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠣⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸
⠀⢸⢰⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸
⠀⢸⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠢⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸
⠀⢸⡎⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸
⠀⢸⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⢄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸
⠀⢸⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⠢⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸
⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠒⠤⢄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸
⠒⢺⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠛⠛⠛⠒⠒⠒⠒⠒⠒⠒X⠒⠒⠒⠒⠒⠒⠒⢺
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Or you could have a very unconfident prediction of the outcome with very little model uncertainty — a tightly distributed posterior distribution centered on the prior probability:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  Uncertain prediction, confident model
⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⡀⠀⠀⠀⠀⠀⠀⡇
⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⡇⠀⠀⠀⠀⠀⠀⡇
⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⡇⠀⠀⠀⠀⠀⠀⡇
⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⡇⠀⠀⠀⠀⠀⠀⡇
⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⡇⠀⠀⠀⠀⠀⠀⡇
⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⢱⠀⠀⠀⠀⠀⠀⡇
⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⢸⠀⠀⠀⠀⠀⠀⡇
⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠃⢸⠀⠀⠀⠀⠀⠀⡇
⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⢸⠀⠀⠀⠀⠀⠀⡇
⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⢸⠀⠀⠀⠀⠀⠀⡇
⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⢸⠀⠀⠀⠀⠀⠀⡇
⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⢸⠀⠀⠀⠀⠀⠀⡇
⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠘⡄⠀⠀⠀⠀⠀⡇
⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡎⠀⠀⡇⠀⠀⠀⠀⠀⡇
⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⡇⠀⠀⠀⠀⠀⡇
⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⡇⠀⠀⠀⠀⠀⡇
⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠇⠀⠀⡇⠀⠀⠀⠀⠀⡇
⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⢣⠀⠀⠀⠀⠀⡇
⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡜⠀⠀⠀⢸⠀⠀⠀⠀⠀⡇
⠒⡗⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠓⠒X⠒⠚⠓⠒⠒⠒⠒⡗
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;summing-up&quot;&gt;Summing up&lt;/h2&gt;

&lt;p&gt;The argument I’ve made here can be summed up as:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;A probability prediction is a full probability distribution and so it inherently quantifies uncertainty — it’s a misconception to think that you need a confidence interval to express uncertainty&lt;/li&gt;
  &lt;li&gt;Model uncertainty propagates through to produce an additional (but orthogonal) layer of uncertainty over the outcome&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This may seem obvious in retrospect, but it’s always good to gain clarity on the fundamentals, where confused intuitions may lurk unnoticed.
Here, intuitions such as “a scalar prediction must be a point estimate” and “you need a confidence interval to express uncertainty” are highly misleading.&lt;/p&gt;

&lt;p&gt;In this case, understanding the distinct sources of uncertainty has resolved some confusion I had about prediction markets and machine learning model predictions.
The upshot is that (if I’m comfortable ignoring model uncertainty), I need only be concerned that the probability predictions are &lt;a href=&quot;https://scikit-learn.org/stable/modules/calibration.html&quot;&gt;calibrated&lt;/a&gt;.
This is straightforward to check: for prediction markets, you just need some historical data on outcomes; for classifier models, you can check on a holdout dataset.
Then you can be comfortable that the predictions are accurately quantifying uncertainty.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Find Your Community: Increasing user engagement at Reddit</title>
   <link href="https://tobanwiebe.com/blog/2017/06/reddit-engagement"/>
   <updated>2017-06-22T20:00:00+00:00</updated>
   <id>https://tobanwiebe.com/blog/2017/06/reddit-engagement</id>
   <content type="html">&lt;p&gt;&lt;em&gt;Toban Wiebe is an Insight Data Science Fellow in Silicon Valley.
For his fellowship project, he performed an analysis of Reddit user engagement to provide actionable insights for the business.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://assets.ifttt.com/images/channels/1352860597/icons/on_color_large.png&quot; alt=&quot;Reddit logo&quot; style=&quot;float:right;&quot; /&gt;
&lt;a href=&quot;https://www.reddit.com/&quot;&gt;Reddit&lt;/a&gt; is a social media platform where people can browse or join communities called &lt;em&gt;subreddits&lt;/em&gt; to submit posts as well as vote and comment on submissions.
Any user can create a subreddit — as a result, there are now &lt;a href=&quot;http://redditmetrics.com/history#tab2&quot;&gt;over 1 million subreddits&lt;/a&gt; spanning almost any topic imaginable.
Subreddits are based around topics such as &lt;a href=&quot;https://www.reddit.com/r/cats/&quot;&gt;r/cats&lt;/a&gt; or &lt;a href=&quot;https://www.reddit.com/r/datascience/&quot;&gt;r/datascience&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When someone first visits &lt;a href=&quot;https://www.reddit.com&quot;&gt;reddit.com&lt;/a&gt;, they are shown the reddit &lt;em&gt;frontpage&lt;/em&gt;, a post feed comprised of the currently most popular content from a curated selection of 50 &lt;em&gt;default&lt;/em&gt; subreddits.
(Note: this has recently changed to showing popular posts from any subreddit, with some exceptions. However, this only affects new accounts — existing users still see the default frontpage subreddits).
Logged-in users (also called redditors) can customize their feed by subscribing to other subreddits; otherwise they see the default frontpage content.&lt;/p&gt;

&lt;p&gt;However, while frontpage subreddits are prominently featured, the web interface doesn’t make it very obvious how to find other subreddits.
Reddit has a very useful &lt;a href=&quot;https://www.reddit.com/subreddits/&quot;&gt;subreddit discovery feature&lt;/a&gt;, but it’s only accessible through the small “More” link in the subreddit navigation bar at the top of the page.
This made me wonder: &lt;em&gt;would reddit benefit from making subreddit discovery more prominent in the user interface?&lt;/em&gt; 
To answer this question, I analyzed user engagement across subreddits to look for evidence of a causal relationship.&lt;/p&gt;

&lt;h2 id=&quot;data&quot;&gt;Data&lt;/h2&gt;

&lt;p&gt;Data on all reddit comments is &lt;a href=&quot;https://bigquery.cloud.google.com/dataset/fh-bigquery:reddit_comments&quot;&gt;publicly available on Google BigQuery&lt;/a&gt; thanks to redditor &lt;a href=&quot;https://www.reddit.com/user/fhoffa&quot;&gt;fhoffa&lt;/a&gt;.
The data is very large and is divided into monthly tables — the table for May 2017 alone contains 80 million rows and takes up 20GB on disk.
As such, it was very important to use BigQuery for performant queries.&lt;/p&gt;

&lt;p&gt;To access the data, I used the &lt;a href=&quot;https://cloud.google.com/datalab/&quot;&gt;Google Cloud Datalab&lt;/a&gt;, a Jupyter notebook environment running on a VM instance which connects to BigQuery.
By using SQL queries to aggegate the data down to a manageable size, I could load the results into pandas dataframes for my analyses.&lt;/p&gt;

&lt;h2 id=&quot;analysis-of-user-engagement&quot;&gt;Analysis of user engagement&lt;/h2&gt;

&lt;p&gt;As reddit content is entirely user-generated, I decided to focus on commenting as a proxy for adding value to the reddit experience.
Comments are an integral part of reddit — as many a redditor knows, discussions in the comments often contain some of the most valuable content.
For each user, I calculated the &lt;em&gt;number of monthly comments&lt;/em&gt; as a metric for user engagement.&lt;/p&gt;

&lt;h3 id=&quot;frontpage-subreddits-vs-the-rest&quot;&gt;Frontpage subreddits vs the rest&lt;/h3&gt;

&lt;p&gt;The distinction between the frontpage and other subreddits is a key divide in the spectrum of reddit usage styles.
On one end of the spectrum are the “frontpage-focused” users; at the other end are the users who participate solely in non-frontpage subreddits.
To measure this, I calculated a participation metric: the &lt;em&gt;percentage of comments outside of frontpage subreddits&lt;/em&gt; for each user in each month.&lt;/p&gt;

&lt;p&gt;The frontpage surfaces excellent content with broad appeal and is extremely popular.
However, the frontpage default subreddits only produce 17% of all reddit comments, despite their outsized popularity.
Other subreddits vary widely, but many thriving communities are based around a specific interest, such as &lt;a href=&quot;https://www.reddit.com/r/Coffee/&quot;&gt;r/coffee&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Based on my experience as a redditor, I hypothesized that people would get the most value out of reddit by going beyond the frontpage and finding subreddits related to their specific interests.
As a result, they would become more engaged in those communities and leave more comments overall.
However, given the popularity of the frontpage, it wasn’t obvious that this would be true.&lt;/p&gt;

&lt;h3 id=&quot;initial-cohort-level-analysis&quot;&gt;Initial cohort-level analysis&lt;/h3&gt;

&lt;p&gt;I started by looking at the relationship between engagement and participation in other subreddits at the cohort level in order to avoid selection bias from tenure.
For example, people who have been on reddit longer are likely to be both more engaged as well as participate more broadly in other subreddits.&lt;/p&gt;

&lt;p&gt;I took four monthly cohorts (from July to October of 2016) and measured their commenting activity in their 6th month of tenure.
As I suspected, there is a strong relationship between engagement and participation in other subreddits.
The chart below shows that “frontpage-focused” users (0-20% of comments outside of frontpage subreddits) have the lowest engagement with an average of 22.8 comments per month.
Engagement increases by &lt;em&gt;22.7%&lt;/em&gt; to an average of 27.8 comments per month for users with the majority of their comments outside of frontpage subreddits.
The difference between the first two groups is 2.55 with a 99% confidence interval of (1.69, 3.41).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://i.imgur.com/GQtdM93.png&quot; alt=&quot;engagement-chart&quot; /&gt;&lt;/p&gt;

&lt;p&gt;(Note: This chart is limited to users with 5-150 comments per month, to exclude outliers and low comment counts, which could skew the results.
I also excluded the 80-100% group, which is almost entirely composed of users who never comment on frontpage subreddits.
This group is large and behaves very differently — likely because they joined reddit to participate in a specific subreddit, with no interest in the frontpage.
As my focus is on increasing engagement for frontpage-focused users, I restricted my analysis to users with at least some frontpage engagement.)&lt;/p&gt;

&lt;p&gt;Furthermore, there are many users in this frontpage-focused group, so there are potentially large gains to be made from helping them to discover other subreddits.
The chart below adds bars for the number of users in each group (the average number per monthly cohort).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://i.imgur.com/xpmMgsZ.png&quot; alt=&quot;counts-chart&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;panel-data-analysis&quot;&gt;Panel data analysis&lt;/h3&gt;

&lt;p&gt;Though my cohort analysis controlled for the selection bias from tenure, I was worried that it was being confounded by another selection effect: what if the more highly engaged users within each cohort are more likely to seek out other subreddits?
To control for this, I constructed a panel dataset to quantify the effect at the user level.
This way, I could directly see how each user’s engagement changes over time as their participation shifts to other subreddits.&lt;/p&gt;

&lt;p&gt;Formally, I modeled this with user fixed-effects in a linear model:&lt;/p&gt;

\[y_{it} = \alpha_i + \beta^{\prime} x_{it} + \varepsilon_{it}.\]

&lt;p&gt;Here, \(y_{it}\) is the engagement of user \(i\) in month \(t\).
\(\alpha_i\) is the user fixed-effect.
\(x_{it}\) is a vector which includes the participation metric (% of comments outside of frontpage subreddits) as well as user tenure.
As I don’t care about recovering the fixed-effects, I differenced them out to get the &lt;a href=&quot;https://en.wikipedia.org/wiki/Fixed_effects_model&quot;&gt;“within” estimator&lt;/a&gt;:&lt;/p&gt;

\[y_{it} - \bar y_{i} = \beta^{\prime} (x_{it} - \bar x_{i}) + (\varepsilon_{it} - \bar \varepsilon_{i}).\]

&lt;p&gt;I ran this linear regression on all users who joined reddit within the last two years, which gave me 14 million user-month observations.
This also yielded a positive effect, with an estimated 0.38 more monthly comments per user for every 10 percentage point increase in participation outside of the frontpage (with a 95% confidence interval of (0.35, 0.41)).&lt;/p&gt;

&lt;p&gt;However, this is only about half of the effect size suggested by the above cohort-based analysis.
This means that selection on engagement was confounding the previous analysis.
Still, the estimated effect is quite substantial: if a frontpage-focused user shifted their participation to 70% outside of frontpage subreddits, that would induce an average increase of &lt;strong&gt;11.6%&lt;/strong&gt; in engagement.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://imgur.com/tbhKmSw.png&quot; alt=&quot;regression-chart&quot; /&gt;&lt;/p&gt;

&lt;p&gt;For comparison, an extra year of tenure on reddit is associated with a 7% increase in engagement.&lt;/p&gt;

&lt;h2 id=&quot;proposed-feature-and-ab-test&quot;&gt;Proposed feature and A/B test&lt;/h2&gt;

&lt;p&gt;Based on this evidence, I conclude that reddit should do more to help frontpage-focused users discover other communities.
Specifically, I propose adding a subreddit discovery feature into the frontpage sidebar.
This way, subreddit discovery would be much more evident to frontpage visitors.&lt;/p&gt;

&lt;p&gt;To evaluate the impact of this proposed sidebar feature (and to establish whether my finding is indeed a causal relationship), I designed an A/B test that could be implemented by reddit.
The goal of the experiment is to determine if this feature increases the commenting activity of frontpage-focused users.&lt;/p&gt;

&lt;h3 id=&quot;target-group&quot;&gt;Target group&lt;/h3&gt;

&lt;p&gt;The experiment targets existing frontpage-focused users: registered users with some commenting activity, but who haven’t subscribed to any other subreddits (and hence still see the default frontpage).
I also limited the experiment to users that joined in 2016 to avoid potential bias from older cohorts, and also because the newest cohorts are by far the largest.
(Though it is typical to target newly registered users, reddit is &lt;a href=&quot;https://www.reddit.com/live/x3ckzbsj6myw/updates/bb55d54c-7f79-11e6-bf48-0eeb724eeebd&quot;&gt;already running&lt;/a&gt; an A/B test for subreddit discovery during the onboarding flow. As such, my proposed test focuses on existing users.)&lt;/p&gt;

&lt;h3 id=&quot;duration-and-metrics&quot;&gt;Duration and metrics&lt;/h3&gt;

&lt;p&gt;The test would run for 5 weeks in total.
The first week would be an adaptation period for users to try out the feature and subscribe to other subreddits.
Then, the following 4 weeks would track the number of comments for each user.&lt;/p&gt;

&lt;p&gt;An important secondary metric to track is the number of subscriptions to other subreddits.
This tells us how effective the feature is at driving users to find other communities.&lt;/p&gt;

&lt;h3 id=&quot;power-analysis&quot;&gt;Power analysis&lt;/h3&gt;

&lt;p&gt;Unlike most other social media platforms, reddit is very conservative about changing the user experience (and primarily &lt;a href=&quot;https://www.reddit.com/live/x3ckzbsj6myw/&quot;&gt;runs A/B tests&lt;/a&gt; to learn more about its users).
As such, I tailored the design of the test to reflect this cautious approach.&lt;/p&gt;

&lt;p&gt;I set the test significance at \(\alpha = 0.01\) to be very stringent with respect to false positives.
I set the power at \(1 - \beta = 0.9\) to reflect less concern about false negatives.
This way, a positive result would be very strong grounds for launching the feature.&lt;/p&gt;

&lt;p&gt;The minimum detectable effect size that would be worthwhile should be based on the tradeoff between the value of additional comments and the opportunity cost of sidebar space (which would otherwise be ad space).
As I don’t have this information, I chose an intuitively plausible effect of 5%, or about 1 extra comment per user per month, on average.&lt;/p&gt;

&lt;p&gt;To reduce the number of users exposed to the new feature, I used an unbalanced design with a much larger control group.
I started from a total sample size of 27,000 users because that is roughly the number of frontpage-focused users among all of the 2016 cohorts.
This is more than enough for a balanced design, so I minimized the treatment group size subject to the other constraints.
This gave me a sample size of 7,000 users in the treatment group and 20,000 users in the control group.&lt;/p&gt;

&lt;h3 id=&quot;impact&quot;&gt;Impact&lt;/h3&gt;

&lt;p&gt;There are roughly 300,000 actively commenting users who only comment on the frontpage, so a 5% increase in their commenting would result in an overall increase of roughly 0.5% in commenting across all of reddit!
This effect could also grow over time as these users continue to explore other subreddits. 
Moreover, this is only considering the impact from users who are commenting at all — presumably there are far more users who never comment at all.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Reddit’s mission is “to help people discover places where they can be their true selves”.
This fits nicely with my recommendation of making community discovery more prominent in the user interface.
Furthermore, helping people to find other communities has a direct financial impact as reddit sells &lt;a href=&quot;https://static.reddit.com/marketing/subreddit_targeting_manual.pdf&quot;&gt;targeted subreddit ads&lt;/a&gt;.
All told, my analysis suggests that reddit could benefit substantially from improving the subreddit discovery process, and it would be well worth running an experiment to precisely quantify this impact.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Dealing with Anaconda Python in Linux</title>
   <link href="https://tobanwiebe.com/blog/2016/09/anaconda-python-linux"/>
   <updated>2016-09-30T15:00:00+00:00</updated>
   <id>https://tobanwiebe.com/blog/2016/09/anaconda-python-linux</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;https://www.continuum.io/&quot;&gt;Anaconda&lt;/a&gt; is a very handy Python distribution that bundles a slew of scientific packages along with the handy &lt;a href=&quot;http://conda.pydata.org/docs/&quot;&gt;conda package manager&lt;/a&gt;, allowing you to easily update your packages to the latest versions.
However, it doesn’t seamlessly integrate with Linux: the installer will simply add a line to your shell configuration file (e.g., &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/.bashrc&lt;/code&gt;) prepending the Anaconda &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bin&lt;/code&gt; directory to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PATH&lt;/code&gt; environment variable.
This means that Anaconda’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;python&lt;/code&gt; and other packages will override Linux’s system &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;python&lt;/code&gt; and packages (to see this, run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;which python&lt;/code&gt;).
For the most part, this shouldn’t be an issue, but in some cases it can cause trouble.&lt;/p&gt;

&lt;p&gt;For example, if you use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;yaourt&lt;/code&gt; package manager on Arch Linux, you’ll run into two problems with Anaconda Python.
First, Anaconda’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;curl&lt;/code&gt; will break &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;yaourt&lt;/code&gt;.
Second, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;yaourt&lt;/code&gt; will blindly install Python packages into the Anaconda Python package directory.
This sometimes causes conflicts with Python packages installed through &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pacman&lt;/code&gt; (which are properly installed into the system Python package directory).
I ran into this problem when installing &lt;a href=&quot;https://github.com/michael-lazar/rtv&quot;&gt;Reddit Terminal Viewer&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you just want to use Anaconda but not have it take over like this, there’s an easy fix: instead of &lt;em&gt;prepending&lt;/em&gt; the Anaconda &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bin&lt;/code&gt; directory to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PATH&lt;/code&gt; (which gives it priority), simply &lt;em&gt;append&lt;/em&gt; it so that system Python (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/usr/bin/python&lt;/code&gt;) and packages take precedence.
In your shell configuration (e.g., &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/.bashrc&lt;/code&gt;), change the line added by the Anaconda installer:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Default configuration of Anaconda installer&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#export PATH=&quot;/path/to/anaconda3/bin:$PATH&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Append Anaconda so that it doesn&apos;t override system Python&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PATH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$PATH&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;:/path/to/anaconda3/bin&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;python&lt;/code&gt; (and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;curl&lt;/code&gt;, for example) will still be the system version, but Anaconda applications will also be available (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jupyter&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ipython&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conda&lt;/code&gt;, etc).
My Anaconda workflow is to work in a &lt;a href=&quot;http://jupyter.org/&quot;&gt;Jupyter notebook&lt;/a&gt; along with a text editor.
Since &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jupyter&lt;/code&gt; is tied to the Anaconda &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;python&lt;/code&gt;, it continues to work seamlessly as before.&lt;/p&gt;

&lt;p&gt;If you want to temporarily use Anaconda’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;python&lt;/code&gt; at the shell, just use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conda&lt;/code&gt;’s environment manager to activate/deactivate it:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;source &lt;/span&gt;activate &amp;lt;&lt;span class=&quot;nb&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;source &lt;/span&gt;deactivate
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;root&lt;/code&gt; environment uses the standard Anaconda &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;python&lt;/code&gt; installation, so to activate the Anaconda’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;python&lt;/code&gt;, just do &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;source activate root&lt;/code&gt;.
(Note: this only affects the current shell session).&lt;/p&gt;

&lt;h4 id=&quot;bonus-python-linting-and-auto-completion-in-vim&quot;&gt;Bonus: Python linting and auto-completion in Vim&lt;/h4&gt;

&lt;p&gt;Since Vim (and Neovim) are compiled against the system &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;python&lt;/code&gt;, they won’t work with your Anaconda packages by default.
For example, running &lt;a href=&quot;https://www.pylint.org/&quot;&gt;pylint&lt;/a&gt; as a syntax checker in &lt;a href=&quot;https://github.com/vim-syntastic/syntastic&quot;&gt;Syntastic&lt;/a&gt; or &lt;a href=&quot;https://github.com/neomake/neomake&quot;&gt;Neomake&lt;/a&gt; will use the system &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;python&lt;/code&gt; and give errors when you import Anaconda packages.
The solution is very simple: just include your Anaconda package directory in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PYTHONPATH&lt;/code&gt; environment variable.
This way, the system python will be able to import the Anaconda packages.&lt;/p&gt;

&lt;p&gt;In your shell configuration (e.g., &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/.bashrc&lt;/code&gt;), append your Anaconda &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;site-packages&lt;/code&gt; directory as such:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PYTHONPATH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$PYTHONPATH&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;:/path/to/anaconda3/lib/python3.6/site-packages&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Also, the (Neovim-only) python completions package &lt;a href=&quot;https://github.com/zchee/deoplete-jedi&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;deoplete-jedi&lt;/code&gt;&lt;/a&gt; allows you to specify which &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;python&lt;/code&gt; interpreter to use for the completion server.
It seems that setting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PYTHONPATH&lt;/code&gt; isn’t sufficient (for example, I couldn’t get &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pandas&lt;/code&gt; completions to work).
Add the following line to your Vim config (with the correct path):&lt;/p&gt;

&lt;div class=&quot;language-vim highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;g:deoplete&lt;/span&gt;#sources#jedi#python_path &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;/path/to/anaconda3/bin/python&apos;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

</content>
 </entry>
 
 <entry>
   <title>Make your own Julia packages</title>
   <link href="https://tobanwiebe.com/blog/2016/08/julia-packaging"/>
   <updated>2016-08-20T20:30:00+00:00</updated>
   <id>https://tobanwiebe.com/blog/2016/08/julia-packaging</id>
   <content type="html">&lt;p&gt;[
&lt;strong&gt;Update&lt;/strong&gt;: with the release of Julia 1.0, the package manager, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pkg&lt;/code&gt;, was completely rewritten, though it remains quite similar.
Check out &lt;a href=&quot;https://julialang.github.io/Pkg.jl/v1/creating-packages/&quot;&gt;the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pkg&lt;/code&gt; documentation&lt;/a&gt; to see what’s new.
]&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://julialang.org/&quot;&gt;Julia&lt;/a&gt; is a fantastic language for scientific computing and as a result is gaining traction among researchers.
In research projects, it often happens that you need to write code which could be generalized and reused.
For example, in a recent project, I coded up a &lt;a href=&quot;https://github.com/tobanw/MarriageMarkets.jl&quot;&gt;marriage market model&lt;/a&gt; as a component of a larger model.
The best way to make such code reusable is to create a package (most languages provide a packaging system).&lt;/p&gt;

&lt;p&gt;Julia provides a convenient way to create a new package.
As explained in &lt;a href=&quot;http://docs.julialang.org/en/release-0.4/manual/packages/#creating-a-new-package&quot;&gt;the manual&lt;/a&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pkg.generate(&quot;NewPackage&quot;, &quot;MIT&quot;)&lt;/code&gt; initializes a git repo containing the package structure for a package named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NewPackage&lt;/code&gt; with an MIT license.
If you configure your GitHub username in git (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git config --global github.user &quot;USERNAME&quot;&lt;/code&gt;), it will even configure the remote repository (which you’ll still need to create in GitHub).&lt;/p&gt;

&lt;p&gt;Since the Julia package directory isn’t a very convenient location for developing your package (e.g., &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/.julia/v0.4/&lt;/code&gt;), I recommend moving your package (cut and paste) to your desired location and then symlinking it to the Julia package directory (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ln -s your/directory/NewPackage ~/.julia/v0.4/NewPackage&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Converting your code into a package takes a few simple steps.
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/NewPackage.jl&lt;/code&gt; contains the actual module that users will import.
The manual explains how to &lt;a href=&quot;http://docs.julialang.org/en/release-0.4/manual/modules/&quot;&gt;create a module&lt;/a&gt;.
You simply define functions and types and use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;export&lt;/code&gt; statement to choose which ones to make available externally.
A good way to organize your code is to put it in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src&lt;/code&gt; directory and then &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;include()&lt;/code&gt; it in the module file.&lt;/p&gt;

&lt;p&gt;Next, you should specify which packages are required as dependencies in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;REQUIRE&lt;/code&gt; file.
The file already includes the current stable version of Julia as a requirement.&lt;/p&gt;

&lt;p&gt;While optional, it’s a good idea to include some tests of your code!
Put them in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;test/runtests.jl&lt;/code&gt; and run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pkg.test(&quot;NewPackage&quot;)&lt;/code&gt; to run your tests.
If you enable Travis CI in GitHub, it will automatically run your tests when you &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git push&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Finally, don’t forget to fill out the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;README.md&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;To share your package with others, push it to GitHub and then &lt;a href=&quot;http://docs.julialang.org/en/release-0.4/manual/packages/#installing-unregistered-packages&quot;&gt;others can install it&lt;/a&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pkg.clone(&quot;git@github.com:username/NewPackage.jl.git&quot;)&lt;/code&gt;.
The manual also has instructions for registering your package as an official Julia package that can be installed with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pkg.install()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Look at &lt;a href=&quot;https://github.com/tobanw/MarriageMarkets.jl&quot;&gt;my package&lt;/a&gt; for a simple example.
The &lt;a href=&quot;https://github.com/QuantEcon/QuantEcon.jl&quot;&gt;QuantEcon&lt;/a&gt; package is a more comprehensive example that I drew on in making my package.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>MathJax with Kramdown</title>
   <link href="https://tobanwiebe.com/blog/2016/02/mathjax-kramdown"/>
   <updated>2016-02-10T10:30:00+00:00</updated>
   <id>https://tobanwiebe.com/blog/2016/02/mathjax-kramdown</id>
   <content type="html">&lt;p&gt;Last week, GitHub Pages &lt;a href=&quot;https://github.com/blog/2100-github-pages-now-faster-and-simpler-with-jekyll-3-0&quot;&gt;upgraded to Jekyll 3.0&lt;/a&gt;.
One major consequence of the upgrade is that, for Jekyll sites hosted on GitHub Pages, &lt;em&gt;only&lt;/em&gt; the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kramdown&lt;/code&gt; engine is supported.&lt;/p&gt;

&lt;p&gt;This broke my existing MathJax setup – I was using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;redcarpet&lt;/code&gt; Markdown engine before, which understood math with the delimiters &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\\( \LaTeX \\)&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\\[ \LaTeX \\]&lt;/code&gt; for inline and displayed math, respectively.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kramdown&lt;/code&gt; only recognizes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$$ \LaTeX $$&lt;/code&gt; for &lt;em&gt;both&lt;/em&gt; inline and displayed math.
This means that it will automatically infer whether you want inline or displayed math.&lt;/p&gt;

&lt;p&gt;Here’s the live demo with inline \(\LaTeX\) and displayed&lt;/p&gt;

\[\LaTeX\]

&lt;p&gt;This is an easy fix unless you have a lot of old posts with LaTeX to convert, in which case you should probably write a small converter script to switch your math delimiters to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$$&lt;/code&gt;.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Simple keyboard shortcuts for any website</title>
   <link href="https://tobanwiebe.com/blog/2015/11/keyboard-shortcuts-web"/>
   <updated>2015-11-28T16:30:00+00:00</updated>
   <id>https://tobanwiebe.com/blog/2015/11/keyboard-shortcuts-web</id>
   <content type="html">&lt;p&gt;I’m a huge fan of Gmail’s vim-inspired keyboard shortcuts.
It’s been nice to see the adoption of keyboard shortcuts in other sites, but for most of the web, keyboard access remains completely ignored.
I always just figured that it must be prohibitively difficult to implement keyboard shortcuts in a website, and so only the big players could do it.
It turns out, however, that implementing keyboard shortcuts is embarassingly easy.&lt;/p&gt;

&lt;p&gt;With no knowledge of javascript, I was able to add some simple keyboard navigation to this website (&lt;a href=&quot;https://github.com/tobanw/tobanw.github.io&quot;&gt;source repo&lt;/a&gt;).
Though this website is built with &lt;a href=&quot;http://jekyllrb.com/&quot;&gt;Jekyll&lt;/a&gt;, this method would work on any website as it only uses some simple client-side javascript.
I used the excellent &lt;a href=&quot;https://craig.is/killing/mice&quot;&gt;Mousetrap&lt;/a&gt; library to handle keyboard input, and wrote some simple &lt;a href=&quot;https://github.com/tobanw/tobanw.github.io/blob/master/assets/scripts/keyboard.js&quot;&gt;navigation commands&lt;/a&gt; in javascript.&lt;/p&gt;

&lt;p&gt;I implemented two kinds of navigation in the spirit of Gmail: jumping and list navigation.
(Note: I’m using the &lt;a href=&quot;https://github.com/ccampbell/mousetrap/tree/master/plugins/bind-dictionary&quot;&gt;bind dictionary&lt;/a&gt; extension to bind multiple keys at once):&lt;/p&gt;

&lt;h3 id=&quot;jumping&quot;&gt;Jumping&lt;/h3&gt;

&lt;p&gt;To get &amp;lt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;g&lt;/code&gt; then &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;h&lt;/code&gt;&amp;gt; style jumping, all you need is:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;Mousetrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
	&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;g h&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;	&lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;location&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;href&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
	&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;g b&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;	&lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;location&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;href&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/blog&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
	&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;g r&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;	&lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;location&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;href&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/research&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;That’s it: incredibly simple.&lt;/p&gt;

&lt;h3 id=&quot;blog-post-navigation&quot;&gt;Blog post navigation&lt;/h3&gt;

&lt;p&gt;Adding j/k navigation was a little more complicated.
I wrote &lt;a href=&quot;https://github.com/tobanw/tobanw.github.io/blob/master/assets/scripts/keyboard.js&quot;&gt;a function&lt;/a&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;blogNav&lt;/code&gt; which takes a key press and does the following:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;gets a list of all the post links (using their unique class, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;post-link&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;gets the currently focused element&lt;/li&gt;
  &lt;li&gt;moves the link focus accordingly (‘j/k’), or launches the focused link (‘o’)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I also tweaked the CSS to change the color of focused links. 
To bind it in Mousetrap:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;Mousetrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
	&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;blogNav&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
	&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;blogNav&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
	&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;o&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;blogNav&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;o&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;Adding keyboard shortcuts to a website is surprisingly easy.
It’s unfortunate that most web development is entirely focused on mouse input, relegating keyboard users to hacky extensions like &lt;a href=&quot;https://vimium.github.io/&quot;&gt;vimium&lt;/a&gt; and &lt;a href=&quot;http://5digits.org/pentadactyl/&quot;&gt;pentadactyl&lt;/a&gt;.
Hopefully &lt;a href=&quot;https://craig.is/killing/mice&quot;&gt;Mousetrap&lt;/a&gt; can help more websites become keyboard friendly.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Economic growth via effective regulation</title>
   <link href="https://tobanwiebe.com/blog/2015/11/economic-growth-effective-regulation"/>
   <updated>2015-11-07T08:30:00+00:00</updated>
   <id>https://tobanwiebe.com/blog/2015/11/economic-growth-effective-regulation</id>
   <content type="html">&lt;p&gt;I somehow ended up reading &lt;a href=&quot;http://johnhcochrane.blogspot.com/2015/10/economic-growth.html&quot;&gt;this long essay&lt;/a&gt; by economist John Cochrane on growth-oriented policy.
I really enjoyed it because it takes a hard-headed approach to topics where reason is too often crowded out by &lt;a href=&quot;https://philosophynow.org/issues/101/The_Righteous_Mind_by_Jonathan_Haidt&quot;&gt;moral instinct&lt;/a&gt;.
(Other examples of this approach include &lt;a href=&quot;http://www.effectivealtruism.org/&quot;&gt;Effective Altruism&lt;/a&gt;, or the &lt;a href=&quot;http://www.ecomodernism.org/&quot;&gt;Eco-Modernist Manifesto&lt;/a&gt;.)&lt;/p&gt;

&lt;p&gt;It’s an idealistic vision – it ignores the political economy that sustains the gigantic inefficiencies he decries – yet it’s an overwhelmingly sensible one.
Perhaps I’m biased towards the views of pro-growth economists, but this essay was packed with an uncommon amount of common sense (which is a pretty low bar when it comes to the topic of policy).&lt;/p&gt;

&lt;p&gt;The essay makes a two-part argument: that growth should be a very high policy priority, and that there’s a lot of inefficient regulation that hinders growth.
I’ll quote a bunch of highlights below if you don’t want to read the whole thing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;In the long run, nothing but growth matters.&lt;/em&gt;&lt;/strong&gt;
Small differences in growth rates lead to dramatically different outcomes, because of compounding.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;If the US economy had grown at 2% rather than 3.5% since 1950, income per person by 2000 would have been $23,000 not $50,000. That’s a huge difference. Nowhere in economic policy are we even talking about events that will double, or halve, the average American’s living standards in the next generation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The primacy of economic growth should be a really obvious point, but it’s easy to lose sight of the big picture.
If you think about it, economic growth is the &lt;em&gt;only&lt;/em&gt; thing that has lifted nations out of poverty.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Nothing other than productivity matters in the long run. A factor of three increase in income in 50 years, and the much larger rise in income and health since the dawn of the industrial age, dwarfs what unions bargaining for better wages, progressive taxes or redistribution, monetary, fiscal or other stimulus programs, minimum wage laws or other Federal regulation of labor markets, price caps and supports, subsidies, or much of anything else the government can do.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And the primacy of growth should be non-controversial:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;38% more income — or 26% less income — drives just about any agenda one could wish for, from strong defense, to environmental protection, to the affordability of social programs, to the welfare of any segment of the population, to public investments, health, and fundamental research.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Dumb regulation hinders growth.&lt;/em&gt;&lt;/strong&gt;
To increase growth, there’s a lot of obviously wasteful regulation that could be made a lot smarter.
Unfortunately, that regulation is there because of problems of political economy, and so it’s not as easy to fix as it looks.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;When the average person (voter) expresses concern over inequality, what they really mean is that they are concerned that average people are not getting ahead economically. If the average person were getting ahead, whether some big shot CEOs fly on private jets or not would make little difference. Conversely, the average voter, if not the average left-wing pundit, does not support equality of misery. If the average person continues to do poorly, it would bring them little solace for the government to tax away the lifestyles of the rich and famous.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;On the problems of health insurance regulation:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The central problem of preexisting conditions was an artifact of regulation. In the ideal form of health insurance, you buy cheap catastrophic insurance when young, but the insurance policy can follow you as you age, change jobs, and move from state to state, and does not radically increase premiums if you get sick.
[…]
We need to allow simple, portable, largely catastrophic, lifelong, guaranteed-renewable health insurance to emerge. Right now it’s illegal.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;On energy policy:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The poster child for inefficiency may well be the mandate for gasoline producers to use ethanol. Corn ethanol, it turns out, does nothing to help the environment: It takes nearly as much petroleum energy to produce it as it contains, in the form of fertilizer, transport fuel and so on; it uses up valuable land, which directly emits greenhouse gases, and contributes to erosion and runoff; it drives up the price of food.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;If you are serious about carbon, let the words “nuclear power” pass your lips. We have sitting before us a technology that can easily supply our electricity and many transport needs, with zero carbon or methane emissions. New designs, if only they could pass the immense regulatory hurdle, would be much safer than the 1950s Soviet technology that failed at Chernobyl or the 1960s technology that failed at Fukushima. We are now operating antiques. And even with this rate of accident, nuclear power has caused orders of magnitude less human or environmental suffering than any other fuel.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;Similarly, the most environmentally friendly way for people to live is in tightly packed cities, fed by genetically modified foods which yield more per acre of farmland and require fewer fertilizers and pesticides, from laser-leveled fields run efficiently by large corporations in the highest productivity locations. Federal policies to the contrary are not just anti-growth, they’re anti-environment too. When Federal policy can say these things in public, it will have a bit more standing to invoke the name of “science.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;On taxation:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Often, however, tax reform proposals sacrifice too quickly the principles of what a good tax system should be with perceived political accommodations to powerful interest groups. Economists should not play politician. We should always start with “in a perfect world, here is what the tax code should look like,” and accommodate political constraints only when asked to. Political constraints change quickly. Economic fundamentals do not.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;The right corporate tax rate is zero. Corporations never pay taxes. Every dollar of taxes that a corporation pays comes from higher prices of their products, lower wages to their workers, or lower returns to their owners.
[…]
For all these reasons, eliminating the corporate tax is as likely to be more rather than less progressive. The higher prices a corporation charges hurt everyone. The lower wages corporations pay hurt workers. The income it passes along to its owners is subject to our highly progressive tax system.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;When we say broaden the base by removing deductions and credits, we should be serious about that. Thus, even the holy trinity of mortgage interest deduction, charitable donation deduction, and employer provided health insurance deduction should be scrapped. The extra revenue could finance a large reduction in marginal rates.
Why? Consider the mortgage interest deduction. Imagine that in the absence of the deduction, Congress proposes to send a check to each homeowner, in proportion to the interest he or she pays on money borrowed against the value of the house. Furthermore, rich people, people who buy more expensive houses, people who borrow lots of money, and people who refinance often to take cash out get bigger checks than poor people, people who buy smaller houses, people who save up and pay cash, or people who pay down their mortgages. A rich person buying a huge house in Palo Alto, who pays 40% marginal income tax rate, gets a check for 40% of his huge mortgage. A poor person buying a small house in Fresno, who pays a 10% income tax, gets a check for 10% of his much smaller mortgage. There would be riots in the streets before this bill would pass. Yet this is exactly what the mortgage interest deduction accomplishes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;On labor markets:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Start, of course, with taxes: income taxes and payroll taxes are primarily taxes on employment. But the regulatory burdens of employment are larger still, as anyone who has tried to get a nanny legal will attest.
Minimum wages, occupational licensing, anti-discrimination laws, laws regulating hours people can work, benefits they must receive, leave they must be given, fear of lawsuits if you fire someone, and so forth all impede the labor market.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;The usual argument is that workers need protection of all these laws. Well, the supposed protections do cost economic growth, and they do reduce employment. How much do they actually protect workers? The strongest force for worker protection is a vibrant labor market — if you don’t like this job, go take another. The tightly regulated labor market makes it much harder to get a new job, and thus, paradoxically, lowers your bargaining power in the old one.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An exceptional section on immigration. Had a hard time not quoting the whole thing:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Immigrants contribute to economic growth. Even if income per capita is unchanged, imagine how much better off our social security system, our medicare system, our unfunded pension promises, and our looming deficits and debt would be, if America could attract a steady flow of young, hard-working people who want to come and pay taxes. Aha, we can attract them! They’re beating the doors down to come. But then we keep them out.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;Allowing free migration is, by many estimates the single policy change that would raise world GDP the most. If you believe in free trade in goods, and free investment, then you have to believe that free movement of people has the same benefits.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;On education:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The culprit is easy to find: awful public schools run by and for the benefit of politically powerful teachers’ and administrators’ unions. (Don’t forget the latter! Teachers account for only half of typical public school expenses.) Education poses a particularly large tradeoff between profits to incumbents and economic growth, since education lies at the foundation of higher productivity. In addition, the costs of awful schools fall primarily on lower-income people who cannot afford to get out of the system. It is one of the major contributors to inequality.
The solution is simple as well: widespread financing by vouchers and charter schools. As with health care, a vibrant market demands that people control their spending, and can move it to where they get better results. As with health care, the government does not have to directly provide a service in order to help people to pay for that service. But as with health care, a healthy market also demands supply competition, that new schools be allowed to start and compete for students.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As exciting as this vision is, I’m not very optimistic about any of these prescriptions being implemented, at least not in the near term.
But it’s good to know that we have a lot of simple solutions if we ever get desperate.
And I hope that some of these proposals (like immigration) can gain enough momentum to be implemented in the medium term.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Note taking like a hacker</title>
   <link href="https://tobanwiebe.com/blog/2015/10/note-taking-like-a-hacker"/>
   <updated>2015-10-06T10:30:00+00:00</updated>
   <id>https://tobanwiebe.com/blog/2015/10/note-taking-like-a-hacker</id>
   <content type="html">&lt;p&gt;In the spirit of &lt;a href=&quot;http://tom.preston-werner.com/2008/11/17/blogging-like-a-hacker.html&quot;&gt;blogging like a hacker&lt;/a&gt;, I am now taking notes like a hacker, thanks to a system I pieced together using Markdown and Dropbox.
I have used Evernote and Google Docs for my notes in the past, but I was never satisfied.&lt;/p&gt;

&lt;p&gt;I liked the idea of Markdown, and tried some online editors like &lt;a href=&quot;https://stackedit.io&quot;&gt;StackEdit&lt;/a&gt; and &lt;a href=&quot;https://laverna.cc&quot;&gt;Laverna&lt;/a&gt;.
This was a nice experience, but I was lured by the tantalizing prospect of editing the Markdown files in my text editor (vim), rather than the web editor.
(StackEdit can sync with Dropbox, allowing local editing of the plaintext files, but unfortunately, each file has to be synced manually, so you can’t just sync a directory.)&lt;/p&gt;

&lt;p&gt;My note taking system had to have these features:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Markdown based&lt;/li&gt;
  &lt;li&gt;Accessible across devices&lt;/li&gt;
  &lt;li&gt;Edit notes in any text editor&lt;/li&gt;
  &lt;li&gt;MathJax enabled for writing math with \(\LaTeX\)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I don’t really care about embedding media or features like Evernote’s clipping functionality.
As a PhD student, I mostly just want to save academic things like research ideas and paper summaries.&lt;/p&gt;

&lt;p&gt;My system is minimal, but effective.
Notes are just Markdown files in my Dropbox.
On my desktop, I can edit them in any text editor.
With vim, I use the &lt;a href=&quot;https://github.com/greyblake/vim-preview&quot;&gt;vim-preview&lt;/a&gt; plugin to render an html preview.&lt;/p&gt;

&lt;p&gt;On a mobile device, I can of course access the plaintext through the Dropbox app.
But there are also Markdown apps like &lt;a href=&quot;http://2appstudio.com/jotterpad/&quot;&gt;Jotterpad&lt;/a&gt; which can connect to Dropbox.&lt;/p&gt;

&lt;p&gt;And that’s it! Very simple, but now my notes are in a very portable format. (Speaking of which, I wrote a &lt;a href=&quot;https://github.com/tobanw/laverna-export&quot;&gt;little script&lt;/a&gt; to export notes from Laverna.)&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>New Jekyll site</title>
   <link href="https://tobanwiebe.com/blog/2015/09/new-jekyll-site"/>
   <updated>2015-09-05T08:30:00+00:00</updated>
   <id>https://tobanwiebe.com/blog/2015/09/new-jekyll-site</id>
   <content type="html">&lt;p&gt;So I decided to move from Wordpress to &lt;a href=&quot;http://jekyllrb.com/&quot;&gt;Jekyll&lt;/a&gt;.
Not that I had any complaints with Wordpress, it’s an absolutely fantastic platform.
I just wanted to start &lt;a href=&quot;http://tom.preston-werner.com/2008/11/17/blogging-like-a-hacker.html&quot;&gt;blogging like a hacker&lt;/a&gt;.
With Jekyll I can work from a text editor, use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git&lt;/code&gt; for the entire site, and publish with a simple &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git push&lt;/code&gt;.
Furthermore, I can host the site on &lt;a href=&quot;https://pages.github.com/&quot;&gt;Github Pages&lt;/a&gt;, which automatically rebuilds the site whenever a change is made.&lt;/p&gt;

&lt;p&gt;The comments were a cesspool back on Wordpress (and I’m talking about legitimate, non-spam comments here), so I’m nuking all the past comments and starting here with no commenting system for the time being.&lt;/p&gt;

&lt;p&gt;I’ve chosen a Creative Commons 4.0 license to encourage sharing.
Feel free to copy code from the &lt;a href=&quot;https://github.com/tobanw/tobanw.github.io&quot;&gt;github repository&lt;/a&gt; that this site is generated from.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Double standard: caffeine vs nicotine</title>
   <link href="https://tobanwiebe.com/blog/2015/01/double-standard-caffeine-vs-nicotine"/>
   <updated>2015-01-16T14:20:48+00:00</updated>
   <id>https://tobanwiebe.com/blog/2015/01/double-standard-caffeine-vs-nicotine</id>
   <content type="html">&lt;blockquote&gt;[...] there is a kind of puritanical view that everything relating to nicotine is bad and harmful and should be stamped on.&lt;/p&gt;
&lt;p&gt;-&lt;a href=&quot;http://www.newscientist.com/article/dn26160-who-vaping-report-is-misguided-say-tobacco-experts.html#.VLgL1jXL_7B&quot;&gt;Richard West&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;I&apos;m no expert on this topic, but it seems to me that the harms of tobacco are from smoking (and chewing) and not from the nicotine itself (apart from the addictiveness). So nicotine administered with gum/patch/vaping would be somewhat more like caffeine in harmfulness (loads of people are addicted to caffeine).&lt;/p&gt;
&lt;p&gt;Nicotine also seems to have similar useful effects. From &lt;a href=&quot;https://en.wikipedia.org/wiki/Nicotine&quot;&gt;Wikipedia&lt;/a&gt;: &quot;Nicotine appears to have significant performance enhancing effects, particularly in fine motor skills, attention, and memory.&quot; A Martian scientist comparing the harms and benefits (for humans) of drinking coffee vs &lt;a href=&quot;http://www.engadget.com/2014/05/23/vaporizers-explainer/&quot;&gt;vaping nicotine&lt;/a&gt; might think that both drugs are safe and have productivity-boosting effects, and wouldn&apos;t see a reason for only one of them to be socially acceptable.&lt;/p&gt;
&lt;p&gt;So why is nicotine held to a &lt;a href=&quot;http://www.newscientist.com/article/dn26160-who-vaping-report-is-misguided-say-tobacco-experts.html#.VLgL1jXL_7B&quot;&gt;much higher standard&lt;/a&gt;? Well, the public health effort to end smoking became a moral crusade. As Jonathan Haidt puts it, morality binds and blinds. The anti-smoking crusade gained enough strength that it created &lt;a href=&quot;https://www.youtube.com/watch?v=gUEjnoWpdao&quot;&gt;a hated enemy&lt;/a&gt;. Smokers in North America are now a low-status out-group from the perspective of most non-smokers. As usual, when activists morally charge their case by painting something as sacred or evil, they commit themselves to not giving up an inch. Smoking is pure evil, and nicotine is central to smoking, so nicotine must be evil too. Any admission that nicotine might not be horrible is helping the enemy.&lt;/p&gt;
&lt;p&gt;Caffeine, on the other hand, did not get loaded with negative affect because it had a safe delivery system. Imagine if nicotine had historically been consumed in drink form instead of smoking -- in such a world, I imagine that it would just be another stimulant drink like coffee or tea.&lt;/p&gt;
&lt;p&gt;It&apos;s a real shame that e-cigarettes (nicotine) are being morally condemned along with cigarettes (tobacco). If smokers can switch to vaping, they can avoid all the harm and still get their nicotine. From a public health perspective, getting smokers to switch is a huge win. Doctors should be prescribing e-cigs to smokers, government should promote switching. Unfortunately, since nicotine has been painted evil by association, it&apos;s probably not going to happen.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>A thought on methodology</title>
   <link href="https://tobanwiebe.com/blog/2014/08/a-thought-on-methodology"/>
   <updated>2014-08-26T01:30:50+00:00</updated>
   <id>https://tobanwiebe.com/blog/2014/08/a-thought-on-methodology</id>
   <content type="html">&lt;p&gt;I&apos;ve never felt comfortable with the logical positivists&apos; &quot;science is prediction&quot; characterization, primarily because it neglects what I intuitively think of as the heart of science: explanation. For example, Darwin&apos;s theory of evolution – perhaps the greatest scientific discovery ever – is big on explanation, but not nearly as big on prediction. (Because evolution happens on such long timescales, although microbial evolution can be observed on very short timescales.) Or consider the &apos;selfish gene&apos; paradigm, the evolutionary paradigm of viewing the gene as fundamental unit of selection, and the organism as a mere tool fabricated by the genes for the purpose of propagating themselves into the future. Dawkins&apos; discusses (I think it was in The Extended Phenotype) criticisms of the idea as not providing any new predictions. My initial reaction to these criticisms is always: So what? They&apos;re wonderful &lt;em&gt;explanations&lt;/em&gt; of the world. They make sense of the world. Isn&apos;t that pretty remarkable?&lt;/p&gt;
&lt;p&gt;The point I want to make here is that the emphasis on prediction is just a convenient special case of a more general principle: that a theory should correspond to reality, just as a &lt;a href=&quot;http://wiki.lesswrong.com/wiki/Map_and_Territory_(sequence)&quot; target=&quot;_blank&quot;&gt;map corresponds to the territory&lt;/a&gt;. Reality can be observed past, present, and future. It is just as well to vet a theory against past observations as against future observations. The reason the scientific method favors prediction is that it prevents the scientist from concocting a &apos;just so&apos; story that too neatly fits the existing facts (&quot;overfitting&quot;). An idealized honest scientist can test a theory against any empirical evidence.&lt;/p&gt;
&lt;p&gt;Darwin&apos;s theory is so amazing because &lt;a href=&quot;http://www.amazon.com/gp/product/1416594795/ref=as_li_tl?ie=UTF8&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=1416594795&amp;amp;linkCode=as2&amp;amp;tag=highthou-20&amp;amp;linkId=V4OQUPRBW3EBZQ6E&quot;&gt;it makes sense of so many existing facts&lt;/a&gt;. (And you can still make predictions about historical facts (&lt;a href=&quot;http://erdmannevolution.blogspot.com/2010/04/retrodictions.html&quot; target=&quot;_blank&quot;&gt;&quot;retrodictions&quot;&lt;/a&gt;), such as the famous quip that evolution would be falsified by finding &lt;a href=&quot;https://en.wikipedia.org/wiki/Precambrian_rabbit&quot; target=&quot;_blank&quot;&gt;fossil rabbits in the precambrian&lt;/a&gt;.) Of course, if you have a beautiful theory that has no connection to reality, then you&apos;re not doing science. Science is concerned with explaining reality, and so scientific theories must say things about reality – things which can (in principle) be empirically checked. It ultimately doesn&apos;t matter where that evidence is temporally located.&lt;/p&gt;
</content>
 </entry>
 
 
</feed>
