{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# What is a distribution?\n", "\n", "An object-oriented exploration of one of the most useful concepts in statistics.\n", "\n", "Copyright 2016 Allen Downey\n", "\n", "MIT License: http://opensource.org/licenses/MIT" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [], "source": [ "from __future__ import print_function, division\n", "\n", "%matplotlib inline\n", "%precision 6\n", "\n", "import matplotlib.pyplot as plt\n", "\n", "import numpy as np\n", "from numpy.fft import fft, ifft" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": true }, "outputs": [], "source": [ "from inspect import getsourcelines\n", "\n", "def show_code(func):\n", " lines, _ = getsourcelines(func)\n", " for line in lines:\n", " print(line, end='')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Playing dice with the universe\n", "\n", "One of the recurring themes of my books is the use of object-oriented programming to explore mathematical ideas. Many mathematical entities are hard to define because they are so abstract. Representing them in Python puts the focus on what operations each entity supports -- that is, what the objects can *do* -- rather than on what they *are*.\n", "\n", "In this notebook, I explore the idea of a probability distribution, which is one of the most important ideas in statistics, but also one of the hardest to explain.\n", "\n", "To keep things concrete, I'll start with one of the usual examples: rolling dice. When you roll a standard six-sided die, there are six possible outcomes -- numbers 1 through 6 -- and all outcomes are equally likely.\n", "\n", "If you roll two dice and add up the total, there are 11 possible outcomes -- numbers 2 through 12 -- but they are not equally likely. The least likely outcomes, 2 and 12, only happen once in 36 tries; the most likely outcome happens 1 times in 6.\n", "\n", "And if you roll three dice and add them up, you get a different set of possible outcomes with a different set of probabilities.\n", "\n", "What I've just described are three random number generators, which are also called **random processes**. The output from a random process is a **random variable**, or more generally a set of random variables. And each random variable has **probability distribution**, which is the set of possible outcomes and the corresponding set of probabilities.\n", "\n", "There are many ways to represent a probability distribution. The most obvious is a **probability mass function**, or PMF, which is a function that maps from each possible outcome to its probability. And in Python, the most obvious way to represent a PMF is a dictionary that maps from outcomes to probabilities.\n", "\n", "Here's a definition for a class named `Pmf` that represents a PMF." ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [], "source": [ "class Pmf:\n", " \n", " def __init__(self, d=None):\n", " \"\"\"Initializes the distribution.\n", "\n", " d: map from values to probabilities\n", " \"\"\"\n", " self.d = {} if d is None else d\n", "\n", " def items(self):\n", " \"\"\"Returns a sequence of (value, prob) pairs.\"\"\"\n", " return self.d.items()\n", " \n", " def __repr__(self):\n", " \"\"\"Returns a string representation of the object.\"\"\"\n", " cls = self.__class__.__name__\n", " return '%s(%s)' % (cls, repr(self.d))\n", "\n", " def __getitem__(self, value):\n", " \"\"\"Looks up the probability of a value.\"\"\"\n", " return self.d.get(value, 0)\n", "\n", " def __setitem__(self, value, prob):\n", " \"\"\"Sets the probability associated with a value.\"\"\"\n", " self.d[value] = prob\n", "\n", " def __add__(self, other):\n", " \"\"\"Computes the Pmf of the sum of values drawn from self and other.\n", "\n", " other: another Pmf or a scalar\n", "\n", " returns: new Pmf\n", " \"\"\"\n", " pmf = Pmf()\n", " for v1, p1 in self.items():\n", " for v2, p2 in other.items():\n", " pmf[v1 + v2] += p1 * p2\n", " return pmf\n", " \n", " def total(self):\n", " \"\"\"Returns the total of the probabilities.\"\"\"\n", " return sum(self.d.values())\n", "\n", " def normalize(self):\n", " \"\"\"Normalizes this PMF so the sum of all probs is 1.\n", "\n", " Args:\n", " fraction: what the total should be after normalization\n", "\n", " Returns: the total probability before normalizing\n", " \"\"\"\n", " total = self.total()\n", " for x in self.d:\n", " self.d[x] /= total\n", " return total\n", " \n", " def mean(self):\n", " \"\"\"Computes the mean of a PMF.\"\"\"\n", " return sum(p * x for x, p in self.items())\n", "\n", " def var(self, mu=None):\n", " \"\"\"Computes the variance of a PMF.\n", "\n", " mu: the point around which the variance is computed;\n", " if omitted, computes the mean\n", " \"\"\"\n", " if mu is None:\n", " mu = self.mean()\n", "\n", " return sum(p * (x - mu) ** 2 for x, p in self.items())\n", "\n", " def expect(self, func):\n", " \"\"\"Computes the expectation of a given function, E[f(x)]\n", "\n", " func: function\n", " \"\"\"\n", " return sum(p * func(x) for x, p in self.items())\n", "\n", " def display(self):\n", " \"\"\"Displays the values and probabilities.\"\"\"\n", " for value, prob in self.items():\n", " print(value, prob)\n", " \n", " def plot_pmf(self, **options):\n", " \"\"\"Plots the values and probabilities.\"\"\"\n", " xs, ps = zip(*sorted(self.items()))\n", " plt.plot(xs, ps, **options)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Each `Pmf` contains a dictionary named `d` that contains the values and probabilities. To show how this class is used, I'll create a `Pmf` that represents a six-sided die:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 1\n", "2 1\n", "3 1\n", "4 1\n", "5 1\n", "6 1\n" ] } ], "source": [ "d6 = Pmf()\n", "for x in range(1, 7):\n", " d6[x] = 1\n", "\n", "d6.display()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Initially the \"probabilities\" are all 1, so the total probability in the `Pmf` is 6, which doesn't make a lot of sense. In a proper, meaningful, PMF, the probabilities add up to 1, which implies that one outcome, and only one outcome, will occur (for any given roll of the die).\n", "\n", "We can take this \"unnormalized\" distribution and make it a proper `Pmf` using the `normalize` method. Here's what the method looks like:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " def normalize(self):\n", " \"\"\"Normalizes this PMF so the sum of all probs is 1.\n", "\n", " Args:\n", " fraction: what the total should be after normalization\n", "\n", " Returns: the total probability before normalizing\n", " \"\"\"\n", " total = self.total()\n", " for x in self.d:\n", " self.d[x] /= total\n", " return total\n" ] } ], "source": [ "show_code(Pmf.normalize)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`normalize` adds up the probabilities in the PMF and divides through by the total. The result is a `Pmf` with probabilities that add to 1.\n", "\n", "Here's how it's used:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 0.16666666666666666\n", "2 0.16666666666666666\n", "3 0.16666666666666666\n", "4 0.16666666666666666\n", "5 0.16666666666666666\n", "6 0.16666666666666666\n" ] } ], "source": [ "d6.normalize()\n", "d6.display()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The fundamental operation provided by a `Pmf` is a \"lookup\"; that is, we can look up an outcome and get the corresponding probability. `Pmf` provides `__getitem__`, so we can use bracket notation to look up an outcome:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "0.166667" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d6[3]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And if you look up a value that's not in the `Pmf`, the probability is 0." ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "0" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d6[7]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exerise:** Create a `Pmf` that represents a six-sided die that is red on two sides and blue on the other four." ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "blue 0.6666666666666666\n", "red 0.3333333333333333\n" ] } ], "source": [ "# Solution\n", "\n", "die = Pmf(dict(red=2, blue=4))\n", "die.normalize()\n", "die.display()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Is that all there is?\n", "\n", "So is a `Pmf` a distribution? No. At least in this framework, a `Pmf` is one of several representations of a distribution. Other representations include the **cumulative distribution function**, or CDF, and the **characteristic function**.\n", "\n", "These representations are equivalent in the sense that they all contain the same informaton; if I give you any one of them, you can figure out the others (and we'll see how soon).\n", "\n", "So why would we want different representations of the same information? The fundamental reason is that there are many different operations we would like to perform with distributions; that is, questions we would like to answer. Some representations are better for some operations, but none of them is the best for all operations.\n", "\n", "So what are the questions we would like a distribution to answer? They include:\n", "\n", "* What is the probability of a given outcome?\n", "* What is the mean of the outcomes, taking into account their probabilities?\n", "* What is the variance, and other moments, of the outcome?\n", "* What is the probability that the outcome exceeds (or falls below) a threshold?\n", "* What is the median of the outcomes, that is, the 50th percentile?\n", "* What are the other percentiles?\n", "* How can get generate a random sample from this distribution, with the appropriate probabilities?\n", "* If we run two random processes and choose the maximum of the outcomes (or minimum), what is the distribution of the result?\n", "* If we run two random processes and add up the results, what is the distribution of the sum?\n", "\n", "Each of these questions corresponds to a method we would like a distribution to provide. But as I said, there is no one representation that answers all of them easily and efficiently. So let's look at the different representations and see what they can do.\n", "\n", "Getting back to the `Pmf`, we've already seen how to look up the probability of a given outcome. Here's the code:" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " def __getitem__(self, value):\n", " \"\"\"Looks up the probability of a value.\"\"\"\n", " return self.d.get(value, 0)\n" ] } ], "source": [ "show_code(Pmf.__getitem__)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Python dictionaries are implemented using hash tables, so we expect `__getitem__` to be fast. In terms of algorithmic complexity, it is constant time, or $O(1)$.\n", "\n", "## Moments and expecations\n", "\n", "The `Pmf` representation is also good for computing mean, variance, and other moments. Here's the implementation of `Pmf.mean`:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " def mean(self):\n", " \"\"\"Computes the mean of a PMF.\"\"\"\n", " return sum(p * x for x, p in self.items())\n" ] } ], "source": [ "show_code(Pmf.mean)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This implementation is efficient, in the sense that it is $O(n)$, and because it uses a comprehension to traverse the outcomes, the overhead is low. \n", "\n", "The implementation of `Pmf.var` is similar:" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " def var(self, mu=None):\n", " \"\"\"Computes the variance of a PMF.\n", "\n", " mu: the point around which the variance is computed;\n", " if omitted, computes the mean\n", " \"\"\"\n", " if mu is None:\n", " mu = self.mean()\n", "\n", " return sum(p * (x - mu) ** 2 for x, p in self.items())\n" ] } ], "source": [ "show_code(Pmf.var)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And here's how they are used:" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(3.500000, 2.916667)" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d6.mean(), d6.var()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The structure of `mean` and `var` is the same: they traverse the outcomes and their probabilities, `x` and `p`, and add up the product of `p` and some function of `x`.\n", "\n", "We can generalize this structure to compute the **expectation** of any function of `x`, which is defined as\n", "\n", "$E[f] = \\sum_x p(x) f(x)$\n", "\n", "`Pmf` provides `expect`, which takes a function object, `func`, and returns the expectation of `func`:" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " def expect(self, func):\n", " \"\"\"Computes the expectation of a given function, E[f(x)]\n", "\n", " func: function\n", " \"\"\"\n", " return sum(p * func(x) for x, p in self.items())\n" ] } ], "source": [ "show_code(Pmf.expect)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As an example, we can use `expect` to compute the third central moment of the distribution: " ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "0.000000" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mu = d6.mean()\n", "d6.expect(lambda x: (x-mu)**3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Because the distribution is symmetric, the third central moment is 0." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Addition\n", "\n", "The next question we'll answer is the last one on the list: if we run two random processes and add up the results, what is the distribution of the sum? In other words, if the result of the first process is a random variable, $X$, and the result of the second is $Y$, what is the distribution of $X+Y$?\n", "\n", "The `Pmf` representation of the distribution can answer this question pretty well, but we'll see later that the characteristic function is even better.\n", "\n", "Here's the implementation:" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " def __add__(self, other):\n", " \"\"\"Computes the Pmf of the sum of values drawn from self and other.\n", "\n", " other: another Pmf or a scalar\n", "\n", " returns: new Pmf\n", " \"\"\"\n", " pmf = Pmf()\n", " for v1, p1 in self.items():\n", " for v2, p2 in other.items():\n", " pmf[v1 + v2] += p1 * p2\n", " return pmf\n" ] } ], "source": [ "show_code(Pmf.__add__)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The outer loop traverses the outcomes and probabilities of the first `Pmf`; the inner loop traverses the second `Pmf`. Each time through the loop, we compute the sum of the outcome pair, `v1` and `v2`, and the probability that the pair occurs.\n", "\n", "Note that this method implicitly assumes that the two processes are independent; that is, the outcome from one does not affect the other. That's why we can compute the probability of the pair by multiplying the probabilities of the outcomes.\n", "\n", "To demonstrate this method, we'll start with `d6` again. Here's what it looks like:" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "d6.plot_pmf()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "When we use the `+` operator, Python invokes the `__add__` method, which returns a new `Pmf` object. Here's the `Pmf` that represents the sum of two dice:" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "twice = d6 + d6\n", "twice.plot_pmf(color='green')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And here's the `Pmf` that represents the sum of three dice." ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "thrice = twice + d6\n", "d6.plot_pmf()\n", "twice.plot_pmf()\n", "thrice.plot_pmf()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As we add up more dice, the result converges to the bell shape of the Gaussian distribution." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exercise:** If you did the previous exercise, you have a `Pmf` that represents a die with red on 2 sides and blue on the other 4. Use the `+` operator to compute the outcomes of rolling two of these dice and the probabilities of the outcomes.\n", "\n", "Note: if you represent the outcomes as strings, the `__add__` method will concatenate them instead of adding, which actually works." ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "redred 0.1111111111111111\n", "redblue 0.2222222222222222\n", "blueblue 0.4444444444444444\n", "bluered 0.2222222222222222\n" ] } ], "source": [ "# Solution\n", "\n", "dice = die + die\n", "dice.display()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Cumulative probabilities" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The next few questions on the list are related to the median and other percentiles. They are harder to answer with the `Pmf` representation, but easier with a **cumulative distribution function** (CDF).\n", "\n", "A CDF is a map from an outcome, $x$, to its cumulative probability, which is the probability that the outcome is less than or equal to $x$. In math notation:\n", "\n", "$CDF(x) = Prob(X \\le x)$\n", "\n", "where $X$ is the outcome of a random process, and $x$ is the threshold we are interested in. For example, if $CDF$ is the cumulative distribution for the sum of three dice, the probability of getting 5 or less is $CDF(5)$, and the probability of getting 6 or more is $1 - CDF(5)$.\n", "\n", "To represent a CDF in Python, I use a sorted list of outcomes and the corresponding list of cumulative probabilities." ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": false }, "outputs": [], "source": [ "class Cdf:\n", " \n", " def __init__(self, xs, ps):\n", " self.xs = xs\n", " self.ps = ps\n", "\n", " def __repr__(self):\n", " return 'Cdf(%s, %s)' % (repr(self.xs), repr(self.ps))\n", "\n", " def __getitem__(self, x):\n", " return self.cumprobs([x])[0]\n", " \n", " def cumprobs(self, values):\n", " \"\"\"Gets probabilities for a sequence of values.\n", "\n", " values: any sequence that can be converted to NumPy array\n", "\n", " returns: NumPy array of cumulative probabilities\n", " \"\"\"\n", " values = np.asarray(values)\n", " index = np.searchsorted(self.xs, values, side='right')\n", " ps = self.ps[index-1]\n", " ps[values < self.xs[0]] = 0.0\n", " return ps\n", "\n", " def values(self, ps):\n", " \"\"\"Returns InverseCDF(p), the value that corresponds to probability p.\n", "\n", " ps: sequence of numbers in the range [0, 1]\n", "\n", " returns: NumPy array of values\n", " \"\"\"\n", " ps = np.asarray(ps)\n", " if np.any(ps < 0) or np.any(ps > 1):\n", " raise ValueError('Probability p must be in range [0, 1]')\n", "\n", " index = np.searchsorted(self.ps, ps, side='left')\n", " return self.xs[index]\n", " \n", " def sample(self, shape):\n", " \"\"\"Generates a random sample from the distribution.\n", " \n", " shape: dimensions of the resulting NumPy array\n", " \"\"\"\n", " ps = np.random.random(shape)\n", " return self.values(ps)\n", " \n", " def maximum(self, k):\n", " \"\"\"Computes the CDF of the maximum of k samples from the distribution.\"\"\"\n", " return Cdf(self.xs, self.ps**k)\n", " \n", " def display(self):\n", " \"\"\"Displays the values and cumulative probabilities.\"\"\"\n", " for x, p in zip(self.xs, self.ps):\n", " print(x, p)\n", " \n", " def plot_cdf(self, **options):\n", " \"\"\"Plots the cumulative probabilities.\"\"\"\n", " plt.plot(self.xs, self.ps, **options)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`compute_cumprobs` takes a dictionary that maps outcomes to probabilities, sorts the outcomes in increasing order, then makes two NumPy arrays: `xs` is the sorted sequence of values; `ps` is the sequence of cumulative probabilities:" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def compute_cumprobs(d):\n", " \"\"\"Computes cumulative probabilities.\n", " \n", " d: map from values to probabilities\n", " \"\"\"\n", " xs, freqs = zip(*sorted(d.items()))\n", " xs = np.asarray(xs)\n", " ps = np.cumsum(freqs, dtype=np.float)\n", " ps /= ps[-1]\n", " return xs, ps" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here's how we use it to create a `Cdf` object for the sum of three dice:" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3 0.00462962962963\n", "4 0.0185185185185\n", "5 0.0462962962963\n", "6 0.0925925925926\n", "7 0.162037037037\n", "8 0.259259259259\n", "9 0.375\n", "10 0.5\n", "11 0.625\n", "12 0.740740740741\n", "13 0.837962962963\n", "14 0.907407407407\n", "15 0.953703703704\n", "16 0.981481481481\n", "17 0.99537037037\n", "18 1.0\n" ] } ], "source": [ "xs, ps = compute_cumprobs(thrice.d)\n", "cdf = Cdf(xs, ps)\n", "cdf.display()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Because we have to sort the values, the time to compute a `Cdf` is $O(n \\log n)$.\n", "\n", "Here's what the CDF looks like:" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": "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\nAAAASUVORK5CYII=\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "cdf.plot_cdf()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The range of the CDF is always from 0 to 1.\n", "\n", "Now we can compute $CDF(x)$ by searching the `xs` to find the right location, or index, and then looking up the corresponding probability. Because the `xs` are sorted, we can use bisection search, which is $O(\\log n)$.\n", "\n", "`Cdf` provides `cumprobs`, which takes an array of values and returns the corresponding probabilities:" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " def cumprobs(self, values):\n", " \"\"\"Gets probabilities for a sequence of values.\n", "\n", " values: any sequence that can be converted to NumPy array\n", "\n", " returns: NumPy array of cumulative probabilities\n", " \"\"\"\n", " values = np.asarray(values)\n", " index = np.searchsorted(self.xs, values, side='right')\n", " ps = self.ps[index-1]\n", " ps[values < self.xs[0]] = 0.0\n", " return ps\n" ] } ], "source": [ "show_code(Cdf.cumprobs)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The details here are a little tricky because we have to deal with some \"off by one\" problems, and if any of the values are less than the smallest value in the `Cdf`, we have to handle that as a special case. But the basic idea is simple, and the implementation is efficient.\n", "\n", "Now we can look up probabilities for a sequence of values:" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([ 0. , 0.5, 1. ])" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cdf.cumprobs((2, 10, 18))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`Cdf` also provides `__getitem__`, so we can use brackets to look up a single value:" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "0.046296" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cdf[5]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exercise:** If you roll three dice, what is the probability of getting 15 or more?" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "0.092593" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Solution\n", "\n", "1 - cdf[14]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Reverse lookup\n", "\n", "You might wonder why I represent a `Cdf` with two lists rather than a dictionary. After all, a dictionary lookup is constant time and bisection search is logarithmic. The reason is that we often want to use a `Cdf` to do a reverse lookup; that is, given a probability, we would like to find the corresponding value. With two sorted lists, a reverse lookup has the same performance as a forward loopup, $O(\\log n)$.\n", "\n", "Here's the implementation:" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " def values(self, ps):\n", " \"\"\"Returns InverseCDF(p), the value that corresponds to probability p.\n", "\n", " ps: sequence of numbers in the range [0, 1]\n", "\n", " returns: NumPy array of values\n", " \"\"\"\n", " ps = np.asarray(ps)\n", " if np.any(ps < 0) or np.any(ps > 1):\n", " raise ValueError('Probability p must be in range [0, 1]')\n", "\n", " index = np.searchsorted(self.ps, ps, side='left')\n", " return self.xs[index]\n" ] } ], "source": [ "show_code(Cdf.values)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And here's an example that finds the 10th, 50th, and 90th percentiles:" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([ 7, 10, 14])" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cdf.values((0.1, 0.5, 0.9))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `Cdf` representation is also good at generating random samples, by choosing a probability uniformly from 0 to 1 and finding the corresponding value. Here's the method `Cdf` provides:" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " def sample(self, shape):\n", " \"\"\"Generates a random sample from the distribution.\n", " \n", " shape: dimensions of the resulting NumPy array\n", " \"\"\"\n", " ps = np.random.random(shape)\n", " return self.values(ps)\n" ] } ], "source": [ "show_code(Cdf.sample)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The result is a NumPy array with the given `shape`. The time to generate each random choice is $O(\\log n)$\n", "\n", "Here are some examples that use it." ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([11])" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cdf.sample(1)" ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([12, 12, 8, 11, 12, 10])" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cdf.sample(6)" ] }, { "cell_type": "code", "execution_count": 34, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[11, 12],\n", " [11, 10]])" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cdf.sample((2, 2))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exercise:** Write a function that takes a `Cdf` object and returns the interquartile range (IQR), which is the difference between the 75th and 25th percentiles." ] }, { "cell_type": "code", "execution_count": 35, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "5" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Solution\n", "\n", "def iqr(cdf):\n", " values = cdf.values((0.25, 0.75))\n", " return np.diff(values)[0]\n", "\n", "iqr(cdf)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Max and min\n", "\n", "The `Cdf` representation is particularly good for finding the distribution of a maximum. For example, in Dungeons and Dragons, players create characters with random properties like strength and intelligence. The properties are generated by rolling three dice and adding them, so the CDF for each property is the `Cdf` we used in this example. Each character has 6 properties, so we might wonder what the distribution is for the best of the six.\n", "\n", "Here's the method that computes it:" ] }, { "cell_type": "code", "execution_count": 36, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " def maximum(self, k):\n", " \"\"\"Computes the CDF of the maximum of k samples from the distribution.\"\"\"\n", " return Cdf(self.xs, self.ps**k)\n" ] } ], "source": [ "show_code(Cdf.maximum)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To get the distribution of the maximum, we make a new `Cdf` with the same values as the original, and with the `ps` raised to the `k`th power. Simple, right?\n", "\n", "To see how it works, suppose you generate six properties and your best is only a 10. That's unlucky, but you might wonder how unlucky. So, what is the chance of rolling 3 dice six times, and never getting anything better than 10?\n", "\n", "Well, that means that all six values were 10 or less. The probability that each of them is 10 or less is $CDF(10)$, because that's what the CDF means. So the probability that all 6 are 10 or less is $CDF(10)^6$. \n", "\n", "Now we can generalize that by replacing $10$ with any value of $x$ and $6$ with any integer $k$. The result is $CDF(x)^k$, which is the probability that all $k$ rolls are $x$ or less, and that is the CDF of the maximum.\n", "\n", "Here's how we use `Cdf.maximum`:" ] }, { "cell_type": "code", "execution_count": 37, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "best = cdf.maximum(6)\n", "best.plot_cdf()" ] }, { "cell_type": "code", "execution_count": 38, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "0.015625" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "best[10]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So the chance of generating a character whose best property is 10 is less than 2%." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exercise:** Write a function that takes a CDF and returns the CDF of the *minimum* of `k` values.\n", "\n", "Hint: If the minimum is less than $x$, that means all `k` values must be less than $x$." ] }, { "cell_type": "code", "execution_count": 39, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Solution\n", "\n", "def minimum(cdf, k):\n", " return Cdf(cdf.xs, 1 - (1-cdf.ps)**k)\n", "\n", "worst = minimum(cdf, 6)\n", "worst.plot_cdf()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Characteristic function\n", "\n", "At this point we've answered all the questions on the list, but I want to come back to addition, because the algorithm we used with the `Pmf` representation is not as efficient as it could be. It enumerates all pairs of outcomes, so if there are $n$ values in each `Pmf`, the run time is $O(n^2)$. We can do better.\n", "\n", "The key is the **characteristic function**, which is the Fourier transform (FT) of the PMF. If you are familiar with the Fourier transform and the Convolution Theorem, keep reading. Otherwise, skip the rest of this cell and get to the code, which is much simpler than the explanation.\n", "\n", "### Details for people who know about convolution\n", "\n", "If you are familiar with the FT in the context of spectral analysis of signals, you might wonder why we would possibly want to compute the FT of a PMF. The reason is the Convolution Theorem.\n", "\n", "It turns out that the algorithm we used to \"add\" two `Pmf` objects is a form of convolution. To see how that works, suppose we are computing the distribution of $Z = X+Y$. To make things concrete, let's compute the probability that the sum, $Z$ is 5. To do that, we can enumerate all possible values of $X$ like this:\n", "\n", "$Prob(Z=5) = \\sum_x Prob(X=x) \\cdot Prob(Y=5-x)$\n", "\n", "Now we can write each of those probabilities in terms of the PMF of $X$, $Y$, and $Z$:\n", "\n", "$PMF_Z(5) = \\sum_x PMF_X(x) \\cdot PMF_Y(5-x)$\n", "\n", "And now we can generalize by replacing 5 with any value of $z$:\n", "\n", "$PMF_Z(z) = \\sum_x PMF_X(x) \\cdot PMF_Y(z-x)$\n", "\n", "You might recognize that computation as convolution, denoted with the operator $\\ast$. \n", "\n", "$PMF_Z = PMF_X \\ast PMF_Y$\n", "\n", "Now, according to the Convolution Theorem:\n", "\n", "$FT(PMF_X \\ast Y) = FT(PMF_X) \\cdot FT(PMF_Y)$\n", "\n", "Or, taking the inverse FT of both sides:\n", "\n", "$PMF_X \\ast PMF_Y = IFT(FT(PMF_X) \\cdot FT(PMF_Y))$\n", "\n", "In words, to compute the convolution of $PMF_X$ and $PMF_Y$, we can compute the FT of $PMF_X$ and $PMF_Y$ and multiply them together, then compute the inverse FT of the result.\n", "\n", "Let's see how that works. Here's a class that represents a characteristic function." ] }, { "cell_type": "code", "execution_count": 40, "metadata": { "collapsed": false }, "outputs": [], "source": [ "class CharFunc:\n", " \n", " def __init__(self, hs):\n", " \"\"\"Initializes the CF.\n", " \n", " hs: NumPy array of complex\n", " \"\"\"\n", " self.hs = hs\n", "\n", " def __mul__(self, other):\n", " \"\"\"Computes the elementwise product of two CFs.\"\"\"\n", " return CharFunc(self.hs * other.hs)\n", " \n", " def make_pmf(self, thresh=1e-11):\n", " \"\"\"Converts a CF to a PMF.\n", " \n", " Values with probabilities below `thresh` are dropped.\n", " \"\"\"\n", " ps = ifft(self.hs)\n", " d = dict((i, p) for i, p in enumerate(ps.real) if p > thresh)\n", " return Pmf(d)\n", " \n", " def plot_cf(self, **options):\n", " \"\"\"Plots the real and imaginary parts of the CF.\"\"\"\n", " n = len(self.hs)\n", " xs = np.arange(-n//2, n//2)\n", " hs = np.roll(self.hs, len(self.hs) // 2)\n", " plt.plot(xs, hs.real, label='real', **options)\n", " plt.plot(xs, hs.imag, label='imag', **options)\n", " plt.legend()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The attribute, `hs`, is the Fourier transform of the `Pmf`, represented as a NumPy array of complex numbers.\n", "\n", "The following function takes a dictionary that maps from outcomes to their probabilities, and computes the FT of the PDF:" ] }, { "cell_type": "code", "execution_count": 41, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def compute_fft(d, n=256):\n", " \"\"\"Computes the FFT of a PMF of integers.\n", " \n", " Values must be integers less than `n`.\n", " \"\"\"\n", " xs, freqs = zip(*d.items())\n", " ps = np.zeros(256)\n", " ps[xs,] = freqs\n", " hs = fft(ps)\n", " return hs" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`fft` computes the Fast Fourier Transform (FFT), which is called \"fast\" because the run time is $O(n \\log n)$.\n", "\n", "Here's what the characteristic function looks like for the sum of three dice (plotting the real and imaginary parts of `hs`):" ] }, { "cell_type": "code", "execution_count": 42, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": "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\nIqBBwN66AAAAAElFTkSuQmCC\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "hs = compute_fft(thrice)\n", "cf = CharFunc(hs)\n", "cf.plot_cf()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The characteristic function contains all of the information from the `Pmf`, but it is encoded in a form that is hard to interpret. However, if we are given a characteristic function, we can find the corresponding `Pmf`.\n", "\n", "`CharFunc` provides `make_pmf`, which uses the inverse FFT to get back to the `Pmf` representation. Here's the code:" ] }, { "cell_type": "code", "execution_count": 43, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " def make_pmf(self, thresh=1e-11):\n", " \"\"\"Converts a CF to a PMF.\n", " \n", " Values with probabilities below `thresh` are dropped.\n", " \"\"\"\n", " ps = ifft(self.hs)\n", " d = dict((i, p) for i, p in enumerate(ps.real) if p > thresh)\n", " return Pmf(d)\n" ] } ], "source": [ "show_code(CharFunc.make_pmf)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And here's an example:" ] }, { "cell_type": "code", "execution_count": 44, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": "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\noqIvIpJH/j9DZ00gA8SJ+QAAAABJRU5ErkJggg==\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "cf.make_pmf().plot_pmf()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we can use the characteristic function to compute a convolution. `CharFunc` provides `__mul__`, which multiplies the `hs` elementwise and returns a new `CharFunc` object:" ] }, { "cell_type": "code", "execution_count": 45, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " def __mul__(self, other):\n", " \"\"\"Computes the elementwise product of two CFs.\"\"\"\n", " return CharFunc(self.hs * other.hs)\n" ] } ], "source": [ "show_code(CharFunc.__mul__)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And here's how we can use it to compute the distribution of the sum of 6 dice." ] }, { "cell_type": "code", "execution_count": 46, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "sixth = (cf * cf).make_pmf()\n", "sixth.plot_pmf()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here are the probabilities, mean, and variance." ] }, { "cell_type": "code", "execution_count": 47, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "6 2.14334705076e-05\n", "7 0.000128600823045\n", "8 0.000450102880659\n", "9 0.00120027434842\n", "10 0.00270061728395\n", "11 0.0054012345679\n", "12 0.00977366255144\n", "13 0.0162037037037\n", "14 0.0248842592593\n", "15 0.0357081618656\n", "16 0.0481610082305\n", "17 0.0612139917695\n", "18 0.0735382373114\n", "19 0.0837191358025\n", "20 0.0904706790123\n", "21 0.0928497942387\n", "22 0.0904706790123\n", "23 0.0837191358025\n", "24 0.0735382373114\n", "25 0.0612139917695\n", "26 0.0481610082305\n", "27 0.0357081618656\n", "28 0.0248842592593\n", "29 0.0162037037037\n", "30 0.00977366255144\n", "31 0.0054012345679\n", "32 0.00270061728395\n", "33 0.00120027434842\n", "34 0.000450102880658\n", "35 0.000128600823045\n", "36 2.14334705075e-05\n" ] } ], "source": [ "sixth.display()" ] }, { "cell_type": "code", "execution_count": 48, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(21.000000, 17.500000)" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sixth.mean(), sixth.var()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This might seem like a roundabout way to compute a convolution, but it is efficient. The time to Compute the `CharFunc` objects is $O(n \\log n)$. Multiplying them together is $O(n)$. And converting back to a `Pmf` is $O(n \\log n)$.\n", "\n", "So the whole process is $O(n \\log n)$, which is better than `Pmf.__add__`, which is $O(n^2)$." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exercise:** Plot the magnitude of `cf.hs` using `np.abs`. What does that shape look like?\n", "\n", "Hint: it might be clearer if you us `np.roll` to put the peak of the CF in the middle." ] }, { "cell_type": "code", "execution_count": 49, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "#Solution\n", "\n", "n = len(cf.hs)\n", "mags = np.abs(cf.hs)\n", "plt.plot(np.roll(mags, n//2))\n", "None\n", "\n", "# The result approximates a Gaussian curve because \n", "# the PMF is approximately Gaussian and the FT of a \n", "# Gaussian is also Gaussian" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Distributions\n", "\n", "Finally, let's back to the question we started with: *what is a distribution?*\n", "\n", "I've said that `Pmf`, `Cdf`, and `CharFunc` are different ways to represent the same information. For the questions we want to answer, some representations are better than others. But how should we represent the distribution itself?\n", "\n", "One option is to treat each representation as a **mixin**; that is, a class that provides a set of capabilities. A distribution inherits all of the capabilities from all of the representations. Here's a class that shows what I mean:" ] }, { "cell_type": "code", "execution_count": 50, "metadata": { "collapsed": false }, "outputs": [], "source": [ "class Dist(Pmf, Cdf, CharFunc):\n", " \n", " def __init__(self, d):\n", " \"\"\"Initializes the Dist.\n", " \n", " Calls all three __init__ methods.\n", " \"\"\"\n", " Pmf.__init__(self, d)\n", " Cdf.__init__(self, *compute_cumprobs(d))\n", " CharFunc.__init__(self, compute_fft(d))\n", " \n", " def __add__(self, other):\n", " \"\"\"Computes the distribution of the sum using Pmf.__add__.\n", " \"\"\"\n", " pmf = Pmf.__add__(self, other)\n", " return Dist(pmf.d)\n", " \n", " def __mul__(self, other):\n", " \"\"\"Computes the distribution of the sum using CharFunc.__mul__.\n", " \"\"\"\n", " pmf = CharFunc.__mul__(self, other).make_pmf()\n", " return Dist(pmf.d)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "When you create a `Dist`, you provide a dictionary of values and probabilities.\n", "\n", "`Dist.__init__` calls the other three `__init__` methods to create the `Pmf`, `Cdf`, and `CharFunc` representations. The result is an object that has all the attributes and methods of the three representations.\n", "\n", "As an example, I'll create a `Dist` that represents the sum of six dice:" ] }, { "cell_type": "code", "execution_count": 51, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "dist = Dist(sixth.d)\n", "dist.plot_pmf()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We inherit `__getitem__` from `Pmf`, so we can look up the probability of a value." ] }, { "cell_type": "code", "execution_count": 52, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "0.092850" ] }, "execution_count": 52, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dist[21]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We also get mean and variance from `Pmf`:" ] }, { "cell_type": "code", "execution_count": 53, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(21.000000, 17.500000)" ] }, "execution_count": 53, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dist.mean(), dist.var()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But we can also use methods from `Cdf`, like `values`:" ] }, { "cell_type": "code", "execution_count": 54, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([18, 21, 24])" ] }, "execution_count": 54, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dist.values((0.25, 0.5, 0.75))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And `cumprobs`" ] }, { "cell_type": "code", "execution_count": 55, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([ 0.279385, 0.546425, 0.794153])" ] }, "execution_count": 55, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dist.cumprobs((18, 21, 24))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And `sample` and `plot_cdf`" ] }, { "cell_type": "code", "execution_count": 56, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([14, 14, 25, 20, 26, 18, 16, 15, 15, 22])" ] }, "execution_count": 56, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dist.sample(10)" ] }, { "cell_type": "code", "execution_count": 57, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "dist.maximum(6).plot_cdf()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`Dist.__add__` uses `Pmf.__add__`, which performs convolution the slow way:" ] }, { "cell_type": "code", "execution_count": 58, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "twelfth = dist + dist\n", "twelfth.plot_pmf()" ] }, { "cell_type": "code", "execution_count": 59, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "42.000000" ] }, "execution_count": 59, "metadata": {}, "output_type": "execute_result" } ], "source": [ "twelfth.mean()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`Dist.__mul__` uses `CharFunc.__mul__`, which performs convolution the fast way." ] }, { "cell_type": "code", "execution_count": 60, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "twelfth_fft = dist * dist\n", "twelfth_fft.plot_pmf()" ] }, { "cell_type": "code", "execution_count": 61, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "42.000000" ] }, "execution_count": 61, "metadata": {}, "output_type": "execute_result" } ], "source": [ "twelfth_fft.mean()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Either way, we get the right answer, which is 42, of course." ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "## Summary\n", "\n", "Abstractly, a distribution is an entity that can answer questions about the outcomes of random variables and their probabilities. There are many ways to represent a distribution; each representation is equivalent to the others in the sense that they contain the same information, and you can convert from any of them to the others. \n", "\n", "Some representations make it easy and efficient to answer some questions, but none of the representations is best for all of the questions.\n", "\n", "In my implementation, a `Dist` object has the attributes and methods of all representations. From a software engineering point of view, that might not be the best design, but it is meant to illustrate what it means to be a distribution.\n", "\n", "In short, if you give me any representation of a distribution, you have told me everything I need to know to answer questions about the possible outcomes and their probabilities. Converting from one representation to another is mostly a matter of convenience and computational efficiency.\n", "\n", "Conversely, if you are trying to find the distribution of a random variable, you can do it by computing whichever representation is easiest to figure out." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.5.1" } }, "nbformat": 4, "nbformat_minor": 0 }