Rainier

Rainier

  • Docs
  • GitHub

›Overview

Overview

  • Introduction to Rainier
  • Priors and Random Variables
  • Likelihoods and Observations
  • Vectors and Variables
  • Posteriors and Predictions

Installation

  • Getting Rainier
  • Using Jupyter
  • Roadmap
  • Modules

API Reference

  • Distributions
  • Model and Trace
  • Generator
  • Real
  • Vec
  • Samplers

Implementation

  • Bryant (2020)

Priors and Random Variables

Let's start by importing these two packages, which contain all of the types we will use:

import com.stripe.rainier.core._
import com.stripe.rainier.compute._

Constructing Random Variables

The most fundamental data type in Rainier is the Real, which represents a real-valued scalar random variable. A real-valued scalar is simple enough: that sounds like a Double, and indeed you can treat a Real just like a Double in a lot of ways. But since it's a random variable, it represents a set of possible values rather than one specific known value.

To construct a Real, we very often start with a Distribution object. For example, here we first construct a Uniform(0,1) distribution, and then use latent to create a new latent random variable, a, with that distribution as its prior.

val a = Uniform(0,1).latent
val b = a + 1

/*
a: Real = Real(0.00, 1.00)
b: Real = Real(1.00, 2.00)
*/

Although we don't know the exact value, you can see in the output that Rainier is tracking the bounds of each Real, as best it can: we know that a must be in the range (0,1), which means b must be within (1,2). Seeing these bounds can be a good basic sanity check as you're building a model.

You can combine Reals using normal arithmetic operations, and they support a wide range of unary operators like abs, exp, log, and logit. You can also use a Real for any parameter of a Distribution. So, for example, we can use our b and a as the mean and standard deviation of a new Normal latent variable.

val c = Normal(b, a).latent

/*
c: Real = Real(-Infinity, Infinity)
*/

Sampling from the Prior

The bounds for c are not that helpful: in theory, it can take on any real value. Some values, however, are much more likely than others. To get a view into that, we can sample from c. In fact, we can jointly sample from a and c to get a sense of not just what values are more and less likely for them, but how those values are related to each other.

We'll see a more thorough treatment of sampling later on, but for now, we can use a simple convenience method that's perfect for this kind of exploratory work.

Model.sample((a,c)).take(10)

/*
res0: List[(Double, Double)] = List(
  (0.6156257013298864, 1.095372215976534),
  (0.6055193504418845, 1.1657928784338316),
  (0.6513162868186462, 1.8960333440701265),
  (0.6117323232691895, 0.9805336083328635),
...
*/

You can see a few things here: the sampling process has converted our (a, c) tuple into a list of concrete (Double, Double) tuples. Each of those tuples is an independent joint sample of the (Real, Real) 2-dimensional random variable. We can verify that the values for a are all in that (0,1) range we expected, and that the values for c are a little more widely spread. But to get a better understanding, we should look at a plot.

Visualizing Samples

Rainier comes with plotting support, based on EvilPlot, in a separate rainier-notebook module.

NOTE: this currently is only supported for Scala 2.12.

Importing the package exposes all of the plotting methods:

import com.stripe.rainier.notebook._

Now we can create and render a basic scatter plot of our (a,c) tuples.

val ac = Model.sample((a,c)))
show("a", "c", scatter(ac))

Here, the relationship is a lot clearer! Because we used a as the standard deviation for c, we get a funnel shape where c spreads out more as a gets larger. But we also see that the center of the funnel shifts upwards as a grows, because we set the mean to be b = a + 1.

← Introduction to RainierLikelihoods and Observations →
  • Constructing Random Variables
  • Sampling from the Prior
  • Visualizing Samples
Rainier
Docs
OverviewPaper
Community
Chat on GitterGitHub