Hello stranger, and welcome! 👋😊
I'm Rasmus Bååth, data scientist, engineering manager, father, husband, tinkerer,
tweaker, coffee brewer, tea steeper, and, occasionally, publisher of stuff I find
interesting down below👇
Peter Norvig, the director of research at Google, wrote a nice essay on
How to Write a Spelling Corrector a couple of years ago. That essay explains and implements a simple but effective spelling correction function in just 21 lines of Python. Highly recommended reading! I was wondering how many lines it would take to write something similar in base R. Turns out you can do it in (at least) two pretty obfuscated lines:
sorted_words <- names(sort(table(strsplit(tolower(paste(readLines("https://www.norvig.com/big.txt"), collapse = " ")), "[^a-z]+")), decreasing = TRUE))
correct <- function(word) { c(sorted_words[ adist(word, sorted_words) <= min(adist(word, sorted_words), 2)], word)[1] }
While not working exactly as Norvig’s version it should result in similar spelling corrections:
## [1] "piece"
## [1] "of"
## [1] "cake"
![](/blog/2014/12/peter-norvigs-spell-checker-in-two-lines-of-r/images/r_cake.jpeg)
So let’s deobfuscate the two-liner slightly (however, the code below might not make sense if you don’t read
Norvig’s essay first):
Making a slight digression from last month’s
Probable Points and Credible Intervals here is how to summarize a 2D posterior density using a highest density ellipse. This is a straight forward extension of the highest density interval to the situation where you have a two-dimensional posterior (say, represented as a two column matrix of samples
) and you want to visualize what region, containing a given proportion of the probability, that has the most probable parameter combinations. So let’s first have a look at a fictional 2D posterior by using a simple scatter plot:
![plot of chunk unnamed-chunk-2](/blog/2014/11/how-to-summarize-a-2d-posterior-using-a-highest-density-ellipse/figures/unnamed-chunk-2.png)
Whoa… that’s some serious over-plotting and it’s hard to see what’s going on. Sure, the bulk of the posterior is somewhere in that black hole, but where exactly and how much of it?
Why R? Because S!
R is the open source implementation (and a pun!) of S, a language for statistical computing that was developed at Bell Labs in the late 1970s. After that, the implementation of S underwent a number of major revisions documented in a series of seminal books, often just referred to by the color of their cover: The Brown Book, the Blue Book, the White Book and the Green Book. To satisfy my techno-historical lusts I recently acquired all these books and I though I would share some tidbits from them, highlighting how S (and thus R) developed into what we today love and cherish. But first, here are the books in chronological order from left to right:
![](/blog/2014/11/tidbits-from-books-that-defined-s-and-r/images/the_s_books_long.jpeg)
After having broken the Bayesian eggs and prepared your model in your statistical kitchen the main dish is the posterior. The posterior is the posterior is the posterior, given the model and the data it contains all the information you need and anything else will be a little bit less nourishing. However, taking in the posterior in one gulp can be a bit difficult, in all but the most simple cases it will be multidimensional and difficult to plot. But even if it is one-dimensional and you could plot it (as, say, a density plot) that does not necessary mean that it is easy to see what’s going on.
One way of getting around this is to take a bite at a time and look at summaries of the marginal posteriors of the variables of interest, the two most common type of summaries being point estimates and credible intervals (an interval that covers a certain percentage of the probability distribution). Here one is faced with a choice, which of the many ways of constructing point estimates and credible intervals to choose? This is a perfectly good question that can be given an unhelpful answer (with a predictable follow-up question):
- That depends on your loss function.
- So which loss function should I use?
Big data is all the rage, but sometimes you don’t have big data. Sometimes you don’t even have average size data. Sometimes you only have eleven unique socks:
![](/blog/2014/10/tiny-data-and-the-socks-of-karl-broman/images/karl_tweet_1.jpeg)
Karl Broman is here putting forward a very interesting problem. Interesting, not only because it involves socks, but because it involves what I would like to call Tiny Data™. The problem is this: Given the Tiny dataset of eleven unique socks, how many socks does Karl Broman have in his laundry in total?
If we had Big Data we might have been able to use some clever machine learning algorithm to solve this problem such as bootstrap aggregated neural networks. But we don’t have Big Data, we have Tiny Data. We can’t pull ourselves up by our bootstraps because we only have socks (eleven to be precise). Instead we will have to build a statistical model that includes a lot more problem specific information. Let’s do that!
As the normal distribution is sort of the default choice when modeling continuous data (but not necessarily the best choice), the Poisson distribution is the default when modeling counts of events. Indeed, when all you know is the number of events during a certain period it is hard to think of any other distribution, whether you are modeling the
number of deaths in the Prussian army due to horse kicks or the
numer of goals scored in a football game. Like the t.test
in R there is also a poisson.test
that takes one or two samples of counts and spits out a p-value. But what if you have some counts, but don’t significantly feel like testing a null hypothesis? Stay tuned!
![Bayesian First Aid logo](/blog/2014/09/bayesian-first-aid-poisson-test/images/bfa_logo_box_x_ray.png)
I was lucky enough to be presenting at
the 14th International Conference on Music Perception and Cognition in Seoul, South Korea, last week. It was a very inspiring conference and I really like South Korea (especially the amazing food…). My presentation was on the topic of subjective rhythmization, a fascinating auditory illusion. See below for my
presentation slides and for a short conference paper that was published in the proceedings of the conference:
![](/blog/2014/08/subjective-rhythmization-at-icmpc-2014-in-seoul/images/icmpc_presentation_first_slides.png)
Bååth, R., Ingvarsdóttir, K. O. (2014) Subjective Rhythmization: A Replication And an Extension. Proceedings of the 13th International Conference on Music Perception and Cognition in Seoul, South Korea.
pdf of full paper
Inspired by events that took place at
UseR 2014 last month I decided to implement an app that estimates one’s blood alcohol concentration (BAC). Today I present to you
drinkR, implemented using R and
Shiny, Rstudio’s framework for building web apps using R. So, say that I had a good dinner, drinking a couple of glasses of wine, followed by an evening at a divy karaoke bar, drinking a couple of
red needles and a couple of beers. By entering my sex, height and weight and the times when I drank the drinks in the
drinkR app I end up with this estimated BAC curve:
![](/blog/2014/07/estimate-your-bac-using-drinkr/images/example_bac_calculation.png)
(Now I might be totally off with what drinks I had and when but
Romain Francois,
Karl Broman,
Sandy Griffith,
Karthik Ram and
Hilary Parker can probably fill in the details.) If you want to estimate your current BAC (or a friend’s…) then head over to
the drinkr app hosted at ShinyApps.io. If you want to know how the app estimates BAC read on below.
The code for drinkR is available on GitHub, any suggestion on how it can be improved is greatly appreciated.
This year’s UseR! conference was held at the University of California in Los Angeles. Despite the great weather and a nearby beach, most of the conference was spent in front of projector screens in 18° c (64° f) rooms because there were so many interesting presentations and tutorials going on. I was lucky to present my R package
Bayesian First Aid and the slides can be found here:
![](/blog/2014/07/chillin-at-user2014/images/user_2014_presentation.png)
Even though I said it would never happen, my silly package with the sole purpose of playing notification sounds is now on CRAN. Big thanks to the CRAN maintainers for their patience! For instant gratification run the following in R to install beepr
and make R produce a notification sound:
install.packages("beepr")
library(beepr)
beep()