prophet/notebooks/forecasting_growth.ipynb

254 lines
175 KiB
Text
Raw Normal View History

2017-02-22 23:59:43 +00:00
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"block_hidden": true,
"collapsed": false
},
"outputs": [],
"source": [
"%load_ext rpy2.ipython\n",
"%matplotlib inline\n",
"from fbprophet import Prophet\n",
"import pandas as pd"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"block_hidden": true,
"collapsed": false
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/usr/lib/python2.7/dist-packages/rpy2/rinterface/__init__.py:186: RRuntimeWarning: Loading required package: Rcpp\n",
"\n",
" warnings.warn(x, RRuntimeWarning)\n"
]
}
],
"source": [
"%%R\n",
"library(prophet)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"By default, Prophet uses a linear model for its forecast. When forecasting growth, there is usually some maximum achievable point: total market size, total population size, etc. This is called the carrying capacity, and the forecast should saturate at this point.\n",
"\n",
"Prophet allows you to make forecasts using a [logistic growth](https://en.wikipedia.org/wiki/Logistic_function) trend model, with a specified carrying capacity. We illustrate this with the log number of page visits to the [R (programming language)](https://en.wikipedia.org/wiki/R_%28programming_language%29) page on Wikipedia:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"df = pd.read_csv('../examples/example_wp_R.csv')\n",
"import numpy as np\n",
"df['y'] = np.log(df['y'])"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"%%R\n",
"df <- read.csv('../examples/example_wp_R.csv')\n",
"df$y <- log(df$y)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We must specify the carrying capacity in a column `cap`. Here we will assume a particular value, but this would usually be set using data or expertise about the market size."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"df['cap'] = 8.5"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"%%R\n",
"df$cap <- 8.5"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The important things to note are that `cap` must be specified for every row in the dataframe, and that it does not have to be constant. If the market size is growing, then `cap` can be an increasing sequence.\n",
"\n",
"We then fit the model as before, except pass in an additional argument to specify logistic growth:"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": false,
"output_hidden": true
},
"outputs": [
{
"data": {
"text/plain": [
"<fbprophet.forecaster.Prophet at 0x7f15cdd81bd0>"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"m = Prophet(growth='logistic')\n",
"m.fit(df)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"collapsed": false,
"output_hidden": true
},
"outputs": [
{
"data": {
"text/plain": [
"STAN OPTIMIZATION COMMAND (LBFGS)\n",
"init = user\n",
"save_iterations = 1\n",
"init_alpha = 0.001\n",
"tol_obj = 1e-12\n",
"tol_grad = 1e-08\n",
"tol_param = 1e-08\n",
"tol_rel_obj = 10000\n",
"tol_rel_grad = 1e+07\n",
"history_size = 5\n",
"seed = 625631580\n",
"initial log joint probability = -67.9808\n",
"Optimization terminated normally: \n",
" Convergence detected: relative gradient magnitude is below tolerance\n"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%%R\n",
"m <- prophet(df, growth = 'logistic')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We make a dataframe for future predictions as before, except we must also specify the capacity in the future. Here we keep capacity constant at the same value as in the history, and forecast 3 years into the future:"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"collapsed": false,
"output_hidden": true
},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAskAAAGpCAYAAAB/KasqAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzsnXd8XNW1tt8zzb1XbFzoNmBssAyRSUA3BieBewmhpUNI\nwNybckly80EgIYRAIL2TYmrAhG5Mb5YRzTK2bBlLsuRuy+p1+swpe+/vj33qzEiWbZUZsp78iGbm\nlF3OyHrPOu9eSxFCCBAEQRAEQRAEYeMb6g4QBEEQBEEQRL5BIpkgCIIgCIIgMiCRTBAEQRAEQRAZ\nkEgmCIIgCIIgiAxIJBMEQRAEQRBEBiSSCYIgCIIgCCIDEskEQRAEQRAEkQGJZIIgCIIgCILIgEQy\nQRAEQRAEQWQQGOoOuJk8eTLmzp071N0oKHRdRzAYHOpu/FtBcz400LwPPjTnQwPN++BDcz40DNW8\n79+/Hx0dHYfcL69E8ty5c1FRUTHU3SgompqaMGPGjKHuxr8VNOdDA8374ENzPjTQvA8+NOdDw1DN\ne1FRUZ/2I7sFQRAEQRAEQWRAIpkgCIIgCIIgMiCRTBAEQRAEQRAZkEgmCIIgCIIgiAxIJBMEQRAE\nQRBEBiSSCYIgCIIgCCIDEskEQRAEQRAEkQGJZIIgCIIgCILIgEQyQRAEQRAEQWRAIpkgCIIgCIIg\nMiCRTBAEQRAEQRAZkEgmCIIgCIIgiAxIJBMEQRAEQRBEBiSSCYIgiH6lvLwc99xzD8rLy4e6KwRB\nEEdMYKg7QBAEQXx0KC8vx7Jly6BpGkKhEEpLS1FcXDzU3SIIgjhsKJJMEARB9BtlZWXQNA2MMWia\nhrKysqHuEkEQxBExoCL5j3/8I04//XScdtpp+MMf/jCQTREEQRB5QElJCUKhEPx+P0KhEEpKSoa6\nSwRBEEfEgNktqqurcd9992Hjxo0IhUL49Kc/jYsvvhgnnXTSQDVJEARBDDHFxcUoLS1FWVkZSkpK\nyGpBEETBMmAiuba2Fh/72McwcuRIAMD555+P5557DjfddNNANUkQBEHkAcXFxSSOCYIoeAZMJJ9+\n+un40Y9+hM7OTowYMQKvvPIKioqKsvZbuXIlVq5cCQBoaWlBU1PTQHXpI0l7e/tQd+HfDprzoYHm\nffChOR8aaN4HH5rzoSHf533ARPL8+fNx880348ILL8To0aOxcOFCBALZza1YsQIrVqwAABQVFWHG\njBkD1aWPLDRngw/N+dBA8z740JwPDTTvgw/N+dCQz/M+oAv3vvGNb2DLli145513MHHiRPIjEwRB\nEARBEAXBgOZJbmtrw9SpU1FfX4/Vq1dTYnmCIIg8pry8nBbcEQRBmAyoSL788svR2dmJYDCIe++9\nFxMmTBjI5giCIIgjJFcRkDlz5gx1twiCIIaMARXJ77777kCeniAIgugnchUBueaaa4a6WwRBEEMG\nVdwjCIIgqAgIQRQ4jZEUaltjQ92NjxQDGkkmCIIgCoNcRUAoJSdBFA5xlSGc0oe6Gx8pSCQTBEEQ\nAKgICEEUMj4F4EIMdTc+UpDdgiAIgiAI4iMA40Pdg48WJJIJgiAIgiAKHEVRICiS3K+QSCYIgiAI\ngjDZfDAMvRBDskKACwHGSSj3FySSCYIgCIIgTAwuClIkCwFwAdS5Mlzs6UhAMwpvLPkCiWSCIAiC\nIAgTLgQK0bWgKIDOBGIqsz/rSGhoiqaHsFeFDYlkgiAIgiAIk0K0KzAu0JXSwYQAcyl8gwu0xVXy\nKh8hlAKOIAiCIAgCQFpnYFyg0CRlSmfQGYcQwiOILcHPuEDArwxV9woWiiQTBEEQBNGvxNIG4qox\n1N04bLY1R2EIgY6ENtRdOSw0xpHWOQTgEfjCXMxXgMHxvIBEMkEQBEEQ/cr21hjqWuND3Y3DRmcc\nnAONkXTBWRSYkIv3rG7v7kiACQHOxYAXGYmm9T7Nl1FgCyJJJBMEQRAE0a8w7vXGFgqGabUwGLet\nCpyLvBd3Qsh+AoBlFmmKpCEEYIiBF8k72uLY05nsVShrBsfmhkhBeb5JJBMEQRAE0W9Ynt7Cc/ZK\noSmEMIWlfL+9NYbNDZGh7lqvCCFg/08ADeEUGOd2dDmhsZzH9Bc6E2iOppHSs9uxMDhH2vROFwok\nkgmCIAiC6DcawikZeS08jQxbvgkp8hsjaSQ0BtXgONidGsqu9YoAbN+xwQWaomlwYYpnAezpSNr7\naoYUqxUHw2iNqUfdNuMChhltr2mJ9bhfdUtMptc76hYHD8puQRAEQRBEv2FwAZUJDAsWXjYFzk1f\nL6ziHAJpg0FnApG0jlkYMdRdBOcCPp93bmVQWHbcYAIpjZkiGRAKoDKGioPdGB7wI23IbQYT2N+V\nREpnmDNhBBTl8K9XXDVQ1RyViwMBqAbP2T8ASOscHP0bwR5oKJJMEARBEHkI5wKxdOFliBAAGOcw\nGPf0vxDEkWUTEUIKwI6EBp1J64U6wDaBuGqgPa4i3YtloSupYXNDGC0ZBUK8kWQO3VysJ8ciI72q\nIZDSGdI6h2Zw6IxDNThaYyrias9t9kZNSwyqwc0FgvIGKZcXnXMBxnnBFWkhkVzgVFRU4J577kF5\neflQd4UgCILoRzoSGuraen58na9wzqWoNDjaE/JxfmtMRcXBcF4LZSvHsJVG7UB3ShbnMH3KuiEG\nbNFZSzSNmpYYalvj2NuZ7HG/nW0JxFUD8QyPsWWrsPou+2xtk/8xLqAzgbTBHYsEl0L5SDE4tysU\nSqEucvqfw2ndjmw3RY/e4jFYkN2igCkvL8fnP/956LqOUCiE0tJSFBcXD3W3CIIgiKPEYBz7upIF\nlQnAwvLCGq6+7+9KQmMcBhcI5mlRC3f6NKv/luVCQArCllgaM8d5LRdpnYELgZGhI5dUCY1BMyO7\nMdWAzjiC/uw4pqII6BzQcwhbt9vX6/0V4EIBFwIGl9dHVuYD/Oa4jsQp3JXUwDjAOOzsGVwo2NUe\nx5LZEzz77mpPyIWQQqAjruHEyaMOu72hgCLJBUxZWRl0XQdjDJqmoaysbKi7RBAEQfQDTAjzsXnh\nZAKwsKKKlkjmZtSSDUK+XgC92hV6w221AGTOZCkgpWjWXGnhKg52Y0dbHC3RNKpbotjaGD3qfmtM\nRmXTOkNzhp3C7qOZcaMnUet4qR3Rb/WfC2l5kHmTTQuEuW9v0etcqAZDXWtcns+KJJvn0kxbimow\nVDVF0BxNy/zT5sQW0neaRHIBU1JSgmAwCL/fj1AohJKSkqHuEkEQBNEPCAFbWDZFcgumfIXZokmY\ngk5GEJkQ2HeYYuyw2+YCVc2HFqyqkVtIW9JTmB5kK5osrwfQHteQUA2ohkB3UkdTNI2kJvc7EnEu\nhMCBriTCKR0Gk0JWd1klcvWP9xT1taLgsEpTO/X3bMuFkMczLsBhXh8BxFQD2mHYLna2J6AazIxM\nu9PPCWgGRzilo7Y1jnDaQFMkbds/LNtHoUB2iwKmuLgYTz75JGpqalBSUkJWC4IgiI8IArAjfo2R\nFGaMGy4/F+KIshAMJlaUUwCIqcysYicXdnUmB7bcc1w1oDGB9riKKaOH5dzHYBxbG6M4YdJITM65\njwCg2IU4LJ8y4xw6E6hri8PgHAyKtD6YC9K2t8Zx1rHjDqu/HQkNbXHVtiJwISPYLTEVE0eGMGa4\nI9OsaLAQAgmdeb4LArIfiqLApyiwkl3YxyqO5cKTvUMR8EGRxVNcypxxAZ+CrO+a9TQgqTkCmQvA\nncyCA6hrjUNRnOi4IZzodz770jOhSDJBEATxkSWpHV6ELJ+Q6bKcrAUAsK0pmtf5egHrEb8UY0md\nobrFTBEm5MKxhnDu/vdWiKKv7GiXAnZnexwHunJHrTUmMzvsaE/0PAaz/3ZhFPO15Ru2Sj0zLkxf\nroBqHH6hDL9PQVJnpq9ZtmwJ5ZTOPN/d5qgKzZCCXDcEupK6va0lmsaVj2zBK7Vtsv/CHUd2FtXZ\nEX4z6mv9Z/nILSobw9j
"text/plain": [
"<matplotlib.figure.Figure at 0x7f15ce230d10>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"future = m.make_future_dataframe(periods=1826)\n",
"future['cap'] = 8.5\n",
"fcst = m.predict(future)\n",
"m.plot(fcst);"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/png": "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\npFTLjt1pfm6A054T1qfr4AhaPaHVEzfqFP2i/DrnjP8IkIUDgUAgEA7ROfNiu+/31F6Lw27UK67V\nyjt+9g6OAAAaHQCAXKvv+FD3FIS3USgUUivUarV1o7PMnTuXusyHHnqIai8uLqbfgfz8fGrXkiVL\nqPaJEydS7Q0NDfQu2dnZ1K6VK1dS7f3796cLIBAIqF3btm2j2j/++GOqPSUlhd4lOjqa2vX5559T\n7Zs3b6bag4OD6V0yMjKoXatXr6bad+3aRbUzGAypVCqTyQiCkEqlw4cPp3YtX76c6pKTk0O/zIqK\nCmrXAw88QLU//vjjVHtBQQG9S0FBAbWLnsR92rRpVHtFRQW9y/Hjx6ldy5Yto9qHDx9Ov0wcNynH\nu3btotrfffddqj0jI4PeJSgoiNr17bffUu2ff/451R4TE0PvkpKSQu1at24d1f7zzz9T7QKBgN6l\nf//+1K6VK1dS7QcPHqRfZkNDA7VrwoQJVPvSpUup9vz8fHqXmzdvUrseeughqp3+MN+8eZPe5ezZ\ns9SupUuXUu0TJkyg2i0e5oMHD1K7HHyYf/75Z6p93bp1VLvFw0yPA//ss8+o9m+//ZZqDwoKoneh\nP8zvvvsu9cT+8ccfVDuO4/QuI0aMoHYtW7aMardw0KY/zNOmTaPaH3vsMardwYd5xGzT819ZWUnv\nkpOTQ+1avnw51W7xMNMLKtEf5tWrV1PtPXr0oHcJDg6mdm3evFkqlebeqMy9UfnKuv9BaBL5T2j6\nQHqX1NRUqsvHH39MtW/bto1qt/0whyZBaNJjr5h+TEye76FJEJpUX19P7Rr0wMOUALOWvkJKlXuj\ncsuBk1Q7hCb9fvIy2S6VSufNm0cJMHfuXGqokpIS+lm2HDhJjTb7mRXUUAPvn0+1H7ly13T3Q5Mm\nr9sT/sYBctfjK9ZQXbqPnEp1yb1RyYtLN+wC+Omnn6j2Tz75hDp7TJ8R9C7hGYOp0f7v46+p9lWf\nb6XaAwMDySf2hzO3/FfshRd3w5RXIDQJQpMnrPyS6rLuhz+oLlhYMv0sWfc9SO2a/+KbVPum3Ufp\nN3PfuRvUrlFzFlPtUxe9QLVfuXLl0qVLUs/g8nSPEYTTji3uRS6Xy+WWOqlAIJDJZB0cub6+nhpE\nIBBQf7E6na68vJw6LCIigs1mk9uNjY0SiWHVjcfjhYaGktsEQZSWllJdwsPDORwOud3c3NzS0kJu\nczic8PBw6rDS0lLq9oaGhlIOpBKJpLGxkdxmMplRUSYDYHl5uU6nI7eDgoKEQoMVUSaT1dfXk9s4\njtN/yisrKzUagzt0QECAv78/ua1UKmtqaqjD4uLicBwPCAhoaGioqalRKpVku7+/f0BAALmtVqur\nqqqoLjExMdQ0X1dXR31Nfn5+gYGB5LZGo6H/5kZGRrJYLOubyefzQ0JCyG29Xl9WVkZ1od//pqam\n1tZWcpvL5YaFhVGH3b1r+mUJCwvjcrnkdktLS3NzM7nNYrEiIyOpw8rKyvR6wxtGcHAwNWVKaZMu\ng8GgK3kVFRVarZbcDgw
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%%R -w 10 -h 6 -u in\n",
"future <- make_future_dataframe(m, periods = 1826)\n",
"future$cap <- 8.5\n",
"fcst <- predict(m, future)\n",
"plot(m, fcst);"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.13"
}
},
"nbformat": 4,
"nbformat_minor": 0
}