{"id":56,"date":"2025-08-14T00:57:25","date_gmt":"2025-08-14T00:57:25","guid":{"rendered":"https:\/\/openbooks.spmvv.ac.in\/businessopsanalytics\/chapter\/forecasting-and-predictive-modeling\/"},"modified":"2026-07-10T23:59:39","modified_gmt":"2026-07-10T23:59:39","slug":"forecasting-and-predictive-modeling","status":"publish","type":"chapter","link":"https:\/\/openbooks.spmvv.ac.in\/businessopsanalytics\/chapter\/forecasting-and-predictive-modeling\/","title":{"raw":"Forecasting and Predictive Analytics","rendered":"Forecasting and Predictive Analytics"},"content":{"raw":"<a href=\"http:\/\/pressbooks.usnh.edu\/businessopsanalytics\/files\/2025\/08\/Chapter-10-Header.png\"><img src=\"https:\/\/openbooks.spmvv.ac.in\/app\/uploads\/sites\/3\/2025\/08\/Chapter-10-Header.png\"><\/a>\n<div class=\"textbox textbox--learning-objectives\"><header class=\"textbox__header\">\n<p class=\"textbox__title\">Learning Objectives<\/p>\n\n<\/header>\n<div class=\"textbox__content\">\n<p data-start=\"544\" data-end=\"586\">By the end of this chapter, students will:<\/p>\n\n<ol data-start=\"587\" data-end=\"1006\">\n \t<li data-start=\"587\" data-end=\"681\">\n<p data-start=\"590\" data-end=\"681\">Prepare operational time series in R and split into training\/test (and rolling-origin).<\/p>\n<\/li>\n \t<li data-start=\"682\" data-end=\"762\">\n<p data-start=\"685\" data-end=\"762\">Build and compare baseline forecasts (na\u00efve, seasonal na\u00efve, moving average).<\/p>\n<\/li>\n \t<li data-start=\"763\" data-end=\"853\">\n<p data-start=\"766\" data-end=\"853\">Fit exponential smoothing (ETS) and ARIMA models; interpret components and diagnostics.<\/p>\n<\/li>\n \t<li data-start=\"854\" data-end=\"931\">\n<p data-start=\"857\" data-end=\"931\">Evaluate accuracy with MAE, RMSE, and MAPE; select a model for deployment.<\/p>\n<\/li>\n \t<li data-start=\"932\" data-end=\"1006\">\n<p data-start=\"935\" data-end=\"1006\">Produce a short operations recommendation grounded in forecast results.<\/p>\n<\/li>\n<\/ol>\n<\/div>\n<\/div>\n<h2 data-start=\"219\" data-end=\"256\"><strong data-start=\"222\" data-end=\"256\">10.1 Framing and data prep (R)<\/strong><\/h2>\n<p data-start=\"311\" data-end=\"541\">Forecasting is about estimating future values in a time series \u2014 here, daily orders. Predictive analytics goes a step further by adding outside drivers, such as promotions or weather, that may explain or improve those forecasts.<\/p>\n<p data-start=\"543\" data-end=\"695\">Before modeling, clarify the business question: <em data-start=\"591\" data-end=\"687\">\u201cHow many orders should we expect in the next 28 days, so we can plan staffing and inventory?\u201d<\/em> Then:<\/p>\n\n<ul data-start=\"696\" data-end=\"988\">\n \t<li data-start=\"696\" data-end=\"764\">\n<p data-start=\"698\" data-end=\"764\">Choose the right frequency (daily orders with a weekly pattern).<\/p>\n<\/li>\n \t<li data-start=\"765\" data-end=\"873\">\n<p data-start=\"767\" data-end=\"873\">Hold out the last 28 days of data as a test window. This gives us an honest way to judge model accuracy.<\/p>\n<\/li>\n \t<li data-start=\"874\" data-end=\"988\">\n<p data-start=\"876\" data-end=\"988\">Prepare candidate external drivers (e.g., promo days, average daily temperature) for models that support them.<\/p>\n<\/li>\n<\/ul>\n<p data-start=\"663\" data-end=\"668\"><strong data-start=\"663\" data-end=\"668\">R<\/strong><\/p>\n\n<div class=\"contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary\">\n<div class=\"overflow-y-auto p-4\" dir=\"ltr\">\n\n<span style=\"font-size: 12pt\"><code class=\"whitespace-pre! language-r\">library<span class=\"hljs-punctuation\">(<\/span>readr<span class=\"hljs-punctuation\">)<\/span>; library<span class=\"hljs-punctuation\">(<\/span>dplyr<span class=\"hljs-punctuation\">)<\/span>; library<span class=\"hljs-punctuation\">(<\/span>lubridate<span class=\"hljs-punctuation\">)<\/span>; library<span class=\"hljs-punctuation\">(<\/span>ggplot2<span class=\"hljs-punctuation\">)<\/span>; library<span class=\"hljs-punctuation\">(<\/span>forecast<span class=\"hljs-punctuation\">)<\/span><\/code><\/span>\n\ndf <span class=\"hljs-operator\">&lt;-<\/span> read_csv<span class=\"hljs-punctuation\">(<\/span><span class=\"hljs-string\">\"Chapter10_DailyOrders_PlymouthNH.csv\"<\/span><span class=\"hljs-punctuation\">)<\/span> <span class=\"hljs-operator\">%&gt;%<\/span> mutate<span class=\"hljs-punctuation\">(<\/span>date <span class=\"hljs-operator\">=<\/span> as.Date<span class=\"hljs-punctuation\">(<\/span>date<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">)<\/span>\n\n<span class=\"hljs-comment\"># hold out the last 28 days<\/span>\nh <span class=\"hljs-operator\">&lt;-<\/span> 28\ndf_train <span class=\"hljs-operator\">&lt;-<\/span> df <span class=\"hljs-operator\">|&gt;<\/span> slice_head<span class=\"hljs-punctuation\">(<\/span>n <span class=\"hljs-operator\">=<\/span> n<span class=\"hljs-punctuation\">(<\/span><span class=\"hljs-punctuation\">)<\/span> <span class=\"hljs-operator\">-<\/span> h<span class=\"hljs-punctuation\">)<\/span>\ndf_test <span class=\"hljs-operator\">&lt;-<\/span> df <span class=\"hljs-operator\">|&gt;<\/span> slice_tail<span class=\"hljs-punctuation\">(<\/span>n <span class=\"hljs-operator\">=<\/span> h<span class=\"hljs-punctuation\">)<\/span>\n\n<span class=\"hljs-comment\"># weekly seasonality -&gt; frequency = 7<\/span>\ny_train <span class=\"hljs-operator\">&lt;-<\/span> ts<span class=\"hljs-punctuation\">(<\/span>df_train<span class=\"hljs-operator\">$<\/span>orders<span class=\"hljs-punctuation\">,<\/span> frequency <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-number\">7<\/span><span class=\"hljs-punctuation\">)<\/span>\ny_full <span class=\"hljs-operator\">&lt;-<\/span> ts<span class=\"hljs-punctuation\">(<\/span>df<span class=\"hljs-operator\">$<\/span>orders<span class=\"hljs-punctuation\">,<\/span> frequency <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-number\">7<\/span><span class=\"hljs-punctuation\">)<\/span>\n\n<span class=\"hljs-comment\"># candidate external drivers (optional in some models)<\/span>\nx_train <span class=\"hljs-operator\">&lt;-<\/span> as.matrix<span class=\"hljs-punctuation\">(<\/span>df_train<span class=\"hljs-punctuation\">[<\/span><span class=\"hljs-punctuation\">,<\/span> <span class=\"hljs-built_in\">c<\/span><span class=\"hljs-punctuation\">(<\/span><span class=\"hljs-string\">\"promo_flag\"<\/span><span class=\"hljs-punctuation\">,<\/span><span class=\"hljs-string\">\"avg_temp_f\"<\/span><span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">]<\/span><span class=\"hljs-punctuation\">)<\/span>\nx_test <span class=\"hljs-operator\">&lt;-<\/span> as.matrix<span class=\"hljs-punctuation\">(<\/span>df_test<span class=\"hljs-punctuation\">[<\/span><span class=\"hljs-punctuation\">,<\/span> <span class=\"hljs-built_in\">c<\/span><span class=\"hljs-punctuation\">(<\/span><span class=\"hljs-string\">\"promo_flag\"<\/span><span class=\"hljs-punctuation\">,<\/span><span class=\"hljs-string\">\"avg_temp_f\"<\/span><span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">]<\/span><span class=\"hljs-punctuation\">)<\/span>\n\nggplot<span class=\"hljs-punctuation\">(<\/span>df<span class=\"hljs-punctuation\">,<\/span> aes<span class=\"hljs-punctuation\">(<\/span>date<span class=\"hljs-punctuation\">,<\/span> orders<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">)<\/span> <span class=\"hljs-operator\">+<\/span> geom_line<span class=\"hljs-punctuation\">(<\/span><span class=\"hljs-punctuation\">)<\/span>\n\n<\/div>\n<\/div>\n<h2 data-start=\"1334\" data-end=\"1394\"><strong data-start=\"1337\" data-end=\"1394\">10.2 Baselines: na\u00efve, seasonal na\u00efve, moving average<\/strong><\/h2>\n<p data-start=\"1395\" data-end=\"1495\">Baselines are simple \u201cno-frills\u201d forecasts. They set the minimum that more complex models must beat.<\/p>\n\n<ul data-start=\"1496\" data-end=\"1752\">\n \t<li data-start=\"1496\" data-end=\"1559\">\n<p data-start=\"1498\" data-end=\"1559\">Na\u00efve: tomorrow equals today. Good when series wander slowly.<\/p>\n<\/li>\n \t<li data-start=\"1560\" data-end=\"1652\">\n<p data-start=\"1562\" data-end=\"1652\">Seasonal na\u00efve: next Monday equals last Monday. Strong when day-of-week patterns dominate.<\/p>\n<\/li>\n \t<li data-start=\"1653\" data-end=\"1752\">\n<p data-start=\"1655\" data-end=\"1752\">Moving average: smooths noise to show the local level but does not project seasonality by itself.<\/p>\n<\/li>\n<\/ul>\n<p data-start=\"1754\" data-end=\"1759\"><strong data-start=\"1754\" data-end=\"1759\">R<\/strong><\/p>\n\n<div class=\"contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary\">\n<div class=\"sticky top-9\">\n<div class=\"absolute end-0 bottom-0 flex h-9 items-center pe-2\">\n<div class=\"bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs\"><span class=\"\" data-state=\"closed\"><\/span><\/div>\n<\/div>\n<\/div>\n<div class=\"overflow-y-auto p-4\" dir=\"ltr\"><span style=\"font-size: 12pt\"><code class=\"whitespace-pre! language-r\"><code class=\"whitespace-pre! language-r\">fc_naive  <span class=\"hljs-operator\">&lt;-<\/span> naive<span class=\"hljs-punctuation\">(<\/span>y_train<span class=\"hljs-punctuation\">,<\/span>  h <span class=\"hljs-operator\">=<\/span> h<span class=\"hljs-punctuation\">)<\/span>\nfc_snaive <span class=\"hljs-operator\">&lt;-<\/span> snaive<span class=\"hljs-punctuation\">(<\/span>y_train<span class=\"hljs-punctuation\">,<\/span> h <span class=\"hljs-operator\">=<\/span> h<span class=\"hljs-punctuation\">)<\/span>  <span class=\"hljs-comment\"># respects weekly pattern<\/span><\/code><\/code>autoplot<span class=\"hljs-punctuation\">(<\/span>y_full<span class=\"hljs-punctuation\">)<\/span> <span class=\"hljs-operator\">+<\/span><\/span>\n<span style=\"font-size: 12pt\">autolayer<span class=\"hljs-punctuation\">(<\/span>fc_snaive<span class=\"hljs-punctuation\">,<\/span> series <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-string\">\"Seasonal naive\"<\/span><span class=\"hljs-punctuation\">,<\/span> PI <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-literal\">FALSE<\/span><span class=\"hljs-punctuation\">)<\/span> <span class=\"hljs-operator\">+<\/span><\/span>\n<span style=\"font-size: 12pt\">autolayer<span class=\"hljs-punctuation\">(<\/span>fc_naive<span class=\"hljs-punctuation\">,<\/span> series <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-string\">\"Naive\"<\/span><span class=\"hljs-punctuation\">,<\/span> PI <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-literal\">FALSE<\/span><span class=\"hljs-punctuation\">)<\/span><\/span><\/div>\n<\/div>\n<h2 data-start=\"2020\" data-end=\"2059\"><strong data-start=\"2023\" data-end=\"2059\">10.3 Exponential smoothing (ETS)<\/strong><\/h2>\n<p data-start=\"2060\" data-end=\"2383\">ETS breaks the series into level, trend, and seasonality. It adapts quickly when things change and is a common default for operational data. R can automatically pick the best combination of additive or multiplicative forms. After fitting, check residuals to confirm no leftover pattern.<\/p>\n<p data-start=\"2385\" data-end=\"2390\"><strong data-start=\"2385\" data-end=\"2390\">R<\/strong><\/p>\n\n<div class=\"contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary\">\n<div class=\"sticky top-9\">\n<div class=\"absolute end-0 bottom-0 flex h-9 items-center pe-2\">\n<div class=\"bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs\"><span class=\"\" data-state=\"closed\"><\/span><\/div>\n<\/div>\n<\/div>\n<div class=\"overflow-y-auto p-4\" dir=\"ltr\"><span style=\"font-size: 12pt\"><code class=\"whitespace-pre! language-r\"><code class=\"whitespace-pre! language-r\">fit_ets <span class=\"hljs-operator\">&lt;-<\/span> ets<span class=\"hljs-punctuation\">(<\/span>y_train<span class=\"hljs-punctuation\">)<\/span>              <span class=\"hljs-comment\"># auto-selects additive\/multiplicative forms<\/span>\nfc_ets  <span class=\"hljs-operator\">&lt;-<\/span> forecast<span class=\"hljs-punctuation\">(<\/span>fit_ets<span class=\"hljs-punctuation\">,<\/span> h <span class=\"hljs-operator\">=<\/span> h<span class=\"hljs-punctuation\">)<\/span><\/code><\/code>autoplot<span class=\"hljs-punctuation\">(<\/span>fc_ets<span class=\"hljs-punctuation\">)<\/span><\/span>\n<span style=\"font-size: 12pt\">checkresiduals<span class=\"hljs-punctuation\">(<\/span>fit_ets<span class=\"hljs-punctuation\">)<\/span> <span class=\"hljs-comment\"># want residuals ~ white noise<\/span><\/span><\/div>\n<\/div>\n<h2 data-start=\"2610\" data-end=\"2668\"><strong data-start=\"2613\" data-end=\"2668\">10.4 ARIMA and ARIMAX (with temperature and promos)<\/strong><\/h2>\n<p data-start=\"1725\" data-end=\"1849\">ARIMA uses past values and past errors to explain the series. Seasonal ARIMA adds repeating patterns (like weekly cycles).<\/p>\n\n<ul data-start=\"1850\" data-end=\"2038\">\n \t<li data-start=\"1850\" data-end=\"1904\">\n<p data-start=\"1852\" data-end=\"1904\"><strong data-start=\"1852\" data-end=\"1861\">ARIMA<\/strong>: relies only on the series\u2019 own history.<\/p>\n<\/li>\n \t<li data-start=\"1905\" data-end=\"2038\">\n<p data-start=\"1907\" data-end=\"2038\"><strong data-start=\"1907\" data-end=\"1917\">ARIMAX<\/strong>: adds external predictors (e.g., promos, temperature). This can sharpen forecasts when drivers explain part of demand.<\/p>\n<\/li>\n<\/ul>\n<p data-start=\"2040\" data-end=\"2150\">Residual checks confirm whether the model has captured the structure, or whether systematic patterns remain.<\/p>\n<p data-start=\"3001\" data-end=\"3006\"><strong data-start=\"3001\" data-end=\"3006\">R<\/strong><\/p>\n\n<div class=\"contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary\">\n<div class=\"sticky top-9\">\n<div class=\"absolute end-0 bottom-0 flex h-9 items-center pe-2\">\n<div class=\"bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs\"><span class=\"\" data-state=\"closed\"><\/span><\/div>\n<\/div>\n<\/div>\n<div class=\"overflow-y-auto p-4\" dir=\"ltr\"><span style=\"font-size: 12pt\"><code class=\"whitespace-pre! language-r\"><code class=\"whitespace-pre! language-r\"><span class=\"hljs-comment\"># ARIMA without drivers<\/span>\nfit_arima <span class=\"hljs-operator\">&lt;-<\/span> auto.arima<span class=\"hljs-punctuation\">(<\/span>y_train<span class=\"hljs-punctuation\">,<\/span> seasonal <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-literal\">TRUE<\/span><span class=\"hljs-punctuation\">)<\/span>\nfc_arima  <span class=\"hljs-operator\">&lt;-<\/span> forecast<span class=\"hljs-punctuation\">(<\/span>fit_arima<span class=\"hljs-punctuation\">,<\/span> h <span class=\"hljs-operator\">=<\/span> h<span class=\"hljs-punctuation\">)<\/span><\/code><\/code><span class=\"hljs-comment\"># ARIMAX with promo + temperature<\/span><\/span>\n<span style=\"font-size: 12pt\">fit_arimax <span class=\"hljs-operator\">&lt;-<\/span> auto.arima<span class=\"hljs-punctuation\">(<\/span>y_train<span class=\"hljs-punctuation\">,<\/span> xreg <span class=\"hljs-operator\">=<\/span> x_train<span class=\"hljs-punctuation\">,<\/span> seasonal <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-literal\">TRUE<\/span><span class=\"hljs-punctuation\">)<\/span><\/span>\n<span style=\"font-size: 12pt\">fc_arimax <span class=\"hljs-operator\">&lt;-<\/span> forecast<span class=\"hljs-punctuation\">(<\/span>fit_arimax<span class=\"hljs-punctuation\">,<\/span> xreg <span class=\"hljs-operator\">=<\/span> x_test<span class=\"hljs-punctuation\">,<\/span> h <span class=\"hljs-operator\">=<\/span> h<span class=\"hljs-punctuation\">)<\/span><\/span><span style=\"font-size: 12pt\"><code class=\"whitespace-pre! language-r\"><code class=\"whitespace-pre! language-r\"><\/code><\/code>checkresiduals<span class=\"hljs-punctuation\">(<\/span>fit_arima<span class=\"hljs-punctuation\">)<\/span><\/span>\n<span style=\"font-size: 12pt\">checkresiduals<span class=\"hljs-punctuation\">(<\/span>fit_arimax<span class=\"hljs-punctuation\">)<\/span><\/span><\/div>\n<\/div>\n<p data-start=\"3343\" data-end=\"3552\"><span style=\"font-size: 12pt\">Notes: Be careful not to \u201cpe<\/span>ek\u201d at the future when preparing drivers (xreg for the test window must be known at forecast time). If residuals still show weekly structure or long runs, revisit the specification.<\/p>\n\n<h2 data-start=\"3559\" data-end=\"3609\"><strong data-start=\"3562\" data-end=\"3609\">10.5 Accuracy comparison and rolling-origin<\/strong><\/h2>\n<p data-start=\"3610\" data-end=\"3671\">We compare competing models on the same holdout window using:<\/p>\n\n<ul data-start=\"3672\" data-end=\"3889\">\n \t<li data-start=\"3672\" data-end=\"3740\">\n<p data-start=\"3674\" data-end=\"3740\">MAE (average absolute error): easy to interpret in original units.<\/p>\n<\/li>\n \t<li data-start=\"3741\" data-end=\"3810\">\n<p data-start=\"3743\" data-end=\"3810\">RMSE (root mean square error): penalizes large misses more heavily.<\/p>\n<\/li>\n \t<li data-start=\"3811\" data-end=\"3889\">\n<p data-start=\"3813\" data-end=\"3889\">MAPE (percentage error): intuitive, but avoid when actuals can be near zero.<\/p>\n<\/li>\n<\/ul>\n<p data-start=\"3891\" data-end=\"4064\">A single split can be lucky. Rolling-origin cross-validation re-forecasts many times from expanding windows and averages the error, giving a more stable view of performance.<\/p>\n<p data-start=\"4066\" data-end=\"4071\"><strong data-start=\"4066\" data-end=\"4071\">R<\/strong><\/p>\n\n<div class=\"contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary\">\n<div class=\"sticky top-9\">\n<div class=\"absolute end-0 bottom-0 flex h-9 items-center pe-2\">\n<div class=\"bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs\"><span class=\"\" data-state=\"closed\"><\/span><\/div>\n<\/div>\n<\/div>\n<div class=\"overflow-y-auto p-4\" dir=\"ltr\">\n\n<span style=\"font-size: 12pt\"><code class=\"whitespace-pre! language-r\">library<span class=\"hljs-punctuation\">(<\/span>Metrics<span class=\"hljs-punctuation\">)<\/span><\/code><\/span>\n\ny_test <span class=\"hljs-operator\">&lt;-<\/span> df_test<span class=\"hljs-operator\">$<\/span>orders\ncompare <span class=\"hljs-operator\">&lt;-<\/span> dplyr<span class=\"hljs-operator\">::<\/span>bind_rows<span class=\"hljs-punctuation\">(<\/span>\ntibble<span class=\"hljs-operator\">::<\/span>tibble<span class=\"hljs-punctuation\">(<\/span>model<span class=\"hljs-operator\">=<\/span><span class=\"hljs-string\">\"naive\"<\/span><span class=\"hljs-punctuation\">,<\/span>\nMAE<span class=\"hljs-operator\">=<\/span>mae<span class=\"hljs-punctuation\">(<\/span>y_test<span class=\"hljs-punctuation\">,<\/span> fc_naive<span class=\"hljs-operator\">$<\/span>mean<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">,<\/span>\nRMSE<span class=\"hljs-operator\">=<\/span>rmse<span class=\"hljs-punctuation\">(<\/span>y_test<span class=\"hljs-punctuation\">,<\/span> fc_naive<span class=\"hljs-operator\">$<\/span>mean<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">,<\/span>\nMAPE<span class=\"hljs-operator\">=<\/span>Metrics<span class=\"hljs-operator\">::<\/span>mape<span class=\"hljs-punctuation\">(<\/span>y_test<span class=\"hljs-punctuation\">,<\/span> fc_naive<span class=\"hljs-operator\">$<\/span>mean<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">,<\/span>\ntibble<span class=\"hljs-operator\">::<\/span>tibble<span class=\"hljs-punctuation\">(<\/span>model<span class=\"hljs-operator\">=<\/span><span class=\"hljs-string\">\"snaive\"<\/span><span class=\"hljs-punctuation\">,<\/span>\nMAE<span class=\"hljs-operator\">=<\/span>mae<span class=\"hljs-punctuation\">(<\/span>y_test<span class=\"hljs-punctuation\">,<\/span> fc_snaive<span class=\"hljs-operator\">$<\/span>mean<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">,<\/span>\nRMSE<span class=\"hljs-operator\">=<\/span>rmse<span class=\"hljs-punctuation\">(<\/span>y_test<span class=\"hljs-punctuation\">,<\/span> fc_snaive<span class=\"hljs-operator\">$<\/span>mean<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">,<\/span>\nMAPE<span class=\"hljs-operator\">=<\/span>Metrics<span class=\"hljs-operator\">::<\/span>mape<span class=\"hljs-punctuation\">(<\/span>y_test<span class=\"hljs-punctuation\">,<\/span> fc_snaive<span class=\"hljs-operator\">$<\/span>mean<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">,<\/span>\ntibble<span class=\"hljs-operator\">::<\/span>tibble<span class=\"hljs-punctuation\">(<\/span>model<span class=\"hljs-operator\">=<\/span><span class=\"hljs-string\">\"ETS\"<\/span><span class=\"hljs-punctuation\">,<\/span>\nMAE<span class=\"hljs-operator\">=<\/span>mae<span class=\"hljs-punctuation\">(<\/span>y_test<span class=\"hljs-punctuation\">,<\/span> fc_ets<span class=\"hljs-operator\">$<\/span>mean<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">,<\/span>\nRMSE<span class=\"hljs-operator\">=<\/span>rmse<span class=\"hljs-punctuation\">(<\/span>y_test<span class=\"hljs-punctuation\">,<\/span> fc_ets<span class=\"hljs-operator\">$<\/span>mean<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">,<\/span>\nMAPE<span class=\"hljs-operator\">=<\/span>Metrics<span class=\"hljs-operator\">::<\/span>mape<span class=\"hljs-punctuation\">(<\/span>y_test<span class=\"hljs-punctuation\">,<\/span> fc_ets<span class=\"hljs-operator\">$<\/span>mean<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">,<\/span>\ntibble<span class=\"hljs-operator\">::<\/span>tibble<span class=\"hljs-punctuation\">(<\/span>model<span class=\"hljs-operator\">=<\/span><span class=\"hljs-string\">\"ARIMA\"<\/span><span class=\"hljs-punctuation\">,<\/span>\nMAE<span class=\"hljs-operator\">=<\/span>mae<span class=\"hljs-punctuation\">(<\/span>y_test<span class=\"hljs-punctuation\">,<\/span> fc_arima<span class=\"hljs-operator\">$<\/span>mean<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">,<\/span>\nRMSE<span class=\"hljs-operator\">=<\/span>rmse<span class=\"hljs-punctuation\">(<\/span>y_test<span class=\"hljs-punctuation\">,<\/span> fc_arima<span class=\"hljs-operator\">$<\/span>mean<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">,<\/span>\nMAPE<span class=\"hljs-operator\">=<\/span>Metrics<span class=\"hljs-operator\">::<\/span>mape<span class=\"hljs-punctuation\">(<\/span>y_test<span class=\"hljs-punctuation\">,<\/span> fc_arima<span class=\"hljs-operator\">$<\/span>mean<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">,<\/span>\ntibble<span class=\"hljs-operator\">::<\/span>tibble<span class=\"hljs-punctuation\">(<\/span>model<span class=\"hljs-operator\">=<\/span><span class=\"hljs-string\">\"ARIMAX\"<\/span><span class=\"hljs-punctuation\">,<\/span>\nMAE<span class=\"hljs-operator\">=<\/span>mae<span class=\"hljs-punctuation\">(<\/span>y_test<span class=\"hljs-punctuation\">,<\/span> fc_arimax<span class=\"hljs-operator\">$<\/span>mean<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">,<\/span>\nRMSE<span class=\"hljs-operator\">=<\/span>rmse<span class=\"hljs-punctuation\">(<\/span>y_test<span class=\"hljs-punctuation\">,<\/span> fc_arimax<span class=\"hljs-operator\">$<\/span>mean<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">,<\/span>\nMAPE<span class=\"hljs-operator\">=<\/span>Metrics<span class=\"hljs-operator\">::<\/span>mape<span class=\"hljs-punctuation\">(<\/span>y_test<span class=\"hljs-punctuation\">,<\/span> fc_arimax<span class=\"hljs-operator\">$<\/span>mean<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">)<\/span>\n<span class=\"hljs-punctuation\">)<\/span> <span class=\"hljs-operator\">|&gt;<\/span> arrange<span class=\"hljs-punctuation\">(<\/span>RMSE<span class=\"hljs-punctuation\">)<\/span>\ncompare\n\n<\/div>\n<\/div>\n<p data-start=\"5145\" data-end=\"5184\">Rolling-origin example (7-day horizon):<\/p>\n\n<div class=\"contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary\">\n<div class=\"sticky top-9\">\n<div class=\"absolute end-0 bottom-0 flex h-9 items-center pe-2\">\n<div class=\"bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs\"><span class=\"\" data-state=\"closed\"><\/span><\/div>\n<\/div>\n<\/div>\n<div class=\"overflow-y-auto p-4\" dir=\"ltr\"><span style=\"font-size: 12pt\"><code class=\"whitespace-pre! language-r\"><code class=\"whitespace-pre! language-r\">e_snaive <span class=\"hljs-operator\">&lt;-<\/span> tsCV<span class=\"hljs-punctuation\">(<\/span>y_full<span class=\"hljs-punctuation\">,<\/span> <span class=\"hljs-keyword\">function<\/span><span class=\"hljs-punctuation\">(<\/span>y<span class=\"hljs-punctuation\">,<\/span> h<span class=\"hljs-punctuation\">)<\/span> forecast<span class=\"hljs-punctuation\">(<\/span>snaive<span class=\"hljs-punctuation\">(<\/span>y<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">,<\/span>     h<span class=\"hljs-operator\">=<\/span>h<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">,<\/span> h <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-number\">7<\/span><span class=\"hljs-punctuation\">)<\/span>\ne_arima  <span class=\"hljs-operator\">&lt;-<\/span> tsCV<span class=\"hljs-punctuation\">(<\/span>y_full<span class=\"hljs-punctuation\">,<\/span> <span class=\"hljs-keyword\">function<\/span><span class=\"hljs-punctuation\">(<\/span>y<span class=\"hljs-punctuation\">,<\/span> h<span class=\"hljs-punctuation\">)<\/span> forecast<span class=\"hljs-punctuation\">(<\/span>auto.arima<span class=\"hljs-punctuation\">(<\/span>y<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">,<\/span> h<span class=\"hljs-operator\">=<\/span>h<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">,<\/span> h <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-number\">7<\/span><span class=\"hljs-punctuation\">)<\/span><\/code><\/code><span class=\"hljs-built_in\">sqrt<\/span><span class=\"hljs-punctuation\">(<\/span>mean<span class=\"hljs-punctuation\">(<\/span>e_snaive<span class=\"hljs-operator\">^<\/span><span class=\"hljs-number\">2<\/span><span class=\"hljs-punctuation\">,<\/span> na.rm<span class=\"hljs-operator\">=<\/span><span class=\"hljs-literal\">TRUE<\/span><span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">)<\/span><\/span>\n<span style=\"font-size: 12pt\"><span class=\"hljs-built_in\">sqrt<\/span><span class=\"hljs-punctuation\">(<\/span>mean<span class=\"hljs-punctuation\">(<\/span>e_arima<span class=\"hljs-operator\">^<\/span><span class=\"hljs-number\">2<\/span><span class=\"hljs-punctuation\">,<\/span> na.rm<span class=\"hljs-operator\">=<\/span><span class=\"hljs-literal\">TRUE<\/span><span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">)<\/span><\/span><\/div>\n<\/div>\n<p data-start=\"5419\" data-end=\"5517\">Choose the simplest model that meets your accuracy target and leaves residuals looking like noise.<\/p>\n\n<h2 data-start=\"5524\" data-end=\"5577\"><strong data-start=\"5527\" data-end=\"5577\">10.6 Applied example: 28-day staffing plan (R)<\/strong><\/h2>\n<p data-start=\"2721\" data-end=\"2958\">Forecasts matter when they drive action. For Pemi Coffee Roasters, we use the chosen model (e.g., ETS or ARIMAX) to forecast 28 days of orders. Orders are converted into staff requirements using a simple rule (one staff per 40 orders).<\/p>\n<p data-start=\"2960\" data-end=\"2999\">The deliverable is a short memo with:<\/p>\n\n<ul data-start=\"3000\" data-end=\"3195\">\n \t<li data-start=\"3000\" data-end=\"3035\">\n<p data-start=\"3002\" data-end=\"3035\">The forecast horizon (28 days).<\/p>\n<\/li>\n \t<li data-start=\"3036\" data-end=\"3081\">\n<p data-start=\"3038\" data-end=\"3081\">The chosen model and why it was selected.<\/p>\n<\/li>\n \t<li data-start=\"3082\" data-end=\"3110\">\n<p data-start=\"3084\" data-end=\"3110\">A staffing table by day.<\/p>\n<\/li>\n \t<li data-start=\"3111\" data-end=\"3195\">\n<p data-start=\"3113\" data-end=\"3195\">Any flagged risks (e.g., promotions or heat waves) and one suggested mitigation.<\/p>\n<\/li>\n<\/ul>\n<p data-start=\"5906\" data-end=\"5911\"><strong data-start=\"5906\" data-end=\"5911\">R<\/strong><\/p>\n\n<div class=\"contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary\">\n<div class=\"sticky top-9\">\n<div class=\"absolute end-0 bottom-0 flex h-9 items-center pe-2\">\n<div class=\"bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs\"><span class=\"\" data-state=\"closed\"><\/span><\/div>\n<\/div>\n<\/div>\n<div class=\"overflow-y-auto p-4\" dir=\"ltr\"><span style=\"font-size: 12pt\"><code class=\"whitespace-pre! language-r\"><code class=\"whitespace-pre! language-r\">best <span class=\"hljs-operator\">&lt;-<\/span> fit_arimax   <span class=\"hljs-comment\"># or fit_ets \/ fit_arima based on compare + residuals<\/span>\nfc   <span class=\"hljs-operator\">&lt;-<\/span> forecast<span class=\"hljs-punctuation\">(<\/span>best<span class=\"hljs-punctuation\">,<\/span> xreg <span class=\"hljs-operator\">=<\/span> x_test<span class=\"hljs-punctuation\">,<\/span> h <span class=\"hljs-operator\">=<\/span> h<span class=\"hljs-punctuation\">)<\/span><\/code><\/code>staff_per_day <span class=\"hljs-operator\">&lt;-<\/span> <span class=\"hljs-built_in\">ceiling<\/span><span class=\"hljs-punctuation\">(<\/span><span class=\"hljs-built_in\">as.numeric<\/span><span class=\"hljs-punctuation\">(<\/span>fc<span class=\"hljs-operator\">$<\/span>mean<span class=\"hljs-punctuation\">)<\/span> <span class=\"hljs-operator\">\/<\/span> <span class=\"hljs-number\">40<\/span><span class=\"hljs-punctuation\">)<\/span><\/span>\n<span style=\"font-size: 12pt\">out <span class=\"hljs-operator\">&lt;-<\/span> tibble<span class=\"hljs-operator\">::<\/span>tibble<span class=\"hljs-punctuation\">(<\/span><\/span>\n<span style=\"font-size: 12pt\">date <span class=\"hljs-operator\">=<\/span> tail<span class=\"hljs-punctuation\">(<\/span>df<span class=\"hljs-operator\">$<\/span>date<span class=\"hljs-punctuation\">,<\/span> <span class=\"hljs-number\">1<\/span><span class=\"hljs-punctuation\">)<\/span> <span class=\"hljs-operator\">+<\/span> <span class=\"hljs-number\">1<\/span><span class=\"hljs-operator\">:<\/span>h<span class=\"hljs-punctuation\">,<\/span><\/span>\n<span style=\"font-size: 12pt\">forecast_orders <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-built_in\">as.numeric<\/span><span class=\"hljs-punctuation\">(<\/span>fc<span class=\"hljs-operator\">$<\/span>mean<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">,<\/span><\/span>\n<span style=\"font-size: 12pt\">staff_needed <span class=\"hljs-operator\">=<\/span> staff_per_day<\/span>\n<span class=\"hljs-punctuation\" style=\"font-size: 12pt\">)<\/span>\nprint<span class=\"hljs-punctuation\">(<\/span>out<span class=\"hljs-punctuation\">)<\/span><\/div>\n<\/div>\n<p data-start=\"6248\" data-end=\"6411\">Memo pointers: state the horizon, the chosen model and why, attach the daily staffing table, flag any operational risks (e.g., a promo cluster) and one mitigation.<\/p>\n\n<div class=\"textbox textbox--key-takeaways\"><header class=\"textbox__header\">\n<p class=\"textbox__title\">Key Takeaways<\/p>\n\n<\/header>\n<div class=\"textbox__content\">\n<ul>\n \t<li data-start=\"82\" data-end=\"179\">\n<p data-start=\"84\" data-end=\"179\">Forecasting projects future demand; predictive analytics adds drivers like promos or weather.<\/p>\n<\/li>\n \t<li data-start=\"180\" data-end=\"250\">\n<p data-start=\"182\" data-end=\"250\">Define the question, set frequency, and hold out data for testing.<\/p>\n<\/li>\n \t<li data-start=\"251\" data-end=\"323\">\n<p data-start=\"253\" data-end=\"323\">Baselines (na\u00efve, seasonal na\u00efve, moving average) are the benchmark.<\/p>\n<\/li>\n \t<li data-start=\"324\" data-end=\"400\">\n<p data-start=\"326\" data-end=\"400\">ETS, ARIMA, and ARIMAX capture trend, seasonality, and external drivers.<\/p>\n<\/li>\n \t<li data-start=\"401\" data-end=\"477\">\n<p data-start=\"403\" data-end=\"477\">Accuracy checks use MAE, RMSE, and MAPE, plus rolling-origin validation.<\/p>\n<\/li>\n \t<li data-start=\"478\" data-end=\"546\">\n<p data-start=\"480\" data-end=\"546\">Forecasts should guide concrete actions, such as staffing plans.<\/p>\n<\/li>\n<\/ul>\n<\/div>\n<\/div>\n<h2>Chapter 10 References<\/h2>\n<p data-start=\"253\" data-end=\"354\">Microsoft. (n.d.). <em data-start=\"272\" data-end=\"305\">Forecasting functions in Excel.<\/em> Microsoft. <a data-start=\"317\" data-end=\"352\" rel=\"noopener\" target=\"_new\" class=\"decorated-link cursor-pointer\" href=\"https:\/\/support.microsoft.com\/excel\">https:\/\/support.microsoft.com\/excel<span aria-hidden=\"true\" class=\"ms-0.5 inline-block align-middle leading-none\"><\/span><\/a><\/p>\n<p data-start=\"357\" data-end=\"504\">R Core Team. (2023). <em data-start=\"378\" data-end=\"436\">R: A language and environment for statistical computing.<\/em> R Foundation for Statistical Computing. <a data-start=\"477\" data-end=\"502\" rel=\"noopener\" target=\"_new\" class=\"decorated-link cursor-pointer\" href=\"https:\/\/www.r-project.org\">https:\/\/www.r-project.org<span aria-hidden=\"true\" class=\"ms-0.5 inline-block align-middle leading-none\"><\/span><\/a><\/p>\n<p data-start=\"507\" data-end=\"636\">Hyndman, R. J., &amp; Athanasopoulos, G. (2021). <em data-start=\"552\" data-end=\"590\">Forecasting: Principles and practice<\/em> (3rd ed.). OTexts. <a data-start=\"610\" data-end=\"634\" rel=\"noopener\" target=\"_new\" class=\"decorated-link cursor-pointer\" href=\"https:\/\/otexts.com\/fpp3\/\">https:\/\/otexts.com\/fpp3\/<span aria-hidden=\"true\" class=\"ms-0.5 inline-block align-middle leading-none\"><\/span><\/a><\/p>\n<p data-start=\"639\" data-end=\"790\">Wickham, H., &amp; Grolemund, G. (2017). <em data-start=\"676\" data-end=\"749\">R for data science: Import, tidy, transform, visualize, and model data.<\/em> O\u2019Reilly Media. <a data-start=\"766\" data-end=\"788\" rel=\"noopener\" target=\"_new\" class=\"decorated-link cursor-pointer\" href=\"https:\/\/r4ds.had.co.nz\">https:\/\/r4ds.had.co.nz<\/a><\/p>\n&nbsp;","rendered":"<p><a href=\"http:\/\/pressbooks.usnh.edu\/businessopsanalytics\/files\/2025\/08\/Chapter-10-Header.png\"><img decoding=\"async\" src=\"https:\/\/openbooks.spmvv.ac.in\/app\/uploads\/sites\/3\/2025\/08\/Chapter-10-Header.png\" alt=\"image\" \/><\/a><\/p>\n<div class=\"textbox textbox--learning-objectives\">\n<header class=\"textbox__header\">\n<p class=\"textbox__title\">Learning Objectives<\/p>\n<\/header>\n<div class=\"textbox__content\">\n<p data-start=\"544\" data-end=\"586\">By the end of this chapter, students will:<\/p>\n<ol data-start=\"587\" data-end=\"1006\">\n<li data-start=\"587\" data-end=\"681\">\n<p data-start=\"590\" data-end=\"681\">Prepare operational time series in R and split into training\/test (and rolling-origin).<\/p>\n<\/li>\n<li data-start=\"682\" data-end=\"762\">\n<p data-start=\"685\" data-end=\"762\">Build and compare baseline forecasts (na\u00efve, seasonal na\u00efve, moving average).<\/p>\n<\/li>\n<li data-start=\"763\" data-end=\"853\">\n<p data-start=\"766\" data-end=\"853\">Fit exponential smoothing (ETS) and ARIMA models; interpret components and diagnostics.<\/p>\n<\/li>\n<li data-start=\"854\" data-end=\"931\">\n<p data-start=\"857\" data-end=\"931\">Evaluate accuracy with MAE, RMSE, and MAPE; select a model for deployment.<\/p>\n<\/li>\n<li data-start=\"932\" data-end=\"1006\">\n<p data-start=\"935\" data-end=\"1006\">Produce a short operations recommendation grounded in forecast results.<\/p>\n<\/li>\n<\/ol>\n<\/div>\n<\/div>\n<h2 data-start=\"219\" data-end=\"256\"><strong data-start=\"222\" data-end=\"256\">10.1 Framing and data prep (R)<\/strong><\/h2>\n<p data-start=\"311\" data-end=\"541\">Forecasting is about estimating future values in a time series \u2014 here, daily orders. Predictive analytics goes a step further by adding outside drivers, such as promotions or weather, that may explain or improve those forecasts.<\/p>\n<p data-start=\"543\" data-end=\"695\">Before modeling, clarify the business question: <em data-start=\"591\" data-end=\"687\">\u201cHow many orders should we expect in the next 28 days, so we can plan staffing and inventory?\u201d<\/em> Then:<\/p>\n<ul data-start=\"696\" data-end=\"988\">\n<li data-start=\"696\" data-end=\"764\">\n<p data-start=\"698\" data-end=\"764\">Choose the right frequency (daily orders with a weekly pattern).<\/p>\n<\/li>\n<li data-start=\"765\" data-end=\"873\">\n<p data-start=\"767\" data-end=\"873\">Hold out the last 28 days of data as a test window. This gives us an honest way to judge model accuracy.<\/p>\n<\/li>\n<li data-start=\"874\" data-end=\"988\">\n<p data-start=\"876\" data-end=\"988\">Prepare candidate external drivers (e.g., promo days, average daily temperature) for models that support them.<\/p>\n<\/li>\n<\/ul>\n<p data-start=\"663\" data-end=\"668\"><strong data-start=\"663\" data-end=\"668\">R<\/strong><\/p>\n<div class=\"contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary\">\n<div class=\"overflow-y-auto p-4\" dir=\"ltr\">\n<p><span style=\"font-size: 12pt\"><code class=\"whitespace-pre! language-r\">library<span class=\"hljs-punctuation\">(<\/span>readr<span class=\"hljs-punctuation\">)<\/span>; library<span class=\"hljs-punctuation\">(<\/span>dplyr<span class=\"hljs-punctuation\">)<\/span>; library<span class=\"hljs-punctuation\">(<\/span>lubridate<span class=\"hljs-punctuation\">)<\/span>; library<span class=\"hljs-punctuation\">(<\/span>ggplot2<span class=\"hljs-punctuation\">)<\/span>; library<span class=\"hljs-punctuation\">(<\/span>forecast<span class=\"hljs-punctuation\">)<\/span><\/code><\/span><\/p>\n<p>df <span class=\"hljs-operator\">&lt;-<\/span> read_csv<span class=\"hljs-punctuation\">(<\/span><span class=\"hljs-string\">&#8220;Chapter10_DailyOrders_PlymouthNH.csv&#8221;<\/span><span class=\"hljs-punctuation\">)<\/span> <span class=\"hljs-operator\">%&gt;%<\/span> mutate<span class=\"hljs-punctuation\">(<\/span>date <span class=\"hljs-operator\">=<\/span> as.Date<span class=\"hljs-punctuation\">(<\/span>date<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">)<\/span><\/p>\n<p><span class=\"hljs-comment\"># hold out the last 28 days<\/span><br \/>\nh <span class=\"hljs-operator\">&lt;-<\/span> 28<br \/>\ndf_train <span class=\"hljs-operator\">&lt;-<\/span> df <span class=\"hljs-operator\">|&gt;<\/span> slice_head<span class=\"hljs-punctuation\">(<\/span>n <span class=\"hljs-operator\">=<\/span> n<span class=\"hljs-punctuation\">(<\/span><span class=\"hljs-punctuation\">)<\/span> <span class=\"hljs-operator\">&#8211;<\/span> h<span class=\"hljs-punctuation\">)<\/span><br \/>\ndf_test <span class=\"hljs-operator\">&lt;-<\/span> df <span class=\"hljs-operator\">|&gt;<\/span> slice_tail<span class=\"hljs-punctuation\">(<\/span>n <span class=\"hljs-operator\">=<\/span> h<span class=\"hljs-punctuation\">)<\/span><\/p>\n<p><span class=\"hljs-comment\"># weekly seasonality -&gt; frequency = 7<\/span><br \/>\ny_train <span class=\"hljs-operator\">&lt;-<\/span> ts<span class=\"hljs-punctuation\">(<\/span>df_train<span class=\"hljs-operator\">$<\/span>orders<span class=\"hljs-punctuation\">,<\/span> frequency <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-number\">7<\/span><span class=\"hljs-punctuation\">)<\/span><br \/>\ny_full <span class=\"hljs-operator\">&lt;-<\/span> ts<span class=\"hljs-punctuation\">(<\/span>df<span class=\"hljs-operator\">$<\/span>orders<span class=\"hljs-punctuation\">,<\/span> frequency <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-number\">7<\/span><span class=\"hljs-punctuation\">)<\/span><\/p>\n<p><span class=\"hljs-comment\"># candidate external drivers (optional in some models)<\/span><br \/>\nx_train <span class=\"hljs-operator\">&lt;-<\/span> as.matrix<span class=\"hljs-punctuation\">(<\/span>df_train<span class=\"hljs-punctuation\">[<\/span><span class=\"hljs-punctuation\">,<\/span> <span class=\"hljs-built_in\">c<\/span><span class=\"hljs-punctuation\">(<\/span><span class=\"hljs-string\">&#8220;promo_flag&#8221;<\/span><span class=\"hljs-punctuation\">,<\/span><span class=\"hljs-string\">&#8220;avg_temp_f&#8221;<\/span><span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">]<\/span><span class=\"hljs-punctuation\">)<\/span><br \/>\nx_test <span class=\"hljs-operator\">&lt;-<\/span> as.matrix<span class=\"hljs-punctuation\">(<\/span>df_test<span class=\"hljs-punctuation\">[<\/span><span class=\"hljs-punctuation\">,<\/span> <span class=\"hljs-built_in\">c<\/span><span class=\"hljs-punctuation\">(<\/span><span class=\"hljs-string\">&#8220;promo_flag&#8221;<\/span><span class=\"hljs-punctuation\">,<\/span><span class=\"hljs-string\">&#8220;avg_temp_f&#8221;<\/span><span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">]<\/span><span class=\"hljs-punctuation\">)<\/span><\/p>\n<p>ggplot<span class=\"hljs-punctuation\">(<\/span>df<span class=\"hljs-punctuation\">,<\/span> aes<span class=\"hljs-punctuation\">(<\/span>date<span class=\"hljs-punctuation\">,<\/span> orders<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">)<\/span> <span class=\"hljs-operator\">+<\/span> geom_line<span class=\"hljs-punctuation\">(<\/span><span class=\"hljs-punctuation\">)<\/span><\/p>\n<\/div>\n<\/div>\n<h2 data-start=\"1334\" data-end=\"1394\"><strong data-start=\"1337\" data-end=\"1394\">10.2 Baselines: na\u00efve, seasonal na\u00efve, moving average<\/strong><\/h2>\n<p data-start=\"1395\" data-end=\"1495\">Baselines are simple \u201cno-frills\u201d forecasts. They set the minimum that more complex models must beat.<\/p>\n<ul data-start=\"1496\" data-end=\"1752\">\n<li data-start=\"1496\" data-end=\"1559\">\n<p data-start=\"1498\" data-end=\"1559\">Na\u00efve: tomorrow equals today. Good when series wander slowly.<\/p>\n<\/li>\n<li data-start=\"1560\" data-end=\"1652\">\n<p data-start=\"1562\" data-end=\"1652\">Seasonal na\u00efve: next Monday equals last Monday. Strong when day-of-week patterns dominate.<\/p>\n<\/li>\n<li data-start=\"1653\" data-end=\"1752\">\n<p data-start=\"1655\" data-end=\"1752\">Moving average: smooths noise to show the local level but does not project seasonality by itself.<\/p>\n<\/li>\n<\/ul>\n<p data-start=\"1754\" data-end=\"1759\"><strong data-start=\"1754\" data-end=\"1759\">R<\/strong><\/p>\n<div class=\"contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary\">\n<div class=\"sticky top-9\">\n<div class=\"absolute end-0 bottom-0 flex h-9 items-center pe-2\">\n<div class=\"bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs\"><span class=\"\" data-state=\"closed\"><\/span><\/div>\n<\/div>\n<\/div>\n<div class=\"overflow-y-auto p-4\" dir=\"ltr\"><span style=\"font-size: 12pt\"><code class=\"whitespace-pre! language-r\"><code class=\"whitespace-pre! language-r\">fc_naive  <span class=\"hljs-operator\">&lt;-<\/span> naive<span class=\"hljs-punctuation\">(<\/span>y_train<span class=\"hljs-punctuation\">,<\/span>  h <span class=\"hljs-operator\">=<\/span> h<span class=\"hljs-punctuation\">)<\/span><br \/>\nfc_snaive <span class=\"hljs-operator\">&lt;-<\/span> snaive<span class=\"hljs-punctuation\">(<\/span>y_train<span class=\"hljs-punctuation\">,<\/span> h <span class=\"hljs-operator\">=<\/span> h<span class=\"hljs-punctuation\">)<\/span>  <span class=\"hljs-comment\"># respects weekly pattern<\/span><\/code><\/code>autoplot<span class=\"hljs-punctuation\">(<\/span>y_full<span class=\"hljs-punctuation\">)<\/span> <span class=\"hljs-operator\">+<\/span><\/span><br \/>\n<span style=\"font-size: 12pt\">autolayer<span class=\"hljs-punctuation\">(<\/span>fc_snaive<span class=\"hljs-punctuation\">,<\/span> series <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-string\">&#8220;Seasonal naive&#8221;<\/span><span class=\"hljs-punctuation\">,<\/span> PI <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-literal\">FALSE<\/span><span class=\"hljs-punctuation\">)<\/span> <span class=\"hljs-operator\">+<\/span><\/span><br \/>\n<span style=\"font-size: 12pt\">autolayer<span class=\"hljs-punctuation\">(<\/span>fc_naive<span class=\"hljs-punctuation\">,<\/span> series <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-string\">&#8220;Naive&#8221;<\/span><span class=\"hljs-punctuation\">,<\/span> PI <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-literal\">FALSE<\/span><span class=\"hljs-punctuation\">)<\/span><\/span><\/div>\n<\/div>\n<h2 data-start=\"2020\" data-end=\"2059\"><strong data-start=\"2023\" data-end=\"2059\">10.3 Exponential smoothing (ETS)<\/strong><\/h2>\n<p data-start=\"2060\" data-end=\"2383\">ETS breaks the series into level, trend, and seasonality. It adapts quickly when things change and is a common default for operational data. R can automatically pick the best combination of additive or multiplicative forms. After fitting, check residuals to confirm no leftover pattern.<\/p>\n<p data-start=\"2385\" data-end=\"2390\"><strong data-start=\"2385\" data-end=\"2390\">R<\/strong><\/p>\n<div class=\"contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary\">\n<div class=\"sticky top-9\">\n<div class=\"absolute end-0 bottom-0 flex h-9 items-center pe-2\">\n<div class=\"bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs\"><span class=\"\" data-state=\"closed\"><\/span><\/div>\n<\/div>\n<\/div>\n<div class=\"overflow-y-auto p-4\" dir=\"ltr\"><span style=\"font-size: 12pt\"><code class=\"whitespace-pre! language-r\"><code class=\"whitespace-pre! language-r\">fit_ets <span class=\"hljs-operator\">&lt;-<\/span> ets<span class=\"hljs-punctuation\">(<\/span>y_train<span class=\"hljs-punctuation\">)<\/span>              <span class=\"hljs-comment\"># auto-selects additive\/multiplicative forms<\/span><br \/>\nfc_ets  <span class=\"hljs-operator\">&lt;-<\/span> forecast<span class=\"hljs-punctuation\">(<\/span>fit_ets<span class=\"hljs-punctuation\">,<\/span> h <span class=\"hljs-operator\">=<\/span> h<span class=\"hljs-punctuation\">)<\/span><\/code><\/code>autoplot<span class=\"hljs-punctuation\">(<\/span>fc_ets<span class=\"hljs-punctuation\">)<\/span><\/span><br \/>\n<span style=\"font-size: 12pt\">checkresiduals<span class=\"hljs-punctuation\">(<\/span>fit_ets<span class=\"hljs-punctuation\">)<\/span> <span class=\"hljs-comment\"># want residuals ~ white noise<\/span><\/span><\/div>\n<\/div>\n<h2 data-start=\"2610\" data-end=\"2668\"><strong data-start=\"2613\" data-end=\"2668\">10.4 ARIMA and ARIMAX (with temperature and promos)<\/strong><\/h2>\n<p data-start=\"1725\" data-end=\"1849\">ARIMA uses past values and past errors to explain the series. Seasonal ARIMA adds repeating patterns (like weekly cycles).<\/p>\n<ul data-start=\"1850\" data-end=\"2038\">\n<li data-start=\"1850\" data-end=\"1904\">\n<p data-start=\"1852\" data-end=\"1904\"><strong data-start=\"1852\" data-end=\"1861\">ARIMA<\/strong>: relies only on the series\u2019 own history.<\/p>\n<\/li>\n<li data-start=\"1905\" data-end=\"2038\">\n<p data-start=\"1907\" data-end=\"2038\"><strong data-start=\"1907\" data-end=\"1917\">ARIMAX<\/strong>: adds external predictors (e.g., promos, temperature). This can sharpen forecasts when drivers explain part of demand.<\/p>\n<\/li>\n<\/ul>\n<p data-start=\"2040\" data-end=\"2150\">Residual checks confirm whether the model has captured the structure, or whether systematic patterns remain.<\/p>\n<p data-start=\"3001\" data-end=\"3006\"><strong data-start=\"3001\" data-end=\"3006\">R<\/strong><\/p>\n<div class=\"contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary\">\n<div class=\"sticky top-9\">\n<div class=\"absolute end-0 bottom-0 flex h-9 items-center pe-2\">\n<div class=\"bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs\"><span class=\"\" data-state=\"closed\"><\/span><\/div>\n<\/div>\n<\/div>\n<div class=\"overflow-y-auto p-4\" dir=\"ltr\"><span style=\"font-size: 12pt\"><code class=\"whitespace-pre! language-r\"><code class=\"whitespace-pre! language-r\"><span class=\"hljs-comment\"># ARIMA without drivers<\/span><br \/>\nfit_arima <span class=\"hljs-operator\">&lt;-<\/span> auto.arima<span class=\"hljs-punctuation\">(<\/span>y_train<span class=\"hljs-punctuation\">,<\/span> seasonal <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-literal\">TRUE<\/span><span class=\"hljs-punctuation\">)<\/span><br \/>\nfc_arima  <span class=\"hljs-operator\">&lt;-<\/span> forecast<span class=\"hljs-punctuation\">(<\/span>fit_arima<span class=\"hljs-punctuation\">,<\/span> h <span class=\"hljs-operator\">=<\/span> h<span class=\"hljs-punctuation\">)<\/span><\/code><\/code><span class=\"hljs-comment\"># ARIMAX with promo + temperature<\/span><\/span><br \/>\n<span style=\"font-size: 12pt\">fit_arimax <span class=\"hljs-operator\">&lt;-<\/span> auto.arima<span class=\"hljs-punctuation\">(<\/span>y_train<span class=\"hljs-punctuation\">,<\/span> xreg <span class=\"hljs-operator\">=<\/span> x_train<span class=\"hljs-punctuation\">,<\/span> seasonal <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-literal\">TRUE<\/span><span class=\"hljs-punctuation\">)<\/span><\/span><br \/>\n<span style=\"font-size: 12pt\">fc_arimax <span class=\"hljs-operator\">&lt;-<\/span> forecast<span class=\"hljs-punctuation\">(<\/span>fit_arimax<span class=\"hljs-punctuation\">,<\/span> xreg <span class=\"hljs-operator\">=<\/span> x_test<span class=\"hljs-punctuation\">,<\/span> h <span class=\"hljs-operator\">=<\/span> h<span class=\"hljs-punctuation\">)<\/span><\/span><span style=\"font-size: 12pt\"><code class=\"whitespace-pre! language-r\"><code class=\"whitespace-pre! language-r\"><\/code><\/code>checkresiduals<span class=\"hljs-punctuation\">(<\/span>fit_arima<span class=\"hljs-punctuation\">)<\/span><\/span><br \/>\n<span style=\"font-size: 12pt\">checkresiduals<span class=\"hljs-punctuation\">(<\/span>fit_arimax<span class=\"hljs-punctuation\">)<\/span><\/span><\/div>\n<\/div>\n<p data-start=\"3343\" data-end=\"3552\"><span style=\"font-size: 12pt\">Notes: Be careful not to \u201cpe<\/span>ek\u201d at the future when preparing drivers (xreg for the test window must be known at forecast time). If residuals still show weekly structure or long runs, revisit the specification.<\/p>\n<h2 data-start=\"3559\" data-end=\"3609\"><strong data-start=\"3562\" data-end=\"3609\">10.5 Accuracy comparison and rolling-origin<\/strong><\/h2>\n<p data-start=\"3610\" data-end=\"3671\">We compare competing models on the same holdout window using:<\/p>\n<ul data-start=\"3672\" data-end=\"3889\">\n<li data-start=\"3672\" data-end=\"3740\">\n<p data-start=\"3674\" data-end=\"3740\">MAE (average absolute error): easy to interpret in original units.<\/p>\n<\/li>\n<li data-start=\"3741\" data-end=\"3810\">\n<p data-start=\"3743\" data-end=\"3810\">RMSE (root mean square error): penalizes large misses more heavily.<\/p>\n<\/li>\n<li data-start=\"3811\" data-end=\"3889\">\n<p data-start=\"3813\" data-end=\"3889\">MAPE (percentage error): intuitive, but avoid when actuals can be near zero.<\/p>\n<\/li>\n<\/ul>\n<p data-start=\"3891\" data-end=\"4064\">A single split can be lucky. Rolling-origin cross-validation re-forecasts many times from expanding windows and averages the error, giving a more stable view of performance.<\/p>\n<p data-start=\"4066\" data-end=\"4071\"><strong data-start=\"4066\" data-end=\"4071\">R<\/strong><\/p>\n<div class=\"contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary\">\n<div class=\"sticky top-9\">\n<div class=\"absolute end-0 bottom-0 flex h-9 items-center pe-2\">\n<div class=\"bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs\"><span class=\"\" data-state=\"closed\"><\/span><\/div>\n<\/div>\n<\/div>\n<div class=\"overflow-y-auto p-4\" dir=\"ltr\">\n<p><span style=\"font-size: 12pt\"><code class=\"whitespace-pre! language-r\">library<span class=\"hljs-punctuation\">(<\/span>Metrics<span class=\"hljs-punctuation\">)<\/span><\/code><\/span><\/p>\n<p>y_test <span class=\"hljs-operator\">&lt;-<\/span> df_test<span class=\"hljs-operator\">$<\/span>orders<br \/>\ncompare <span class=\"hljs-operator\">&lt;-<\/span> dplyr<span class=\"hljs-operator\">::<\/span>bind_rows<span class=\"hljs-punctuation\">(<\/span><br \/>\ntibble<span class=\"hljs-operator\">::<\/span>tibble<span class=\"hljs-punctuation\">(<\/span>model<span class=\"hljs-operator\">=<\/span><span class=\"hljs-string\">&#8220;naive&#8221;<\/span><span class=\"hljs-punctuation\">,<\/span><br \/>\nMAE<span class=\"hljs-operator\">=<\/span>mae<span class=\"hljs-punctuation\">(<\/span>y_test<span class=\"hljs-punctuation\">,<\/span> fc_naive<span class=\"hljs-operator\">$<\/span>mean<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">,<\/span><br \/>\nRMSE<span class=\"hljs-operator\">=<\/span>rmse<span class=\"hljs-punctuation\">(<\/span>y_test<span class=\"hljs-punctuation\">,<\/span> fc_naive<span class=\"hljs-operator\">$<\/span>mean<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">,<\/span><br \/>\nMAPE<span class=\"hljs-operator\">=<\/span>Metrics<span class=\"hljs-operator\">::<\/span>mape<span class=\"hljs-punctuation\">(<\/span>y_test<span class=\"hljs-punctuation\">,<\/span> fc_naive<span class=\"hljs-operator\">$<\/span>mean<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">,<\/span><br \/>\ntibble<span class=\"hljs-operator\">::<\/span>tibble<span class=\"hljs-punctuation\">(<\/span>model<span class=\"hljs-operator\">=<\/span><span class=\"hljs-string\">&#8220;snaive&#8221;<\/span><span class=\"hljs-punctuation\">,<\/span><br \/>\nMAE<span class=\"hljs-operator\">=<\/span>mae<span class=\"hljs-punctuation\">(<\/span>y_test<span class=\"hljs-punctuation\">,<\/span> fc_snaive<span class=\"hljs-operator\">$<\/span>mean<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">,<\/span><br \/>\nRMSE<span class=\"hljs-operator\">=<\/span>rmse<span class=\"hljs-punctuation\">(<\/span>y_test<span class=\"hljs-punctuation\">,<\/span> fc_snaive<span class=\"hljs-operator\">$<\/span>mean<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">,<\/span><br \/>\nMAPE<span class=\"hljs-operator\">=<\/span>Metrics<span class=\"hljs-operator\">::<\/span>mape<span class=\"hljs-punctuation\">(<\/span>y_test<span class=\"hljs-punctuation\">,<\/span> fc_snaive<span class=\"hljs-operator\">$<\/span>mean<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">,<\/span><br \/>\ntibble<span class=\"hljs-operator\">::<\/span>tibble<span class=\"hljs-punctuation\">(<\/span>model<span class=\"hljs-operator\">=<\/span><span class=\"hljs-string\">&#8220;ETS&#8221;<\/span><span class=\"hljs-punctuation\">,<\/span><br \/>\nMAE<span class=\"hljs-operator\">=<\/span>mae<span class=\"hljs-punctuation\">(<\/span>y_test<span class=\"hljs-punctuation\">,<\/span> fc_ets<span class=\"hljs-operator\">$<\/span>mean<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">,<\/span><br \/>\nRMSE<span class=\"hljs-operator\">=<\/span>rmse<span class=\"hljs-punctuation\">(<\/span>y_test<span class=\"hljs-punctuation\">,<\/span> fc_ets<span class=\"hljs-operator\">$<\/span>mean<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">,<\/span><br \/>\nMAPE<span class=\"hljs-operator\">=<\/span>Metrics<span class=\"hljs-operator\">::<\/span>mape<span class=\"hljs-punctuation\">(<\/span>y_test<span class=\"hljs-punctuation\">,<\/span> fc_ets<span class=\"hljs-operator\">$<\/span>mean<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">,<\/span><br \/>\ntibble<span class=\"hljs-operator\">::<\/span>tibble<span class=\"hljs-punctuation\">(<\/span>model<span class=\"hljs-operator\">=<\/span><span class=\"hljs-string\">&#8220;ARIMA&#8221;<\/span><span class=\"hljs-punctuation\">,<\/span><br \/>\nMAE<span class=\"hljs-operator\">=<\/span>mae<span class=\"hljs-punctuation\">(<\/span>y_test<span class=\"hljs-punctuation\">,<\/span> fc_arima<span class=\"hljs-operator\">$<\/span>mean<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">,<\/span><br \/>\nRMSE<span class=\"hljs-operator\">=<\/span>rmse<span class=\"hljs-punctuation\">(<\/span>y_test<span class=\"hljs-punctuation\">,<\/span> fc_arima<span class=\"hljs-operator\">$<\/span>mean<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">,<\/span><br \/>\nMAPE<span class=\"hljs-operator\">=<\/span>Metrics<span class=\"hljs-operator\">::<\/span>mape<span class=\"hljs-punctuation\">(<\/span>y_test<span class=\"hljs-punctuation\">,<\/span> fc_arima<span class=\"hljs-operator\">$<\/span>mean<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">,<\/span><br \/>\ntibble<span class=\"hljs-operator\">::<\/span>tibble<span class=\"hljs-punctuation\">(<\/span>model<span class=\"hljs-operator\">=<\/span><span class=\"hljs-string\">&#8220;ARIMAX&#8221;<\/span><span class=\"hljs-punctuation\">,<\/span><br \/>\nMAE<span class=\"hljs-operator\">=<\/span>mae<span class=\"hljs-punctuation\">(<\/span>y_test<span class=\"hljs-punctuation\">,<\/span> fc_arimax<span class=\"hljs-operator\">$<\/span>mean<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">,<\/span><br \/>\nRMSE<span class=\"hljs-operator\">=<\/span>rmse<span class=\"hljs-punctuation\">(<\/span>y_test<span class=\"hljs-punctuation\">,<\/span> fc_arimax<span class=\"hljs-operator\">$<\/span>mean<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">,<\/span><br \/>\nMAPE<span class=\"hljs-operator\">=<\/span>Metrics<span class=\"hljs-operator\">::<\/span>mape<span class=\"hljs-punctuation\">(<\/span>y_test<span class=\"hljs-punctuation\">,<\/span> fc_arimax<span class=\"hljs-operator\">$<\/span>mean<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">)<\/span><br \/>\n<span class=\"hljs-punctuation\">)<\/span> <span class=\"hljs-operator\">|&gt;<\/span> arrange<span class=\"hljs-punctuation\">(<\/span>RMSE<span class=\"hljs-punctuation\">)<\/span><br \/>\ncompare<\/p>\n<\/div>\n<\/div>\n<p data-start=\"5145\" data-end=\"5184\">Rolling-origin example (7-day horizon):<\/p>\n<div class=\"contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary\">\n<div class=\"sticky top-9\">\n<div class=\"absolute end-0 bottom-0 flex h-9 items-center pe-2\">\n<div class=\"bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs\"><span class=\"\" data-state=\"closed\"><\/span><\/div>\n<\/div>\n<\/div>\n<div class=\"overflow-y-auto p-4\" dir=\"ltr\"><span style=\"font-size: 12pt\"><code class=\"whitespace-pre! language-r\"><code class=\"whitespace-pre! language-r\">e_snaive <span class=\"hljs-operator\">&lt;-<\/span> tsCV<span class=\"hljs-punctuation\">(<\/span>y_full<span class=\"hljs-punctuation\">,<\/span> <span class=\"hljs-keyword\">function<\/span><span class=\"hljs-punctuation\">(<\/span>y<span class=\"hljs-punctuation\">,<\/span> h<span class=\"hljs-punctuation\">)<\/span> forecast<span class=\"hljs-punctuation\">(<\/span>snaive<span class=\"hljs-punctuation\">(<\/span>y<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">,<\/span>     h<span class=\"hljs-operator\">=<\/span>h<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">,<\/span> h <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-number\">7<\/span><span class=\"hljs-punctuation\">)<\/span><br \/>\ne_arima  <span class=\"hljs-operator\">&lt;-<\/span> tsCV<span class=\"hljs-punctuation\">(<\/span>y_full<span class=\"hljs-punctuation\">,<\/span> <span class=\"hljs-keyword\">function<\/span><span class=\"hljs-punctuation\">(<\/span>y<span class=\"hljs-punctuation\">,<\/span> h<span class=\"hljs-punctuation\">)<\/span> forecast<span class=\"hljs-punctuation\">(<\/span>auto.arima<span class=\"hljs-punctuation\">(<\/span>y<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">,<\/span> h<span class=\"hljs-operator\">=<\/span>h<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">,<\/span> h <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-number\">7<\/span><span class=\"hljs-punctuation\">)<\/span><\/code><\/code><span class=\"hljs-built_in\">sqrt<\/span><span class=\"hljs-punctuation\">(<\/span>mean<span class=\"hljs-punctuation\">(<\/span>e_snaive<span class=\"hljs-operator\">^<\/span><span class=\"hljs-number\">2<\/span><span class=\"hljs-punctuation\">,<\/span> na.rm<span class=\"hljs-operator\">=<\/span><span class=\"hljs-literal\">TRUE<\/span><span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">)<\/span><\/span><br \/>\n<span style=\"font-size: 12pt\"><span class=\"hljs-built_in\">sqrt<\/span><span class=\"hljs-punctuation\">(<\/span>mean<span class=\"hljs-punctuation\">(<\/span>e_arima<span class=\"hljs-operator\">^<\/span><span class=\"hljs-number\">2<\/span><span class=\"hljs-punctuation\">,<\/span> na.rm<span class=\"hljs-operator\">=<\/span><span class=\"hljs-literal\">TRUE<\/span><span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">)<\/span><\/span><\/div>\n<\/div>\n<p data-start=\"5419\" data-end=\"5517\">Choose the simplest model that meets your accuracy target and leaves residuals looking like noise.<\/p>\n<h2 data-start=\"5524\" data-end=\"5577\"><strong data-start=\"5527\" data-end=\"5577\">10.6 Applied example: 28-day staffing plan (R)<\/strong><\/h2>\n<p data-start=\"2721\" data-end=\"2958\">Forecasts matter when they drive action. For Pemi Coffee Roasters, we use the chosen model (e.g., ETS or ARIMAX) to forecast 28 days of orders. Orders are converted into staff requirements using a simple rule (one staff per 40 orders).<\/p>\n<p data-start=\"2960\" data-end=\"2999\">The deliverable is a short memo with:<\/p>\n<ul data-start=\"3000\" data-end=\"3195\">\n<li data-start=\"3000\" data-end=\"3035\">\n<p data-start=\"3002\" data-end=\"3035\">The forecast horizon (28 days).<\/p>\n<\/li>\n<li data-start=\"3036\" data-end=\"3081\">\n<p data-start=\"3038\" data-end=\"3081\">The chosen model and why it was selected.<\/p>\n<\/li>\n<li data-start=\"3082\" data-end=\"3110\">\n<p data-start=\"3084\" data-end=\"3110\">A staffing table by day.<\/p>\n<\/li>\n<li data-start=\"3111\" data-end=\"3195\">\n<p data-start=\"3113\" data-end=\"3195\">Any flagged risks (e.g., promotions or heat waves) and one suggested mitigation.<\/p>\n<\/li>\n<\/ul>\n<p data-start=\"5906\" data-end=\"5911\"><strong data-start=\"5906\" data-end=\"5911\">R<\/strong><\/p>\n<div class=\"contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary\">\n<div class=\"sticky top-9\">\n<div class=\"absolute end-0 bottom-0 flex h-9 items-center pe-2\">\n<div class=\"bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs\"><span class=\"\" data-state=\"closed\"><\/span><\/div>\n<\/div>\n<\/div>\n<div class=\"overflow-y-auto p-4\" dir=\"ltr\"><span style=\"font-size: 12pt\"><code class=\"whitespace-pre! language-r\"><code class=\"whitespace-pre! language-r\">best <span class=\"hljs-operator\">&lt;-<\/span> fit_arimax   <span class=\"hljs-comment\"># or fit_ets \/ fit_arima based on compare + residuals<\/span><br \/>\nfc   <span class=\"hljs-operator\">&lt;-<\/span> forecast<span class=\"hljs-punctuation\">(<\/span>best<span class=\"hljs-punctuation\">,<\/span> xreg <span class=\"hljs-operator\">=<\/span> x_test<span class=\"hljs-punctuation\">,<\/span> h <span class=\"hljs-operator\">=<\/span> h<span class=\"hljs-punctuation\">)<\/span><\/code><\/code>staff_per_day <span class=\"hljs-operator\">&lt;-<\/span> <span class=\"hljs-built_in\">ceiling<\/span><span class=\"hljs-punctuation\">(<\/span><span class=\"hljs-built_in\">as.numeric<\/span><span class=\"hljs-punctuation\">(<\/span>fc<span class=\"hljs-operator\">$<\/span>mean<span class=\"hljs-punctuation\">)<\/span> <span class=\"hljs-operator\">\/<\/span> <span class=\"hljs-number\">40<\/span><span class=\"hljs-punctuation\">)<\/span><\/span><br \/>\n<span style=\"font-size: 12pt\">out <span class=\"hljs-operator\">&lt;-<\/span> tibble<span class=\"hljs-operator\">::<\/span>tibble<span class=\"hljs-punctuation\">(<\/span><\/span><br \/>\n<span style=\"font-size: 12pt\">date <span class=\"hljs-operator\">=<\/span> tail<span class=\"hljs-punctuation\">(<\/span>df<span class=\"hljs-operator\">$<\/span>date<span class=\"hljs-punctuation\">,<\/span> <span class=\"hljs-number\">1<\/span><span class=\"hljs-punctuation\">)<\/span> <span class=\"hljs-operator\">+<\/span> <span class=\"hljs-number\">1<\/span><span class=\"hljs-operator\">:<\/span>h<span class=\"hljs-punctuation\">,<\/span><\/span><br \/>\n<span style=\"font-size: 12pt\">forecast_orders <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-built_in\">as.numeric<\/span><span class=\"hljs-punctuation\">(<\/span>fc<span class=\"hljs-operator\">$<\/span>mean<span class=\"hljs-punctuation\">)<\/span><span class=\"hljs-punctuation\">,<\/span><\/span><br \/>\n<span style=\"font-size: 12pt\">staff_needed <span class=\"hljs-operator\">=<\/span> staff_per_day<\/span><br \/>\n<span class=\"hljs-punctuation\" style=\"font-size: 12pt\">)<\/span><br \/>\nprint<span class=\"hljs-punctuation\">(<\/span>out<span class=\"hljs-punctuation\">)<\/span><\/div>\n<\/div>\n<p data-start=\"6248\" data-end=\"6411\">Memo pointers: state the horizon, the chosen model and why, attach the daily staffing table, flag any operational risks (e.g., a promo cluster) and one mitigation.<\/p>\n<div class=\"textbox textbox--key-takeaways\">\n<header class=\"textbox__header\">\n<p class=\"textbox__title\">Key Takeaways<\/p>\n<\/header>\n<div class=\"textbox__content\">\n<ul>\n<li data-start=\"82\" data-end=\"179\">\n<p data-start=\"84\" data-end=\"179\">Forecasting projects future demand; predictive analytics adds drivers like promos or weather.<\/p>\n<\/li>\n<li data-start=\"180\" data-end=\"250\">\n<p data-start=\"182\" data-end=\"250\">Define the question, set frequency, and hold out data for testing.<\/p>\n<\/li>\n<li data-start=\"251\" data-end=\"323\">\n<p data-start=\"253\" data-end=\"323\">Baselines (na\u00efve, seasonal na\u00efve, moving average) are the benchmark.<\/p>\n<\/li>\n<li data-start=\"324\" data-end=\"400\">\n<p data-start=\"326\" data-end=\"400\">ETS, ARIMA, and ARIMAX capture trend, seasonality, and external drivers.<\/p>\n<\/li>\n<li data-start=\"401\" data-end=\"477\">\n<p data-start=\"403\" data-end=\"477\">Accuracy checks use MAE, RMSE, and MAPE, plus rolling-origin validation.<\/p>\n<\/li>\n<li data-start=\"478\" data-end=\"546\">\n<p data-start=\"480\" data-end=\"546\">Forecasts should guide concrete actions, such as staffing plans.<\/p>\n<\/li>\n<\/ul>\n<\/div>\n<\/div>\n<h2>Chapter 10 References<\/h2>\n<p data-start=\"253\" data-end=\"354\">Microsoft. (n.d.). <em data-start=\"272\" data-end=\"305\">Forecasting functions in Excel.<\/em> Microsoft. <a data-start=\"317\" data-end=\"352\" rel=\"noopener\" target=\"_new\" class=\"decorated-link cursor-pointer\" href=\"https:\/\/support.microsoft.com\/excel\">https:\/\/support.microsoft.com\/excel<span aria-hidden=\"true\" class=\"ms-0.5 inline-block align-middle leading-none\"><\/span><\/a><\/p>\n<p data-start=\"357\" data-end=\"504\">R Core Team. (2023). <em data-start=\"378\" data-end=\"436\">R: A language and environment for statistical computing.<\/em> R Foundation for Statistical Computing. <a data-start=\"477\" data-end=\"502\" rel=\"noopener\" target=\"_new\" class=\"decorated-link cursor-pointer\" href=\"https:\/\/www.r-project.org\">https:\/\/www.r-project.org<span aria-hidden=\"true\" class=\"ms-0.5 inline-block align-middle leading-none\"><\/span><\/a><\/p>\n<p data-start=\"507\" data-end=\"636\">Hyndman, R. J., &amp; Athanasopoulos, G. (2021). <em data-start=\"552\" data-end=\"590\">Forecasting: Principles and practice<\/em> (3rd ed.). OTexts. <a data-start=\"610\" data-end=\"634\" rel=\"noopener\" target=\"_new\" class=\"decorated-link cursor-pointer\" href=\"https:\/\/otexts.com\/fpp3\/\">https:\/\/otexts.com\/fpp3\/<span aria-hidden=\"true\" class=\"ms-0.5 inline-block align-middle leading-none\"><\/span><\/a><\/p>\n<p data-start=\"639\" data-end=\"790\">Wickham, H., &amp; Grolemund, G. (2017). <em data-start=\"676\" data-end=\"749\">R for data science: Import, tidy, transform, visualize, and model data.<\/em> O\u2019Reilly Media. <a data-start=\"766\" data-end=\"788\" rel=\"noopener\" target=\"_new\" class=\"decorated-link cursor-pointer\" href=\"https:\/\/r4ds.had.co.nz\">https:\/\/r4ds.had.co.nz<\/a><\/p>\n<p>&nbsp;<\/p>\n","protected":false},"author":1,"menu_order":2,"template":"","meta":{"pb_show_title":"on","pb_short_title":"","pb_subtitle":"","pb_authors":[],"pb_section_license":""},"chapter-type":[],"contributor":[],"license":[],"class_list":["post-56","chapter","type-chapter","status-publish","hentry"],"part":51,"_links":{"self":[{"href":"https:\/\/openbooks.spmvv.ac.in\/businessopsanalytics\/wp-json\/pressbooks\/v2\/chapters\/56","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/openbooks.spmvv.ac.in\/businessopsanalytics\/wp-json\/pressbooks\/v2\/chapters"}],"about":[{"href":"https:\/\/openbooks.spmvv.ac.in\/businessopsanalytics\/wp-json\/wp\/v2\/types\/chapter"}],"author":[{"embeddable":true,"href":"https:\/\/openbooks.spmvv.ac.in\/businessopsanalytics\/wp-json\/wp\/v2\/users\/1"}],"version-history":[{"count":1,"href":"https:\/\/openbooks.spmvv.ac.in\/businessopsanalytics\/wp-json\/pressbooks\/v2\/chapters\/56\/revisions"}],"predecessor-version":[{"id":57,"href":"https:\/\/openbooks.spmvv.ac.in\/businessopsanalytics\/wp-json\/pressbooks\/v2\/chapters\/56\/revisions\/57"}],"part":[{"href":"https:\/\/openbooks.spmvv.ac.in\/businessopsanalytics\/wp-json\/pressbooks\/v2\/parts\/51"}],"metadata":[{"href":"https:\/\/openbooks.spmvv.ac.in\/businessopsanalytics\/wp-json\/pressbooks\/v2\/chapters\/56\/metadata\/"}],"wp:attachment":[{"href":"https:\/\/openbooks.spmvv.ac.in\/businessopsanalytics\/wp-json\/wp\/v2\/media?parent=56"}],"wp:term":[{"taxonomy":"chapter-type","embeddable":true,"href":"https:\/\/openbooks.spmvv.ac.in\/businessopsanalytics\/wp-json\/pressbooks\/v2\/chapter-type?post=56"},{"taxonomy":"contributor","embeddable":true,"href":"https:\/\/openbooks.spmvv.ac.in\/businessopsanalytics\/wp-json\/wp\/v2\/contributor?post=56"},{"taxonomy":"license","embeddable":true,"href":"https:\/\/openbooks.spmvv.ac.in\/businessopsanalytics\/wp-json\/wp\/v2\/license?post=56"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}