Post

Time Series Forecasting in Python: A Practical Guide to ARIMA and Prophet

Time series forecasting in Python means using past observations, recorded at regular intervals, to predict future values with a quantified range of uncertainty. The two most widely used approaches are ARIMA/SARIMA from the statsmodels

Uncategorized
Time series forecasting in Python with ARIMA and Prophet, showing a forecast line and 95% prediction interval

Time series forecasting in Python means using past observations, recorded at regular intervals, to predict future values with a quantified range of uncertainty. The two most widely used approaches are ARIMA/SARIMA from the statsmodels library and Prophet from Meta’s open-source prophet package. A reliable workflow has five steps: prepare the series with a proper date index, explore its trend and seasonality, build a simple baseline, fit ARIMA and Prophet, and compare them with time-based backtesting. Keep a model only if it beats the baseline, and always report prediction intervals, not just a single line.

This guide walks through each step with working code on one public dataset. It explains how to judge the results, and what it takes to turn a notebook forecast into something a sales, finance or operations team can rely on.

In this guide

  1. What is time series forecasting?
  2. ARIMA vs Prophet: when to use each
  3. Set up your Python environment
  4. Prepare your time series data
  5. Explore trend, seasonality and stationarity
  6. Start with a baseline forecast
  7. How to build an ARIMA forecast in Python
  8. How to build a Prophet forecast in Python
  9. How to evaluate time series forecasts
  10. Comparing ARIMA and Prophet on the same data
  11. Which approach fits your business?
  12. From notebook to production
  13. Common mistakes
  14. When to bring in a forecasting expert
  15. Frequently asked questions

What Is Time Series Forecasting?

A time series is a sequence of values recorded at regular intervals: daily orders, weekly website sessions, monthly revenue, quarterly demand. Forecasting uses the patterns in that history to estimate what comes next.

Most business series combine three components:

  • Trend: a long-run rise or fall, such as steady revenue growth.
  • Seasonality: a pattern that repeats over a fixed period, such as higher retail sales every December or lower B2B activity every August.
  • Noise: irregular variation that no model can explain.

A good forecast captures the trend and seasonality, gives an honest range for the noise, and is checked against what actually happened. Forecasting is one part of predictive analytics; for the wider picture of how predictive models fit into business decisions, see our introduction to machine learning for business.

ARIMA vs Prophet: When to Use Each

ARIMA and Prophet take different routes to the same goal. ARIMA (AutoRegressive Integrated Moving Average) models the series using its own past values and past errors, after differencing to remove trend; SARIMA adds seasonal terms. Prophet fits a regression with a flexible trend, Fourier-based seasonal components and optional holiday effects (Taylor & Letham, 2018).

Table 1. ARIMA vs Prophet at a Glance

CriterionARIMA / SARIMAProphet
Model typeStatistical model of autocorrelation, after differencingAdditive (or multiplicative) regression: trend + seasonality + holidays
Data needsRegular, gap-free series; works on shorter historiesBenefits from several seasonal cycles; tolerates gaps
SeasonalityOne seasonal period per model (e.g., 12 for monthly)Several at once (yearly, weekly, daily)
Holidays and eventsOnly through exogenous variables (SARIMAX)Built-in holiday and event effects
Missing data and outliersMust be handled before fittingHandles missing dates; outliers still distort fits
InterpretabilityClear coefficients and residual diagnosticsClear component plots (trend, seasonality, holidays)
Tuning effortChoosing p, d, q, P, D, Q needs care or automationSensible defaults; tune changepoints and seasonality
SpeedFast for a single seriesFast; scales well to many series
Best forStable series with clear autocorrelation and one seasonal patternBusiness series with strong seasonality, holidays and trend changes
Watch out forMis-specified orders, over-differencing, non-constant varianceOver-flexible trends that extrapolate badly

Neither method is universally better. On a given dataset, the only fair answer comes from testing both against a simple baseline, which this guide shows you how to do.

Set Up Your Python Environment

Install the libraries used in this guide:

pip install pandas numpy matplotlib statsmodels prophet pmdarima scikit-learn

The code uses current APIs: from prophet import Prophet (the package was renamed from fbprophet) and statsmodels.tsa.arima.model.ARIMA or statsmodels.tsa.statespace.sarimax.SARIMAX (the older statsmodels.tsa.arima_model.ARIMA class has been removed). If pmdarima fails to import, it is usually a version mismatch with NumPy; install it in a fresh virtual environment or skip the automatic order-selection step.

If you are new to pandas and plotting, start with our guide to Python for data analysis.

Prepare Your Time Series Data

Every example in this guide uses the same public dataset, so you can reproduce each step: the Mauna Loa atmospheric CO₂ series bundled with statsmodels. It contains weekly measurements from March 1958 to December 2001 from the Scripps flask network, and the statsmodels documentation describes it as public domain. It has a clear upward trend, strong yearly seasonality and some missing weeks, which makes it a good stand-in for a business series such as monthly revenue or demand. Swap in your own data by replacing the loading step.

Load and resample the data

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import statsmodels.api as sm

# Weekly CO2 readings with a DatetimeIndex
co2 = sm.datasets.co2.load_pandas().data

# Resample to monthly averages (month-start frequency)
y = co2["co2"].resample("MS").mean()

print(y.isna().sum(), "missing months")
y = y.interpolate()          # fill any gaps after resampling
y = y.asfreq("MS")         # make the frequency explicit for the models

For your own data, the same three rules apply:

  1. Use a proper DatetimeIndex with pd.to_datetime(), sorted in time order.
  2. Fix the frequency. Resample to the level you will forecast (daily, weekly, monthly) and make sure every period exists. Missing periods silently break ARIMA.
  3. Fill gaps deliberately. Interpolate short gaps, but investigate long ones: a missing month of sales is a data problem, not a modelling problem.

Also check for one-off spikes (a bulk order, a system outage, a promotion) and decide whether the model should learn from them. Poor input data is the most common reason forecasts fail; our guide to data quality management covers how to catch these problems early.

Real company data is rarely this tidy. If your sales, CRM or finance exports need cleaning before they can be forecast, our data science consulting team offers a free data review to tell you what is usable and what needs fixing.

Split by time, never at random

Hold out the most recent periods as a test set. Here, the last 24 months are kept aside to judge every model:

horizon = 24
train, test = y.iloc[:-horizon], y.iloc[-horizon:]
print(train.index.min(), train.index.max(), test.index.min(), test.index.max())

Shuffling or random splitting leaks future information into training and makes any model look better than it is.

Explore the Series: Trend, Seasonality and Stationarity

Plot and decompose

from statsmodels.tsa.seasonal import STL

train.plot(figsize=(10, 4), title="Monthly CO2 (training data)")
plt.show()

stl = STL(train, period=12).fit()
stl.plot()
plt.show()

STL splits the series into trend, seasonal and remainder components. What to look for: a smooth trend, a seasonal pattern that repeats every 12 months, and a remainder with no obvious structure. If the seasonal swings grow as the level grows, consider a log transform or a multiplicative model.

Check stationarity

ARIMA assumes the series (after differencing) is stationary: its mean and variance do not drift over time. Two complementary tests help:

from statsmodels.tsa.stattools import adfuller, kpss

adf_p = adfuller(train)[1]
kpss_p = kpss(train, regression="c", nlags="auto")[1]
print(f"ADF p = {adf_p:.3f}   KPSS p = {kpss_p:.3f}")

# After one regular and one seasonal difference
diffed = train.diff().diff(12).dropna()
print(f"ADF p (differenced) = {adfuller(diffed)[1]:.3f}")

The tests have opposite null hypotheses. The ADF test’s null is that the series has a unit root (non-stationary), so a small p value supports stationarity. The KPSS test’s null is that the series is stationary, so a small p value suggests it is not. What to look for: on a trending, seasonal series like this one, the raw data should look non-stationary on both tests, and the differenced series should look stationary. The number of differences you needed becomes d (regular) and D (seasonal) in the model. KPSS may print a warning when the p value falls outside its lookup table; the direction of the result is still usable.

Read the ACF and PACF

from statsmodels.graphics.tsaplots import plot_acf, plot_pacf

fig, axes = plt.subplots(1, 2, figsize=(12, 4))
plot_acf(diffed, lags=36, ax=axes[0])
plot_pacf(diffed, lags=36, ax=axes[1], method="ywm")
plt.show()

The autocorrelation (ACF) and partial autocorrelation (PACF) plots of the differenced series suggest starting values for the model orders. Significant spikes at lags 1–2 point to non-seasonal AR or MA terms; a spike at lag 12 points to a seasonal term. Treat these as starting points, not answers.

Start With a Baseline Forecast

A forecasting model is only useful if it beats a simple rule. Two baselines should be in every project:

  • Naive: every future value equals the last observed value.
  • Seasonal naive: every future value equals the value from the same month last year.
naive = pd.Series(train.iloc[-1], index=test.index)
seasonal_naive = pd.Series(np.resize(train.iloc[-12:].values, len(test)), index=test.index)

def evaluate(actual, pred, train=train, m=12):
    err = actual - pred
    mae = np.mean(np.abs(err))
    rmse = np.sqrt(np.mean(err ** 2))
    mape = np.mean(np.abs(err / actual)) * 100
    scale = np.mean(np.abs(train.diff(m).dropna()))   # in-sample seasonal naive error
    mase = mae / scale
    return pd.Series({"MAE": mae, "RMSE": rmse, "MAPE %": mape, "MASE": mase})

results = {"Naive": evaluate(test, naive),
           "Seasonal naive": evaluate(test, seasonal_naive)}
pd.DataFrame(results).T.round(3)

The seasonal naive forecast is the benchmark to beat for any seasonal series. If ARIMA or Prophet cannot outperform it on your data, the simpler rule is the better choice, and that is a useful finding in itself.

How to Build an ARIMA Forecast in Python

Choose p, d, q (and seasonal P, D, Q, m)

A seasonal ARIMA model is written SARIMA(p, d, q)(P, D, Q)m:

  • p: number of autoregressive terms (how many past values the model uses).
  • d: number of regular differences needed to remove the trend.
  • q: number of moving-average terms (how many past forecast errors the model uses).
  • P, D, Q: the seasonal equivalents, applied at the seasonal lag.
  • m: the length of the season (12 for monthly data with a yearly pattern, 7 for daily data with a weekly pattern).

The stationarity tests suggested d = 1 and D = 1. A common, well-tested starting point for monthly seasonal data is SARIMA(1, 1, 1)(0, 1, 1)12. Compare a few candidates by AIC (lower is better) and by out-of-sample error, rather than trusting any single rule.

Fit SARIMA With statsmodels

from statsmodels.tsa.statespace.sarimax import SARIMAX

sarima = SARIMAX(train, order=(1, 1, 1), seasonal_order=(0, 1, 1, 12))
sarima_fit = sarima.fit(disp=False)
print(sarima_fit.summary())

The summary shows each coefficient with its standard error and p value, plus the AIC. What to look for: coefficients that are clearly different from zero, and no warnings about non-convergence. If a term is far from significant, try a simpler order and compare the AIC.

Check the Residuals

A good model leaves residuals that look like random noise.

from statsmodels.stats.diagnostic import acorr_ljungbox

sarima_fit.plot_diagnostics(figsize=(10, 8))
plt.show()

# Skip the first 13 residuals, which are affected by differencing
print(acorr_ljungbox(sarima_fit.resid.iloc[13:], lags=[12, 24]))

What to look for: residuals centred on zero with no pattern over time, a roughly normal histogram, and no significant autocorrelation. In the Ljung-Box output, large p values (above .05) mean no remaining autocorrelation was detected. Small p values mean the model has missed some structure, so revisit the orders.

Forecast With Prediction Intervals

fc = sarima_fit.get_forecast(steps=len(test))
sarima_pred = fc.predicted_mean
sarima_ci = fc.conf_int(alpha=0.05)      # 95% prediction interval

ax = train.iloc[-60:].plot(figsize=(10, 4), label="Train")
test.plot(ax=ax, label="Actual")
sarima_pred.plot(ax=ax, label="SARIMA forecast")
ax.fill_between(sarima_ci.index, sarima_ci.iloc[:, 0], sarima_ci.iloc[:, 1], alpha=0.2)
ax.legend(); plt.show()

results["SARIMA(1,1,1)(0,1,1)12"] = evaluate(test, sarima_pred)

A 95% prediction interval is the range the model expects the actual value to fall within 95% of the time, if the model’s assumptions hold. Intervals widen as the horizon grows, because uncertainty compounds. For planning, the interval is often more useful than the single line: it tells a finance or operations team how much buffer to hold.

Automatic Order Selection With auto_arima

Searching orders by hand is slow when you have many series. pmdarima.auto_arima tests combinations and returns the one with the best information criterion:

import pmdarima as pm

auto = pm.auto_arima(train, seasonal=True, m=12,
                     stepwise=True, information_criterion="aic",
                     suppress_warnings=True, error_action="ignore")
print(auto.order, auto.seasonal_order)

auto_pred = pd.Series(np.asarray(auto.predict(n_periods=len(test))), index=test.index)
results["auto_arima"] = evaluate(test, auto_pred)

Treat the selected order as a strong suggestion, not a final answer: still check the residuals and the out-of-sample error. If pmdarima will not install alongside your NumPy version, a short loop over a handful of SARIMAX orders, compared by AIC, achieves the same thing.

To include known drivers such as price, promotions or marketing spend, pass them as exog to SARIMAX (for both fitting and forecasting). You will need future values of those drivers to forecast.

How to Build a Prophet Forecast in Python

Format the Data (ds and y)

Prophet expects a DataFrame with two columns: ds (the date) and y (the value).

from prophet import Prophet

df_train = train.reset_index()
df_train.columns = ["ds", "y"]

Fit the Model

prophet_model = Prophet(yearly_seasonality=True,
                        weekly_seasonality=False,
                        daily_seasonality=False,
                        interval_width=0.95)
prophet_model.fit(df_train)

future = prophet_model.make_future_dataframe(periods=len(test), freq="MS")
forecast = prophet_model.predict(future)

prophet_pred = forecast.set_index("ds")["yhat"].iloc[-len(test):]
prophet_pred.index = test.index
results["Prophet"] = evaluate(test, prophet_pred)

prophet_model.plot(forecast); plt.show()
prophet_model.plot_components(forecast); plt.show()

Weekly and daily seasonality are switched off because the data are monthly. yhat_lower and yhat_upper in the forecast DataFrame hold the 95% interval. What to look for in the component plot: a smooth trend and a stable yearly pattern. A trend that bends sharply near the end of the history is a warning sign that it may extrapolate badly.

Seasonality, Holidays and Changepoints

The settings that matter most for business data:

  • seasonality_mode="multiplicative" when seasonal swings grow with the level of the series (common in sales).
  • changepoint_prior_scale controls how flexible the trend is. The default is 0.05; raise it if the trend misses real shifts, lower it if the trend chases noise.
  • Holidays: for daily or weekly data, prophet_model.add_country_holidays(country_name="US") adds a country’s public holidays, and you can pass your own events (product launches, promotions, Black Friday) as a holidays DataFrame.

Add External Regressors

If a known driver affects the series, add it as a regressor before fitting:

# Example only: requires a 'promo' column in both df_train and future
m = Prophet()
m.add_regressor("promo")
# m.fit(df_train); forecast = m.predict(future)

As with SARIMAX, you must supply future values of every regressor for the forecast period.

How to Evaluate Time Series Forecasts

One train/test split can be misleading: a model may get lucky on one particular period. Rolling-origin backtesting repeats the test several times, each time training on data up to a cut-off and forecasting the next block.

Table 2. Forecast Accuracy Metrics Explained

MetricWhat it measuresFormula (plain text)When to usePitfall
MAEAverage size of errors, in the data’s unitsmean of the absolute errorsDefault choice; easy to explain (“off by 120 units a month on average”)Not comparable across series of different scales
RMSETypical error size, penalising large misses moresquare root of the mean squared errorWhen large errors are especially costlySensitive to a few big misses
MAPEAverage error as a percentage of actual valuesmean of absolute error divided by actual, × 100Comparing series of different scales; reporting to non-technical teamsUndefined or explosive when actuals are zero or near zero
sMAPEPercentage error using the average of actual and forecastmean of absolute error divided by the mean of absolute actual and forecast, × 100Data with small values where MAPE explodesHarder to interpret; not symmetric in practice
MASEError relative to a seasonal naive forecastMAE divided by the in-sample seasonal naive MAEJudging whether a model beats the baseline (below 1 = better)Needs enough history to compute the scale

Backtesting ARIMA

from sklearn.model_selection import TimeSeriesSplit

tscv = TimeSeriesSplit(n_splits=5, test_size=12)
fold_mae = []
for train_idx, val_idx in tscv.split(train):
    tr, val = train.iloc[train_idx], train.iloc[val_idx]
    fit = SARIMAX(tr, order=(1, 1, 1), seasonal_order=(0, 1, 1, 12)).fit(disp=False)
    pred = fit.forecast(steps=len(val))
    fold_mae.append(np.mean(np.abs(val.values - pred.values)))

print("SARIMA backtest MAE by fold:", np.round(fold_mae, 3))
print("Mean:", round(np.mean(fold_mae), 3))

Each fold trains on an expanding window and forecasts the next 12 months, all within the training data, so the final test set stays untouched.

Cross-Validating Prophet

Prophet has built-in tools for the same job:

from prophet.diagnostics import cross_validation, performance_metrics

cv = cross_validation(prophet_model, initial="7300 days",
                      period="365 days", horizon="730 days")
print(performance_metrics(cv)[["horizon", "mae", "rmse", "mape", "coverage"]].tail())

initial is the first training window, period is how far the cut-off moves each time, and horizon is how far ahead each forecast reaches. The coverage column shows how often actual values fell inside the prediction interval; for a 95% interval, coverage well below 0.95 means the model is overconfident.

ARIMA vs Prophet Results on the Same Data

With every model evaluated on the same 24-month test set, one table answers the question that matters:

comparison = pd.DataFrame(results).T.round(3).sort_values("MASE")
print(comparison)

ax = test.plot(figsize=(10, 4), label="Actual", color="black")
sarima_pred.plot(ax=ax, label="SARIMA")
prophet_pred.plot(ax=ax, label="Prophet")
seasonal_naive.plot(ax=ax, label="Seasonal naive", linestyle="--")
ax.fill_between(sarima_ci.index, sarima_ci.iloc[:, 0], sarima_ci.iloc[:, 1], alpha=0.15)
ax.legend(); plt.show()

How to read the comparison:

  • Any model with a MASE above 1 is losing to the seasonal naive baseline on this test period. Do not use it without a good reason.
  • Look at the backtest averages, not just the single test set. A model that wins one period but loses most folds is not reliable.
  • Check the intervals. A model with a slightly higher error but well-calibrated intervals is often more useful for planning than one with tight but overconfident intervals.
  • Prefer the simpler model when the difference is small. It is easier to explain, maintain and retrain.

On a smooth, strongly seasonal series like this one, both SARIMA and Prophet typically capture the trend and seasonality well, and the ranking can change with the test period. That is exactly why backtesting matters. On messy business data with promotions, holidays and structural breaks, the differences between methods are usually larger.

Not sure which model fits your data, or whether your forecast actually beats a simple baseline? Send us your data for a free data review, and we will tell you what is forecastable and which approach is worth building.

Which Forecasting Approach Fits Your Business?

Table 3. Which Forecasting Approach Fits Your Business Problem?

Business situationData you haveSuggested starting methodWhy
Monthly revenue for one business line3+ years of monthly totalsSeasonal naive, then SARIMAShort, stable series with one yearly pattern suit SARIMA
Daily e-commerce orders2+ years of daily data with promotions and holidaysProphet with holidays and promo regressorsHandles weekly and yearly seasonality plus events
Weekly demand for many productsHundreds of SKUs, some sparseSeasonal naive per SKU, then Prophet or ARIMA on high-volume SKUsAutomation matters; sparse items need simpler methods
Call-centre or staffing volumeHourly or daily historyProphet (multiple seasonalities)Daily and weekly cycles at the same time
Sales driven by price and marketing spendHistory plus future plans for those driversSARIMAX or Prophet with regressorsLets you test “what if” scenarios
Volatile series with frequent structural breaksShort or unstable historySimple baselines plus expert judgementComplex models overfit unstable data

If your goal is to understand past performance before forecasting it, our guide on how to analyze sales data is a good first step. When the patterns become more complex (many products, external drivers, several seasonal cycles), machine-learning models such as gradient boosting can also be tested, but they still need to beat the same baselines.

From Notebook to Production

A forecast that lives in a notebook helps no one. To make it useful:

  1. Automate the data feed. Pull the latest actuals from your database, CRM or accounting system on a schedule, and run the same cleaning steps every time.
  2. Retrain on a fixed cadence. Monthly forecasts are usually refitted monthly; daily forecasts weekly. Re-check model orders and settings quarterly.
  3. Monitor forecast error. Track MAE or MAPE on each new period and set an alert when error drifts above its backtest level. Rising error usually means the business has changed.
  4. Show forecasts where decisions are made. Publish the forecast and its interval to the dashboard your team already uses; see how to create a dashboard in Power BI.
  5. Document assumptions. Record the data range, model settings, known events and what the interval means, so the forecast can be explained in a budget meeting.
  6. Keep humans in the loop. Planned launches, price changes or supply problems that the history cannot know about should adjust the forecast, with the adjustment recorded.

Common Time Series Forecasting Mistakes

  1. Splitting data randomly instead of by time, which leaks the future into training.
  2. Skipping the baseline, so there is no proof the model adds value.
  3. Evaluating on one holdout period instead of backtesting across several.
  4. Ignoring missing periods or an irregular frequency, which silently breaks ARIMA.
  5. Over-differencing, which adds noise and distorts the forecast.
  6. Reporting a single line without prediction intervals.
  7. Using MAPE on data with zeros or very small values.
  8. Letting Prophet’s trend chase recent noise by setting changepoint_prior_scale too high.
  9. Adding regressors without future values for the forecast period.
  10. Never retraining, so the model drifts as the business changes.

When to Bring In a Forecasting Expert

The workflow above works well for a single, clean series. Consider expert help when:

  • You need forecasts for many products, regions or customer segments
  • Promotions, holidays or price changes drive large swings
  • External factors (marketing spend, weather, economic data) matter
  • Forecasts feed inventory, staffing or budget decisions where errors are costly
  • You need automated retraining, monitoring and dashboards, not a one-off notebook
  • Your data is spread across several systems and needs cleaning first

Our team reviews your data, builds and backtests candidate models against baselines, and delivers forecasts with prediction intervals, a written forecast report, a documented Jupyter notebook and dashboard-ready outputs. Our predictive analytics services cover demand, sales, revenue and financial forecasting, and the fixed-scope Revenue Forecasting Package is typically delivered in 2–3 weeks.

Pricing is quote-based. It depends on the service, scope and deliverables, the size and quality of your data, the number of data sources, the complexity of the modelling, your tech stack and your timeline, and projects can be fixed-price or hourly-range. Forecasts are estimates, not guarantees: we report how accurate a model has been in backtesting and how uncertain its predictions are, so you can plan with that range.

Request a Proposal · Book a consultation · See how pricing works

Frequently Asked Questions

Is Prophet better than ARIMA?

Neither is better in general. Prophet is quicker to set up for business data with several seasonal patterns, holidays and trend changes. SARIMA often performs well on stable series with one seasonal pattern and offers clearer statistical diagnostics. Test both against a seasonal naive baseline on your own data.

How much data do I need for time series forecasting?

Enough to see the pattern repeat. For seasonal data, aim for at least two to three full seasonal cycles (for example, two to three years of monthly data), and more if you want to backtest properly. Very short histories favour simple methods.

What is the difference between ARIMA and SARIMA?

SARIMA is ARIMA with additional seasonal terms. It models patterns that repeat at a fixed seasonal lag, such as every 12 months, using the seasonal orders P, D and Q and the season length m.

How do I choose p, d and q for ARIMA?

Use stationarity tests to choose d (and D), read the ACF and PACF of the differenced series for starting values of p and q, then compare a few candidates by AIC and out-of-sample error. pmdarima.auto_arima automates this search.

How do I measure forecast accuracy?

Evaluate on data the model has not seen, using rolling-origin backtesting. Report MAE or RMSE in the data’s own units, MASE to compare against a seasonal naive baseline, and MAPE only when the series has no zeros or near-zero values.

Can I add external variables to ARIMA or Prophet?

Yes. Pass them as exog to SARIMAX, or use add_regressor() in Prophet. In both cases you need values for those variables over the forecast period.

When should I use machine learning instead of ARIMA or Prophet?

When you have many related series, many external drivers or complex non-linear effects. Gradient-boosting and deep-learning models can then help, but they need careful feature engineering and must still beat the same baselines.

Conclusion

Time series forecasting in Python is straightforward to start and easy to get wrong. Prepare a clean series with a fixed frequency, explore its trend and seasonality, set a seasonal naive baseline, then fit SARIMA and Prophet and compare them with backtesting. Keep the model that reliably beats the baseline, report its prediction intervals, and plan to monitor and retrain it. That discipline matters more than the choice of library.

Pius Imwene

Written by

Pius Imwene

Pius Imwene is a Data Analyst, Data Scientist, and analytics consultant specializing in data analysis, business intelligence, dashboards, data cleaning, predictive analytics, machine learning, and statistical reporting. Through Data Science Consulting Pro, he helps…

View full author details