1941 lines
243 KiB
Text
1941 lines
243 KiB
Text
|
{
|
|||
|
"cells": [
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"# Tactical Demand Forecasting"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"The purpose of this notebook is to visualize the time series generation process, the STL decomposition of time series, and a couple of exemplary demand forecasts using different forecasting methods."
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 1,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"name": "stdout",
|
|||
|
"output_type": "stream",
|
|||
|
"text": [
|
|||
|
"\u001b[32murban-meal-delivery\u001b[0m, version \u001b[34m0.3.0\u001b[0m\n"
|
|||
|
]
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
"!umd --version"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"### Imports"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 2,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [],
|
|||
|
"source": [
|
|||
|
"import datetime as dt\n",
|
|||
|
"import matplotlib\n",
|
|||
|
"import matplotlib.pyplot as plt"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 3,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [],
|
|||
|
"source": [
|
|||
|
"from urban_meal_delivery import config, db\n",
|
|||
|
"from urban_meal_delivery.forecasts import methods, models, timify\n",
|
|||
|
"from urban_meal_delivery.forecasts.methods import decomposition"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 4,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [],
|
|||
|
"source": [
|
|||
|
"%load_ext lab_black"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 5,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [],
|
|||
|
"source": [
|
|||
|
"matplotlib.style.use(\"ggplot\")"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"### Settings"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"Choose `\"Bordeaux\"`, `\"Lyon\"`, or `\"Paris\"`."
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 6,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [],
|
|||
|
"source": [
|
|||
|
"city_name = \"Paris\""
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"Choose the `side_length` of the `grid` and the `time_step`. According to the corresponding research paper \"Real-time Demand Forecasting for an Urban Delivery Platform\", we mainly work with `side_length=1000` and `time_step=60`."
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 7,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"[707, 1000, 1414]"
|
|||
|
]
|
|||
|
},
|
|||
|
"execution_count": 7,
|
|||
|
"metadata": {},
|
|||
|
"output_type": "execute_result"
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
"config.GRID_SIDE_LENGTHS # possible values"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 8,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [],
|
|||
|
"source": [
|
|||
|
"side_length = 1000"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 9,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"[60]"
|
|||
|
]
|
|||
|
},
|
|||
|
"execution_count": 9,
|
|||
|
"metadata": {},
|
|||
|
"output_type": "execute_result"
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
"config.TIME_STEPS # possible values"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 10,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [],
|
|||
|
"source": [
|
|||
|
"time_step = 60"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"### Load the Data"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 11,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [],
|
|||
|
"source": [
|
|||
|
"city = db.session.query(db.City).filter_by(name=city_name).one()"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 12,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"<City(Paris)>"
|
|||
|
]
|
|||
|
},
|
|||
|
"execution_count": 12,
|
|||
|
"metadata": {},
|
|||
|
"output_type": "execute_result"
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
"city"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 13,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [],
|
|||
|
"source": [
|
|||
|
"grid = (\n",
|
|||
|
" db.session.query(db.Grid)\n",
|
|||
|
" .filter_by(city=city)\n",
|
|||
|
" .filter_by(side_length=side_length)\n",
|
|||
|
" .one()\n",
|
|||
|
")"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 14,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"<Grid: 1.0 sqr. km>"
|
|||
|
]
|
|||
|
},
|
|||
|
"execution_count": 14,
|
|||
|
"metadata": {},
|
|||
|
"output_type": "execute_result"
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
"grid"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"The `OrderHistory` class abstracts away the communcation with the database when it comes to generating time series out of the `db.Order` model's table."
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 15,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [],
|
|||
|
"source": [
|
|||
|
"orders = timify.OrderHistory(grid=grid, time_step=time_step)"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"## Pixel Visualization"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"Choose a `pixel` from the `grid` for which the order time series are generated."
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 16,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"111"
|
|||
|
]
|
|||
|
},
|
|||
|
"execution_count": 16,
|
|||
|
"metadata": {},
|
|||
|
"output_type": "execute_result"
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
"len(grid.pixels)"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 17,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [],
|
|||
|
"source": [
|
|||
|
"pixel = grid.pixels[15]"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 18,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/html": [
|
|||
|
"<div style=\"width:100%;\"><div style=\"position:relative;width:100%;height:0;padding-bottom:60%;\"><span style=\"color:#565656\">Make this Notebook Trusted to load map: File -> Trust Notebook</span><iframe src=\"about:blank\" style=\"position:absolute;width:100%;height:100%;left:0;top:0;border:none !important;\" data-html=%3C%21DOCTYPE%20html%3E%0A%3Chead%3E%20%20%20%20%0A%20%20%20%20%3Cmeta%20http-equiv%3D%22content-type%22%20content%3D%22text/html%3B%20charset%3DUTF-8%22%20/%3E%0A%20%20%20%20%0A%20%20%20%20%20%20%20%20%3Cscript%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20L_NO_TOUCH%20%3D%20false%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20L_DISABLE_3D%20%3D%20false%3B%0A%20%20%20%20%20%20%20%20%3C/script%3E%0A%20%20%20%20%0A%20%20%20%20%3Cstyle%3Ehtml%2C%20body%20%7Bwidth%3A%20100%25%3Bheight%3A%20100%25%3Bmargin%3A%200%3Bpadding%3A%200%3B%7D%3C/style%3E%0A%20%20%20%20%3Cstyle%3E%23map%20%7Bposition%3Aabsolute%3Btop%3A0%3Bbottom%3A0%3Bright%3A0%3Bleft%3A0%3B%7D%3C/style%3E%0A%20%20%20%20%3Cscript%20src%3D%22https%3A//cdn.jsdelivr.net/npm/leaflet%401.6.0/dist/leaflet.js%22%3E%3C/script%3E%0A%20%20%20%20%3Cscript%20src%3D%22https%3A//code.jquery.com/jquery-1.12.4.min.js%22%3E%3C/script%3E%0A%20%20%20%20%3Cscript%20src%3D%22https%3A//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js%22%3E%3C/script%3E%0A%20%20%20%20%3Cscript%20src%3D%22https%3A//cdnjs.cloudflare.com/ajax/libs/Leaflet.awesome-markers/2.0.2/leaflet.awesome-markers.js%22%3E%3C/script%3E%0A%20%20%20%20%3Clink%20rel%3D%22stylesheet%22%20href%3D%22https%3A//cdn.jsdelivr.net/npm/leaflet%401.6.0/dist/leaflet.css%22/%3E%0A%20%20%20%20%3Clink%20rel%3D%22stylesheet%22%20href%3D%22https%3A//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css%22/%3E%0A%20%20%20%20%3Clink%20rel%3D%22stylesheet%22%20href%3D%22https%3A//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css%22/%3E%0A%20%20%20%20%3Clink%20rel%3D%22stylesheet%22%20href%3D%22https%3A//maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css%22/%3E%0A%20%20%20%20%3Clink%20rel%3D%22stylesheet%22%20href%3D%22https%3A//cdnjs.cloudflare.com/ajax/libs/Leaflet.awesome-markers/2.0.2/leaflet.awesome-markers.css%22/%3E%0A%20%20%20%20%3Clink%20rel%3D%22stylesheet%22%20href%3D%22https%3A//cdn.jsdelivr.net/gh/python-visualization/folium/folium/templates/leaflet.awesome.rotate.min.css%22/%3E%0A%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cmeta%20name%3D%22viewport%22%20content%3D%22width%3Ddevice-width%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20initial-scale%3D1.0%2C%20maximum-scale%3D1.0%2C%20user-scalable%3Dno%22%20/%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cstyle%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23map_2184c8f2531849d0a1da56e14c10408f%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20position%3A%20relative%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20width%3A%20100.0%25%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20height%3A%20100.0%25%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20left%3A%200.0%25%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20top%3A%200.0%25%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C/style%3E%0A%20%20%20%20%20%20%20%20%0A%3C/head%3E%0A%3Cbody%3E%20%20%20%20%0A%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class%3D%22folium-map%22%20id%3D%22map_2184c8f2531849d0a1da56e14c10408f%22%20%3E%3C/div%3E%0A%20%20%20%20%20%20%20%20%0A%3C/body%3E%0A%3Cscript%3E%20%20%20%20%0A%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20var%20map_2184c8f2531849d0a1da56e14c10408f%20%3D%20L.map%28%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22map_2184c8f2531849d0a1da56e14c10408f%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20center%3A%20%5B48.856614%2C%202.3522219%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20crs%3A%20L.CRS.EPSG3857%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%
|
|||
|
],
|
|||
|
"text/plain": [
|
|||
|
"<folium.folium.Map at 0x7f22c763fee0>"
|
|||
|
]
|
|||
|
},
|
|||
|
"execution_count": 18,
|
|||
|
"metadata": {},
|
|||
|
"output_type": "execute_result"
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
"pixel.clear_map().draw(order_counts=True)"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 19,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"24"
|
|||
|
]
|
|||
|
},
|
|||
|
"execution_count": 19,
|
|||
|
"metadata": {},
|
|||
|
"output_type": "execute_result"
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
"len(pixel.restaurants)"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 20,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"datetime.datetime(2016, 3, 8, 12, 0)"
|
|||
|
]
|
|||
|
},
|
|||
|
"execution_count": 20,
|
|||
|
"metadata": {},
|
|||
|
"output_type": "execute_result"
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
"orders.first_order_at(pixel.id)"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 21,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"datetime.datetime(2017, 1, 31, 22, 0)"
|
|||
|
]
|
|||
|
},
|
|||
|
"execution_count": 21,
|
|||
|
"metadata": {},
|
|||
|
"output_type": "execute_result"
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
"orders.last_order_at(pixel.id)"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"## Time Series Generation"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"Choose the `train_horizon` between `3` and `8` weeks (= length of the historic order time series used to train a prediction model) and the day for which the prediction is to be made (= `predict_at`)."
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 22,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [],
|
|||
|
"source": [
|
|||
|
"train_horizon = 8"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 23,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [],
|
|||
|
"source": [
|
|||
|
"predict_at = dt.datetime(2016, 9, 15, 20)"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"There are three kinds of time series used for tactical forecasting: \"horizontal\", \"vertical\", and \"real-time\"."
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 24,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"start_at\n",
|
|||
|
"2016-09-10 20:00:00 10\n",
|
|||
|
"2016-09-11 20:00:00 21\n",
|
|||
|
"2016-09-12 20:00:00 6\n",
|
|||
|
"2016-09-13 20:00:00 10\n",
|
|||
|
"2016-09-14 20:00:00 12\n",
|
|||
|
"Name: n_orders, dtype: int64"
|
|||
|
]
|
|||
|
},
|
|||
|
"execution_count": 24,
|
|||
|
"metadata": {},
|
|||
|
"output_type": "execute_result"
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
"orders.make_horizontal_ts(pixel.id, predict_at, train_horizon)[0].tail(5)"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 25,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"start_at\n",
|
|||
|
"2016-09-14 18:00:00 1\n",
|
|||
|
"2016-09-14 19:00:00 9\n",
|
|||
|
"2016-09-14 20:00:00 12\n",
|
|||
|
"2016-09-14 21:00:00 11\n",
|
|||
|
"2016-09-14 22:00:00 0\n",
|
|||
|
"Name: n_orders, dtype: int64"
|
|||
|
]
|
|||
|
},
|
|||
|
"execution_count": 25,
|
|||
|
"metadata": {},
|
|||
|
"output_type": "execute_result"
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
"orders.make_vertical_ts(pixel.id, predict_at.date(), train_horizon)[0].tail(5)"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 26,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"start_at\n",
|
|||
|
"2016-09-15 15:00:00 0\n",
|
|||
|
"2016-09-15 16:00:00 0\n",
|
|||
|
"2016-09-15 17:00:00 0\n",
|
|||
|
"2016-09-15 18:00:00 0\n",
|
|||
|
"2016-09-15 19:00:00 7\n",
|
|||
|
"Name: n_orders, dtype: int64"
|
|||
|
]
|
|||
|
},
|
|||
|
"execution_count": 26,
|
|||
|
"metadata": {},
|
|||
|
"output_type": "execute_result"
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
"orders.make_realtime_ts(pixel.id, predict_at, train_horizon)[0].tail(5)"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"## Time Series Visualization"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"Generate a vertical `history` time series used to predict the `actuals`. The latter are the order counts that are predicted by the forecasting model below."
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 27,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [],
|
|||
|
"source": [
|
|||
|
"history, frequency, actuals = orders.make_vertical_ts(\n",
|
|||
|
" pixel.id, predict_at.date(), train_horizon\n",
|
|||
|
")"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 28,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"<AxesSubplot:xlabel='start_at'>"
|
|||
|
]
|
|||
|
},
|
|||
|
"execution_count": 28,
|
|||
|
"metadata": {},
|
|||
|
"output_type": "execute_result"
|
|||
|
},
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"image/png": "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
|
|||
|
"text/plain": [
|
|||
|
"<Figure size 432x288 with 1 Axes>"
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
"history.plot(style=\"black\")\n",
|
|||
|
"actuals.plot(style=\"green\")"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 29,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"84"
|
|||
|
]
|
|||
|
},
|
|||
|
"execution_count": 29,
|
|||
|
"metadata": {},
|
|||
|
"output_type": "execute_result"
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
"frequency"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 30,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"start_at\n",
|
|||
|
"2016-07-21 11:00:00 0\n",
|
|||
|
"2016-07-21 12:00:00 0\n",
|
|||
|
"2016-07-21 13:00:00 0\n",
|
|||
|
"2016-07-21 14:00:00 1\n",
|
|||
|
"2016-07-21 15:00:00 0\n",
|
|||
|
" ..\n",
|
|||
|
"2016-09-14 18:00:00 1\n",
|
|||
|
"2016-09-14 19:00:00 9\n",
|
|||
|
"2016-09-14 20:00:00 12\n",
|
|||
|
"2016-09-14 21:00:00 11\n",
|
|||
|
"2016-09-14 22:00:00 0\n",
|
|||
|
"Name: n_orders, Length: 672, dtype: int64"
|
|||
|
]
|
|||
|
},
|
|||
|
"execution_count": 30,
|
|||
|
"metadata": {},
|
|||
|
"output_type": "execute_result"
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
"history"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 31,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"start_at\n",
|
|||
|
"2016-09-15 11:00:00 0\n",
|
|||
|
"2016-09-15 12:00:00 1\n",
|
|||
|
"2016-09-15 13:00:00 1\n",
|
|||
|
"2016-09-15 14:00:00 0\n",
|
|||
|
"2016-09-15 15:00:00 0\n",
|
|||
|
"2016-09-15 16:00:00 0\n",
|
|||
|
"2016-09-15 17:00:00 0\n",
|
|||
|
"2016-09-15 18:00:00 0\n",
|
|||
|
"2016-09-15 19:00:00 7\n",
|
|||
|
"2016-09-15 20:00:00 16\n",
|
|||
|
"2016-09-15 21:00:00 7\n",
|
|||
|
"2016-09-15 22:00:00 1\n",
|
|||
|
"Name: n_orders, dtype: int64"
|
|||
|
]
|
|||
|
},
|
|||
|
"execution_count": 31,
|
|||
|
"metadata": {},
|
|||
|
"output_type": "execute_result"
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
"actuals"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"## STL Decomposition"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"For vertical and real-time time series, a decomposition needs to be made. Due to the high `frequency` (i.e., > 12), we use the STL method, which, among others, has a `ns` parameter that must be tuned by the forecaster. To skip the tuning of `ns`, we choose the so-called \"periodic\" setting and make `ns` a big number."
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 32,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [],
|
|||
|
"source": [
|
|||
|
"ns = 999_999_999"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 33,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [],
|
|||
|
"source": [
|
|||
|
"history_decomposed = decomposition.stl(history, frequency=frequency, ns=ns)"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 34,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/html": [
|
|||
|
"<div>\n",
|
|||
|
"<style scoped>\n",
|
|||
|
" .dataframe tbody tr th:only-of-type {\n",
|
|||
|
" vertical-align: middle;\n",
|
|||
|
" }\n",
|
|||
|
"\n",
|
|||
|
" .dataframe tbody tr th {\n",
|
|||
|
" vertical-align: top;\n",
|
|||
|
" }\n",
|
|||
|
"\n",
|
|||
|
" .dataframe thead th {\n",
|
|||
|
" text-align: right;\n",
|
|||
|
" }\n",
|
|||
|
"</style>\n",
|
|||
|
"<table border=\"1\" class=\"dataframe\">\n",
|
|||
|
" <thead>\n",
|
|||
|
" <tr style=\"text-align: right;\">\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th>seasonal</th>\n",
|
|||
|
" <th>trend</th>\n",
|
|||
|
" <th>residual</th>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>start_at</th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" </tr>\n",
|
|||
|
" </thead>\n",
|
|||
|
" <tbody>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-07-21 11:00:00</th>\n",
|
|||
|
" <td>-2.47545</td>\n",
|
|||
|
" <td>1.92453</td>\n",
|
|||
|
" <td>0.55092</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-07-21 12:00:00</th>\n",
|
|||
|
" <td>-0.35394</td>\n",
|
|||
|
" <td>1.93356</td>\n",
|
|||
|
" <td>-1.57962</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-07-21 13:00:00</th>\n",
|
|||
|
" <td>-0.60663</td>\n",
|
|||
|
" <td>1.94259</td>\n",
|
|||
|
" <td>-1.33596</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-07-21 14:00:00</th>\n",
|
|||
|
" <td>-1.98459</td>\n",
|
|||
|
" <td>1.95162</td>\n",
|
|||
|
" <td>1.03297</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-07-21 15:00:00</th>\n",
|
|||
|
" <td>-2.48642</td>\n",
|
|||
|
" <td>1.96065</td>\n",
|
|||
|
" <td>0.52576</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>...</th>\n",
|
|||
|
" <td>...</td>\n",
|
|||
|
" <td>...</td>\n",
|
|||
|
" <td>...</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-14 18:00:00</th>\n",
|
|||
|
" <td>-2.09759</td>\n",
|
|||
|
" <td>3.06895</td>\n",
|
|||
|
" <td>0.02864</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-14 19:00:00</th>\n",
|
|||
|
" <td>4.65025</td>\n",
|
|||
|
" <td>3.06833</td>\n",
|
|||
|
" <td>1.28142</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-14 20:00:00</th>\n",
|
|||
|
" <td>7.14891</td>\n",
|
|||
|
" <td>3.06771</td>\n",
|
|||
|
" <td>1.78339</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-14 21:00:00</th>\n",
|
|||
|
" <td>6.02162</td>\n",
|
|||
|
" <td>3.06709</td>\n",
|
|||
|
" <td>1.91129</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-14 22:00:00</th>\n",
|
|||
|
" <td>-1.48066</td>\n",
|
|||
|
" <td>3.06647</td>\n",
|
|||
|
" <td>-1.58581</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" </tbody>\n",
|
|||
|
"</table>\n",
|
|||
|
"<p>672 rows × 3 columns</p>\n",
|
|||
|
"</div>"
|
|||
|
],
|
|||
|
"text/plain": [
|
|||
|
" seasonal trend residual\n",
|
|||
|
"start_at \n",
|
|||
|
"2016-07-21 11:00:00 -2.47545 1.92453 0.55092\n",
|
|||
|
"2016-07-21 12:00:00 -0.35394 1.93356 -1.57962\n",
|
|||
|
"2016-07-21 13:00:00 -0.60663 1.94259 -1.33596\n",
|
|||
|
"2016-07-21 14:00:00 -1.98459 1.95162 1.03297\n",
|
|||
|
"2016-07-21 15:00:00 -2.48642 1.96065 0.52576\n",
|
|||
|
"... ... ... ...\n",
|
|||
|
"2016-09-14 18:00:00 -2.09759 3.06895 0.02864\n",
|
|||
|
"2016-09-14 19:00:00 4.65025 3.06833 1.28142\n",
|
|||
|
"2016-09-14 20:00:00 7.14891 3.06771 1.78339\n",
|
|||
|
"2016-09-14 21:00:00 6.02162 3.06709 1.91129\n",
|
|||
|
"2016-09-14 22:00:00 -1.48066 3.06647 -1.58581\n",
|
|||
|
"\n",
|
|||
|
"[672 rows x 3 columns]"
|
|||
|
]
|
|||
|
},
|
|||
|
"execution_count": 34,
|
|||
|
"metadata": {},
|
|||
|
"output_type": "execute_result"
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
"history_decomposed"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 35,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"(1.1904761900081797e-07, 0.0040629613095238245)"
|
|||
|
]
|
|||
|
},
|
|||
|
"execution_count": 35,
|
|||
|
"metadata": {},
|
|||
|
"output_type": "execute_result"
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
"history_decomposed[\"seasonal\"].mean(), history_decomposed[\"residual\"].mean()"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 36,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"<AxesSubplot:xlabel='start_at'>"
|
|||
|
]
|
|||
|
},
|
|||
|
"execution_count": 36,
|
|||
|
"metadata": {},
|
|||
|
"output_type": "execute_result"
|
|||
|
},
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"image/png": "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
|
|||
|
"text/plain": [
|
|||
|
"<Figure size 432x288 with 1 Axes>"
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
"history_decomposed[\"seasonal\"].plot(legend=\"seasonal\", style=\"orange\")\n",
|
|||
|
"history_decomposed[\"trend\"].plot(legend=\"trend\", style=\"blue\")\n",
|
|||
|
"history_decomposed[\"residual\"].plot(legend=\"residual\", style=\"purple\")"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"## Prediction Models"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"A heuristic derived from the findings of the first research paper determines which forecasting model is used to make the predition. The heuristic is a function of the average daily demand in `history` and `train_horizon` (currently, only `train_horizon=8` is implemented)."
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 37,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"30.5"
|
|||
|
]
|
|||
|
},
|
|||
|
"execution_count": 37,
|
|||
|
"metadata": {},
|
|||
|
"output_type": "execute_result"
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
"orders.avg_daily_demand(pixel.id, predict_at.date(), train_horizon)"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 38,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [],
|
|||
|
"source": [
|
|||
|
"best_model = orders.choose_tactical_model(pixel.id, predict_at.date(), train_horizon)"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 39,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"'hets'"
|
|||
|
]
|
|||
|
},
|
|||
|
"execution_count": 39,
|
|||
|
"metadata": {},
|
|||
|
"output_type": "execute_result"
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
"best_model.name"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"#### *hets* Model"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"The *hets* model applies the ETS method on a horizontal time series."
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 40,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/html": [
|
|||
|
"<div>\n",
|
|||
|
"<style scoped>\n",
|
|||
|
" .dataframe tbody tr th:only-of-type {\n",
|
|||
|
" vertical-align: middle;\n",
|
|||
|
" }\n",
|
|||
|
"\n",
|
|||
|
" .dataframe tbody tr th {\n",
|
|||
|
" vertical-align: top;\n",
|
|||
|
" }\n",
|
|||
|
"\n",
|
|||
|
" .dataframe thead th {\n",
|
|||
|
" text-align: right;\n",
|
|||
|
" }\n",
|
|||
|
"</style>\n",
|
|||
|
"<table border=\"1\" class=\"dataframe\">\n",
|
|||
|
" <thead>\n",
|
|||
|
" <tr style=\"text-align: right;\">\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th>actual</th>\n",
|
|||
|
" <th>prediction</th>\n",
|
|||
|
" <th>low80</th>\n",
|
|||
|
" <th>high80</th>\n",
|
|||
|
" <th>low95</th>\n",
|
|||
|
" <th>high95</th>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>start_at</th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" </tr>\n",
|
|||
|
" </thead>\n",
|
|||
|
" <tbody>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 20:00:00</th>\n",
|
|||
|
" <td>16</td>\n",
|
|||
|
" <td>11.52854</td>\n",
|
|||
|
" <td>5.53107</td>\n",
|
|||
|
" <td>17.52601</td>\n",
|
|||
|
" <td>2.3562</td>\n",
|
|||
|
" <td>20.70088</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" </tbody>\n",
|
|||
|
"</table>\n",
|
|||
|
"</div>"
|
|||
|
],
|
|||
|
"text/plain": [
|
|||
|
" actual prediction low80 high80 low95 high95\n",
|
|||
|
"start_at \n",
|
|||
|
"2016-09-15 20:00:00 16 11.52854 5.53107 17.52601 2.3562 20.70088"
|
|||
|
]
|
|||
|
},
|
|||
|
"execution_count": 40,
|
|||
|
"metadata": {},
|
|||
|
"output_type": "execute_result"
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
"best_model.predict(pixel, predict_at, train_horizon)"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"#### *pnaive* Model"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"As a \"naive\" way, we could simply extrapolate the seasonal component of the decomposed vertical `history` time series linearly and add to it the last observation of the trend component, ignoring the residuals."
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 41,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/html": [
|
|||
|
"<div>\n",
|
|||
|
"<style scoped>\n",
|
|||
|
" .dataframe tbody tr th:only-of-type {\n",
|
|||
|
" vertical-align: middle;\n",
|
|||
|
" }\n",
|
|||
|
"\n",
|
|||
|
" .dataframe tbody tr th {\n",
|
|||
|
" vertical-align: top;\n",
|
|||
|
" }\n",
|
|||
|
"\n",
|
|||
|
" .dataframe thead th {\n",
|
|||
|
" text-align: right;\n",
|
|||
|
" }\n",
|
|||
|
"</style>\n",
|
|||
|
"<table border=\"1\" class=\"dataframe\">\n",
|
|||
|
" <thead>\n",
|
|||
|
" <tr style=\"text-align: right;\">\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th>prediction</th>\n",
|
|||
|
" <th>low80</th>\n",
|
|||
|
" <th>high80</th>\n",
|
|||
|
" <th>low95</th>\n",
|
|||
|
" <th>high95</th>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>start_at</th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" </tr>\n",
|
|||
|
" </thead>\n",
|
|||
|
" <tbody>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 11:00:00</th>\n",
|
|||
|
" <td>-2.47545</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 12:00:00</th>\n",
|
|||
|
" <td>-0.35394</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 13:00:00</th>\n",
|
|||
|
" <td>-0.60663</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 14:00:00</th>\n",
|
|||
|
" <td>-1.98459</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 15:00:00</th>\n",
|
|||
|
" <td>-2.48642</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 16:00:00</th>\n",
|
|||
|
" <td>-2.48824</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 17:00:00</th>\n",
|
|||
|
" <td>-2.49007</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 18:00:00</th>\n",
|
|||
|
" <td>-1.99189</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 19:00:00</th>\n",
|
|||
|
" <td>2.38152</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 20:00:00</th>\n",
|
|||
|
" <td>8.25440</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 21:00:00</th>\n",
|
|||
|
" <td>4.75164</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 22:00:00</th>\n",
|
|||
|
" <td>-1.00155</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" </tbody>\n",
|
|||
|
"</table>\n",
|
|||
|
"</div>"
|
|||
|
],
|
|||
|
"text/plain": [
|
|||
|
" prediction low80 high80 low95 high95\n",
|
|||
|
"start_at \n",
|
|||
|
"2016-09-15 11:00:00 -2.47545 NaN NaN NaN NaN\n",
|
|||
|
"2016-09-15 12:00:00 -0.35394 NaN NaN NaN NaN\n",
|
|||
|
"2016-09-15 13:00:00 -0.60663 NaN NaN NaN NaN\n",
|
|||
|
"2016-09-15 14:00:00 -1.98459 NaN NaN NaN NaN\n",
|
|||
|
"2016-09-15 15:00:00 -2.48642 NaN NaN NaN NaN\n",
|
|||
|
"2016-09-15 16:00:00 -2.48824 NaN NaN NaN NaN\n",
|
|||
|
"2016-09-15 17:00:00 -2.49007 NaN NaN NaN NaN\n",
|
|||
|
"2016-09-15 18:00:00 -1.99189 NaN NaN NaN NaN\n",
|
|||
|
"2016-09-15 19:00:00 2.38152 NaN NaN NaN NaN\n",
|
|||
|
"2016-09-15 20:00:00 8.25440 NaN NaN NaN NaN\n",
|
|||
|
"2016-09-15 21:00:00 4.75164 NaN NaN NaN NaN\n",
|
|||
|
"2016-09-15 22:00:00 -1.00155 NaN NaN NaN NaN"
|
|||
|
]
|
|||
|
},
|
|||
|
"execution_count": 41,
|
|||
|
"metadata": {},
|
|||
|
"output_type": "execute_result"
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
"seasonal_predictions = methods.extrapolate_season.predict(\n",
|
|||
|
" history_decomposed[\"seasonal\"], actuals.index, frequency=frequency\n",
|
|||
|
")\n",
|
|||
|
"\n",
|
|||
|
"seasonal_predictions"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 42,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"start_at\n",
|
|||
|
"2016-09-14 13:00:00 3.07100\n",
|
|||
|
"2016-09-14 14:00:00 3.07143\n",
|
|||
|
"2016-09-14 15:00:00 3.07081\n",
|
|||
|
"2016-09-14 16:00:00 3.07019\n",
|
|||
|
"2016-09-14 17:00:00 3.06957\n",
|
|||
|
"2016-09-14 18:00:00 3.06895\n",
|
|||
|
"2016-09-14 19:00:00 3.06833\n",
|
|||
|
"2016-09-14 20:00:00 3.06771\n",
|
|||
|
"2016-09-14 21:00:00 3.06709\n",
|
|||
|
"2016-09-14 22:00:00 3.06647\n",
|
|||
|
"Name: trend, dtype: float64"
|
|||
|
]
|
|||
|
},
|
|||
|
"execution_count": 42,
|
|||
|
"metadata": {},
|
|||
|
"output_type": "execute_result"
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
"history_decomposed[\"trend\"].tail(10)"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 43,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/html": [
|
|||
|
"<div>\n",
|
|||
|
"<style scoped>\n",
|
|||
|
" .dataframe tbody tr th:only-of-type {\n",
|
|||
|
" vertical-align: middle;\n",
|
|||
|
" }\n",
|
|||
|
"\n",
|
|||
|
" .dataframe tbody tr th {\n",
|
|||
|
" vertical-align: top;\n",
|
|||
|
" }\n",
|
|||
|
"\n",
|
|||
|
" .dataframe thead th {\n",
|
|||
|
" text-align: right;\n",
|
|||
|
" }\n",
|
|||
|
"</style>\n",
|
|||
|
"<table border=\"1\" class=\"dataframe\">\n",
|
|||
|
" <thead>\n",
|
|||
|
" <tr style=\"text-align: right;\">\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th>prediction</th>\n",
|
|||
|
" <th>low80</th>\n",
|
|||
|
" <th>high80</th>\n",
|
|||
|
" <th>low95</th>\n",
|
|||
|
" <th>high95</th>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>start_at</th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" </tr>\n",
|
|||
|
" </thead>\n",
|
|||
|
" <tbody>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 11:00:00</th>\n",
|
|||
|
" <td>0.59102</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 12:00:00</th>\n",
|
|||
|
" <td>2.71253</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 13:00:00</th>\n",
|
|||
|
" <td>2.45984</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 14:00:00</th>\n",
|
|||
|
" <td>1.08188</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 15:00:00</th>\n",
|
|||
|
" <td>0.58005</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 16:00:00</th>\n",
|
|||
|
" <td>0.57823</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 17:00:00</th>\n",
|
|||
|
" <td>0.57640</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 18:00:00</th>\n",
|
|||
|
" <td>1.07458</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 19:00:00</th>\n",
|
|||
|
" <td>5.44799</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 20:00:00</th>\n",
|
|||
|
" <td>11.32087</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 21:00:00</th>\n",
|
|||
|
" <td>7.81811</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 22:00:00</th>\n",
|
|||
|
" <td>2.06492</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" </tbody>\n",
|
|||
|
"</table>\n",
|
|||
|
"</div>"
|
|||
|
],
|
|||
|
"text/plain": [
|
|||
|
" prediction low80 high80 low95 high95\n",
|
|||
|
"start_at \n",
|
|||
|
"2016-09-15 11:00:00 0.59102 NaN NaN NaN NaN\n",
|
|||
|
"2016-09-15 12:00:00 2.71253 NaN NaN NaN NaN\n",
|
|||
|
"2016-09-15 13:00:00 2.45984 NaN NaN NaN NaN\n",
|
|||
|
"2016-09-15 14:00:00 1.08188 NaN NaN NaN NaN\n",
|
|||
|
"2016-09-15 15:00:00 0.58005 NaN NaN NaN NaN\n",
|
|||
|
"2016-09-15 16:00:00 0.57823 NaN NaN NaN NaN\n",
|
|||
|
"2016-09-15 17:00:00 0.57640 NaN NaN NaN NaN\n",
|
|||
|
"2016-09-15 18:00:00 1.07458 NaN NaN NaN NaN\n",
|
|||
|
"2016-09-15 19:00:00 5.44799 NaN NaN NaN NaN\n",
|
|||
|
"2016-09-15 20:00:00 11.32087 NaN NaN NaN NaN\n",
|
|||
|
"2016-09-15 21:00:00 7.81811 NaN NaN NaN NaN\n",
|
|||
|
"2016-09-15 22:00:00 2.06492 NaN NaN NaN NaN"
|
|||
|
]
|
|||
|
},
|
|||
|
"execution_count": 43,
|
|||
|
"metadata": {},
|
|||
|
"output_type": "execute_result"
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
"last_trend = history_decomposed[\"trend\"].iloc[-1]\n",
|
|||
|
"pnaive = seasonal_predictions + last_trend\n",
|
|||
|
"\n",
|
|||
|
"pnaive"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 44,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"<AxesSubplot:xlabel='start_at'>"
|
|||
|
]
|
|||
|
},
|
|||
|
"execution_count": 44,
|
|||
|
"metadata": {},
|
|||
|
"output_type": "execute_result"
|
|||
|
},
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"image/png": "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
|
|||
|
"text/plain": [
|
|||
|
"<Figure size 432x288 with 1 Axes>"
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
"history_decomposed[\"seasonal\"].plot(legend=\"seasonal\", style=\"orange\")\n",
|
|||
|
"history_decomposed[\"trend\"].plot(legend=\"trend\", style=\"blue\")\n",
|
|||
|
"seasonal_predictions[\"prediction\"].plot(legend=\"prediction\", style=\"red\")"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"#### *varima* Model"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"The *varima* model applies the ARIMA method on a vertical time series. Any prediction method applied on a vertical time series allows us to predict *all* time steps of the day to be predicted at once and, more importantly, before the day actually begins."
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 45,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [],
|
|||
|
"source": [
|
|||
|
"varima = models.VerticalARIMAModel(orders)"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 46,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/html": [
|
|||
|
"<div>\n",
|
|||
|
"<style scoped>\n",
|
|||
|
" .dataframe tbody tr th:only-of-type {\n",
|
|||
|
" vertical-align: middle;\n",
|
|||
|
" }\n",
|
|||
|
"\n",
|
|||
|
" .dataframe tbody tr th {\n",
|
|||
|
" vertical-align: top;\n",
|
|||
|
" }\n",
|
|||
|
"\n",
|
|||
|
" .dataframe thead th {\n",
|
|||
|
" text-align: right;\n",
|
|||
|
" }\n",
|
|||
|
"</style>\n",
|
|||
|
"<table border=\"1\" class=\"dataframe\">\n",
|
|||
|
" <thead>\n",
|
|||
|
" <tr style=\"text-align: right;\">\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th>actual</th>\n",
|
|||
|
" <th>prediction</th>\n",
|
|||
|
" <th>low80</th>\n",
|
|||
|
" <th>high80</th>\n",
|
|||
|
" <th>low95</th>\n",
|
|||
|
" <th>high95</th>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>start_at</th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" </tr>\n",
|
|||
|
" </thead>\n",
|
|||
|
" <tbody>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 11:00:00</th>\n",
|
|||
|
" <td>0</td>\n",
|
|||
|
" <td>0.38215</td>\n",
|
|||
|
" <td>-1.99851</td>\n",
|
|||
|
" <td>2.76281</td>\n",
|
|||
|
" <td>-3.25875</td>\n",
|
|||
|
" <td>4.02306</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 12:00:00</th>\n",
|
|||
|
" <td>1</td>\n",
|
|||
|
" <td>2.54113</td>\n",
|
|||
|
" <td>0.12154</td>\n",
|
|||
|
" <td>4.96072</td>\n",
|
|||
|
" <td>-1.15932</td>\n",
|
|||
|
" <td>6.24157</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 13:00:00</th>\n",
|
|||
|
" <td>1</td>\n",
|
|||
|
" <td>2.40134</td>\n",
|
|||
|
" <td>-0.03314</td>\n",
|
|||
|
" <td>4.83581</td>\n",
|
|||
|
" <td>-1.32187</td>\n",
|
|||
|
" <td>6.12455</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 14:00:00</th>\n",
|
|||
|
" <td>0</td>\n",
|
|||
|
" <td>1.02338</td>\n",
|
|||
|
" <td>-1.41459</td>\n",
|
|||
|
" <td>3.46135</td>\n",
|
|||
|
" <td>-2.70518</td>\n",
|
|||
|
" <td>4.75193</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 15:00:00</th>\n",
|
|||
|
" <td>0</td>\n",
|
|||
|
" <td>0.52155</td>\n",
|
|||
|
" <td>-1.91991</td>\n",
|
|||
|
" <td>2.96300</td>\n",
|
|||
|
" <td>-3.21234</td>\n",
|
|||
|
" <td>4.25543</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 16:00:00</th>\n",
|
|||
|
" <td>0</td>\n",
|
|||
|
" <td>0.51973</td>\n",
|
|||
|
" <td>-1.92522</td>\n",
|
|||
|
" <td>2.96467</td>\n",
|
|||
|
" <td>-3.21949</td>\n",
|
|||
|
" <td>4.25894</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 17:00:00</th>\n",
|
|||
|
" <td>0</td>\n",
|
|||
|
" <td>0.51790</td>\n",
|
|||
|
" <td>-1.93052</td>\n",
|
|||
|
" <td>2.96632</td>\n",
|
|||
|
" <td>-3.22664</td>\n",
|
|||
|
" <td>4.26243</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 18:00:00</th>\n",
|
|||
|
" <td>0</td>\n",
|
|||
|
" <td>1.01607</td>\n",
|
|||
|
" <td>-1.43583</td>\n",
|
|||
|
" <td>3.46796</td>\n",
|
|||
|
" <td>-2.73378</td>\n",
|
|||
|
" <td>4.76591</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 19:00:00</th>\n",
|
|||
|
" <td>7</td>\n",
|
|||
|
" <td>5.38949</td>\n",
|
|||
|
" <td>2.93412</td>\n",
|
|||
|
" <td>7.84485</td>\n",
|
|||
|
" <td>1.63433</td>\n",
|
|||
|
" <td>9.14464</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 20:00:00</th>\n",
|
|||
|
" <td>16</td>\n",
|
|||
|
" <td>11.26237</td>\n",
|
|||
|
" <td>8.80354</td>\n",
|
|||
|
" <td>13.72119</td>\n",
|
|||
|
" <td>7.50192</td>\n",
|
|||
|
" <td>15.02281</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 21:00:00</th>\n",
|
|||
|
" <td>7</td>\n",
|
|||
|
" <td>7.75961</td>\n",
|
|||
|
" <td>5.29732</td>\n",
|
|||
|
" <td>10.22189</td>\n",
|
|||
|
" <td>3.99387</td>\n",
|
|||
|
" <td>11.52534</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 22:00:00</th>\n",
|
|||
|
" <td>1</td>\n",
|
|||
|
" <td>2.00641</td>\n",
|
|||
|
" <td>-0.45933</td>\n",
|
|||
|
" <td>4.47214</td>\n",
|
|||
|
" <td>-1.76462</td>\n",
|
|||
|
" <td>5.77743</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" </tbody>\n",
|
|||
|
"</table>\n",
|
|||
|
"</div>"
|
|||
|
],
|
|||
|
"text/plain": [
|
|||
|
" actual prediction low80 high80 low95 high95\n",
|
|||
|
"start_at \n",
|
|||
|
"2016-09-15 11:00:00 0 0.38215 -1.99851 2.76281 -3.25875 4.02306\n",
|
|||
|
"2016-09-15 12:00:00 1 2.54113 0.12154 4.96072 -1.15932 6.24157\n",
|
|||
|
"2016-09-15 13:00:00 1 2.40134 -0.03314 4.83581 -1.32187 6.12455\n",
|
|||
|
"2016-09-15 14:00:00 0 1.02338 -1.41459 3.46135 -2.70518 4.75193\n",
|
|||
|
"2016-09-15 15:00:00 0 0.52155 -1.91991 2.96300 -3.21234 4.25543\n",
|
|||
|
"2016-09-15 16:00:00 0 0.51973 -1.92522 2.96467 -3.21949 4.25894\n",
|
|||
|
"2016-09-15 17:00:00 0 0.51790 -1.93052 2.96632 -3.22664 4.26243\n",
|
|||
|
"2016-09-15 18:00:00 0 1.01607 -1.43583 3.46796 -2.73378 4.76591\n",
|
|||
|
"2016-09-15 19:00:00 7 5.38949 2.93412 7.84485 1.63433 9.14464\n",
|
|||
|
"2016-09-15 20:00:00 16 11.26237 8.80354 13.72119 7.50192 15.02281\n",
|
|||
|
"2016-09-15 21:00:00 7 7.75961 5.29732 10.22189 3.99387 11.52534\n",
|
|||
|
"2016-09-15 22:00:00 1 2.00641 -0.45933 4.47214 -1.76462 5.77743"
|
|||
|
]
|
|||
|
},
|
|||
|
"execution_count": 46,
|
|||
|
"metadata": {},
|
|||
|
"output_type": "execute_result"
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
"varima.predict(pixel, predict_at, 8)"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"#### *rtarima* Model"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"The *rtarima* model applies the ARIMA method on a real-time time series. Real-time models are *re-trained* after each time step and predict only one observation into the future."
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 47,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [],
|
|||
|
"source": [
|
|||
|
"rtarima = models.RealtimeARIMAModel(orders)"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 48,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/html": [
|
|||
|
"<div>\n",
|
|||
|
"<style scoped>\n",
|
|||
|
" .dataframe tbody tr th:only-of-type {\n",
|
|||
|
" vertical-align: middle;\n",
|
|||
|
" }\n",
|
|||
|
"\n",
|
|||
|
" .dataframe tbody tr th {\n",
|
|||
|
" vertical-align: top;\n",
|
|||
|
" }\n",
|
|||
|
"\n",
|
|||
|
" .dataframe thead th {\n",
|
|||
|
" text-align: right;\n",
|
|||
|
" }\n",
|
|||
|
"</style>\n",
|
|||
|
"<table border=\"1\" class=\"dataframe\">\n",
|
|||
|
" <thead>\n",
|
|||
|
" <tr style=\"text-align: right;\">\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th>actual</th>\n",
|
|||
|
" <th>prediction</th>\n",
|
|||
|
" <th>low80</th>\n",
|
|||
|
" <th>high80</th>\n",
|
|||
|
" <th>low95</th>\n",
|
|||
|
" <th>high95</th>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>start_at</th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" </tr>\n",
|
|||
|
" </thead>\n",
|
|||
|
" <tbody>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 20:00:00</th>\n",
|
|||
|
" <td>16</td>\n",
|
|||
|
" <td>11.26066</td>\n",
|
|||
|
" <td>8.89482</td>\n",
|
|||
|
" <td>13.62651</td>\n",
|
|||
|
" <td>7.64242</td>\n",
|
|||
|
" <td>14.87891</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" </tbody>\n",
|
|||
|
"</table>\n",
|
|||
|
"</div>"
|
|||
|
],
|
|||
|
"text/plain": [
|
|||
|
" actual prediction low80 high80 low95 high95\n",
|
|||
|
"start_at \n",
|
|||
|
"2016-09-15 20:00:00 16 11.26066 8.89482 13.62651 7.64242 14.87891"
|
|||
|
]
|
|||
|
},
|
|||
|
"execution_count": 48,
|
|||
|
"metadata": {},
|
|||
|
"output_type": "execute_result"
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
"rtarima.predict(pixel, predict_at, 8)"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"#### *hsma* Model"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"For pixels with low demand (i.e., averaging between 2.5 and 10 orders per day), a **simple moving average** applied to a horizontal time series is a more robust model."
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 49,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [],
|
|||
|
"source": [
|
|||
|
"hsma = models.HorizontalSMAModel(orders)"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 50,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/html": [
|
|||
|
"<div>\n",
|
|||
|
"<style scoped>\n",
|
|||
|
" .dataframe tbody tr th:only-of-type {\n",
|
|||
|
" vertical-align: middle;\n",
|
|||
|
" }\n",
|
|||
|
"\n",
|
|||
|
" .dataframe tbody tr th {\n",
|
|||
|
" vertical-align: top;\n",
|
|||
|
" }\n",
|
|||
|
"\n",
|
|||
|
" .dataframe thead th {\n",
|
|||
|
" text-align: right;\n",
|
|||
|
" }\n",
|
|||
|
"</style>\n",
|
|||
|
"<table border=\"1\" class=\"dataframe\">\n",
|
|||
|
" <thead>\n",
|
|||
|
" <tr style=\"text-align: right;\">\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th>actual</th>\n",
|
|||
|
" <th>prediction</th>\n",
|
|||
|
" <th>low80</th>\n",
|
|||
|
" <th>high80</th>\n",
|
|||
|
" <th>low95</th>\n",
|
|||
|
" <th>high95</th>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>start_at</th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" </tr>\n",
|
|||
|
" </thead>\n",
|
|||
|
" <tbody>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 20:00:00</th>\n",
|
|||
|
" <td>16</td>\n",
|
|||
|
" <td>9.928571</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" </tbody>\n",
|
|||
|
"</table>\n",
|
|||
|
"</div>"
|
|||
|
],
|
|||
|
"text/plain": [
|
|||
|
" actual prediction low80 high80 low95 high95\n",
|
|||
|
"start_at \n",
|
|||
|
"2016-09-15 20:00:00 16 9.928571 NaN NaN NaN NaN"
|
|||
|
]
|
|||
|
},
|
|||
|
"execution_count": 50,
|
|||
|
"metadata": {},
|
|||
|
"output_type": "execute_result"
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
"hsma.predict(pixel, predict_at, 8)"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"#### *trivial* Model"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"For pixels with practically no demand (i.e., averaging below 2.5 orders per day), predicting $0$ is the best option as this model is *not* distracted by the noise in the time series."
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 51,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [],
|
|||
|
"source": [
|
|||
|
"trivial = models.TrivialModel(orders)"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 52,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/html": [
|
|||
|
"<div>\n",
|
|||
|
"<style scoped>\n",
|
|||
|
" .dataframe tbody tr th:only-of-type {\n",
|
|||
|
" vertical-align: middle;\n",
|
|||
|
" }\n",
|
|||
|
"\n",
|
|||
|
" .dataframe tbody tr th {\n",
|
|||
|
" vertical-align: top;\n",
|
|||
|
" }\n",
|
|||
|
"\n",
|
|||
|
" .dataframe thead th {\n",
|
|||
|
" text-align: right;\n",
|
|||
|
" }\n",
|
|||
|
"</style>\n",
|
|||
|
"<table border=\"1\" class=\"dataframe\">\n",
|
|||
|
" <thead>\n",
|
|||
|
" <tr style=\"text-align: right;\">\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th>actual</th>\n",
|
|||
|
" <th>prediction</th>\n",
|
|||
|
" <th>low80</th>\n",
|
|||
|
" <th>high80</th>\n",
|
|||
|
" <th>low95</th>\n",
|
|||
|
" <th>high95</th>\n",
|
|||
|
" </tr>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>start_at</th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" <th></th>\n",
|
|||
|
" </tr>\n",
|
|||
|
" </thead>\n",
|
|||
|
" <tbody>\n",
|
|||
|
" <tr>\n",
|
|||
|
" <th>2016-09-15 20:00:00</th>\n",
|
|||
|
" <td>16</td>\n",
|
|||
|
" <td>0.0</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" <td>NaN</td>\n",
|
|||
|
" </tr>\n",
|
|||
|
" </tbody>\n",
|
|||
|
"</table>\n",
|
|||
|
"</div>"
|
|||
|
],
|
|||
|
"text/plain": [
|
|||
|
" actual prediction low80 high80 low95 high95\n",
|
|||
|
"start_at \n",
|
|||
|
"2016-09-15 20:00:00 16 0.0 NaN NaN NaN NaN"
|
|||
|
]
|
|||
|
},
|
|||
|
"execution_count": 52,
|
|||
|
"metadata": {},
|
|||
|
"output_type": "execute_result"
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
"trivial.predict(pixel, predict_at, 8)"
|
|||
|
]
|
|||
|
}
|
|||
|
],
|
|||
|
"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.8.6"
|
|||
|
}
|
|||
|
},
|
|||
|
"nbformat": 4,
|
|||
|
"nbformat_minor": 4
|
|||
|
}
|