Tuesday, September 1, 2026
HomeData ScienceTime Series Forecasting with Python – ARIMA, Prophet & LSTM 2026

Time Series Forecasting with Python – ARIMA, Prophet & LSTM 2026

Table of Content

Time series forecasting is one of the most in-demand data science skills — used in finance, supply chain, energy, and healthcare. This guide covers the three most practical approaches: classical ARIMA for stationary data, Facebook Prophet for business time series, and LSTM for complex non-linear patterns.

Understanding Time Series Data

A time series is a sequence of observations indexed by time. Key components include trend (long-term direction), seasonality (repeating patterns), and noise (random fluctuations). Before choosing a model you need to understand your data’s structure.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from statsmodels.tsa.stattools import adfuller

# Load sample data
df = pd.read_csv('sales.csv', parse_dates=['date'], index_col='date')
df = df.asfreq('D').fillna(method='ffill')   # daily frequency

# Decompose into trend + seasonal + residual
from statsmodels.tsa.seasonal import seasonal_decompose
result = seasonal_decompose(df['sales'], model='additive', period=30)
result.plot()
plt.tight_layout()
plt.show()

# Test for stationarity (ADF test)
adf_result = adfuller(df['sales'].dropna())
print(f'ADF Statistic: {adf_result[0]:.4f}')
print(f'p-value: {adf_result[1]:.4f}')
print('Stationary' if adf_result[1] < 0.05 else 'Non-stationary — need differencing')

ARIMA for Classical Forecasting

ARIMA (AutoRegressive Integrated Moving Average) works well for stationary time series. The three parameters p, d, q represent AR order, differencing, and MA order respectively.

from statsmodels.tsa.arima.model import ARIMA
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf

# Plot ACF/PACF to choose p and q
fig, axes = plt.subplots(1, 2, figsize=(12, 4))
plot_acf(df['sales'].diff().dropna(), ax=axes[0], lags=40)
plot_pacf(df['sales'].diff().dropna(), ax=axes[1], lags=40)
plt.show()

# Fit ARIMA(1,1,1)
model  = ARIMA(df['sales'], order=(1, 1, 1))
result = model.fit()
print(result.summary())

# Forecast next 30 days
forecast = result.get_forecast(steps=30)
mean_fc  = forecast.predicted_mean
conf_int = forecast.conf_int()

plt.figure(figsize=(12, 5))
plt.plot(df['sales'][-90:], label='Actual')
plt.plot(mean_fc, label='Forecast', color='red')
plt.fill_between(conf_int.index,
                 conf_int.iloc[:, 0],
                 conf_int.iloc[:, 1], alpha=0.2, color='red')
plt.legend()
plt.title('ARIMA Forecast')
plt.show()

# Auto-select parameters with pmdarima
from pmdarima import auto_arima
auto_model = auto_arima(df['sales'], seasonal=True, m=7,
                        stepwise=True, suppress_warnings=True)
print(auto_model.summary())

Facebook Prophet for Business Data

Prophet handles missing data, outliers, and multiple seasonalities automatically. It is ideal for business metrics like daily/weekly/yearly sales patterns.

from prophet import Prophet

# Prophet requires columns named 'ds' and 'y'
prophet_df = df.reset_index().rename(columns={'date': 'ds', 'sales': 'y'})

# Add holidays
from prophet.make_holidays import make_holidays_df
holidays = make_holidays_df(year_list=[2024, 2025, 2026], country='IN')

model = Prophet(
    yearly_seasonality=True,
    weekly_seasonality=True,
    daily_seasonality=False,
    holidays=holidays,
    seasonality_mode='multiplicative',   # use 'additive' if no growth trend
    changepoint_prior_scale=0.05         # flexibility of trend — lower = smoother
)
model.fit(prophet_df)

# Create future dataframe and predict
future    = model.make_future_dataframe(periods=90)
forecast  = model.predict(future)

fig1 = model.plot(forecast)
fig2 = model.plot_components(forecast)
plt.show()

print(forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail(10))

LSTM for Deep Learning Forecasting

a computer circuit board with a brain on it
Photo by Steve A Johnson on Unsplash

LSTMs capture complex, non-linear, long-range dependencies that ARIMA and Prophet miss. Use them when classical models underperform.

import numpy as np
from sklearn.preprocessing import MinMaxScaler
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, Dropout
from tensorflow.keras.callbacks import EarlyStopping

# Scale data
scaler = MinMaxScaler(feature_range=(0, 1))
scaled = scaler.fit_transform(df[['sales']])

# Create sequences
def create_sequences(data, seq_len=60):
    X, y = [], []
    for i in range(seq_len, len(data)):
        X.append(data[i-seq_len:i, 0])
        y.append(data[i, 0])
    return np.array(X), np.array(y)

SEQ_LEN = 60
X, y    = create_sequences(scaled, SEQ_LEN)
X       = X.reshape(X.shape[0], X.shape[1], 1)

# Train/test split (80/20)
split   = int(len(X) * 0.8)
X_train, X_test = X[:split], X[split:]
y_train, y_test = y[:split], y[split:]

# Build LSTM model
model = Sequential([
    LSTM(64, return_sequences=True, input_shape=(SEQ_LEN, 1)),
    Dropout(0.2),
    LSTM(32, return_sequences=False),
    Dropout(0.2),
    Dense(1)
])
model.compile(optimizer='adam', loss='mse')

es = EarlyStopping(patience=10, restore_best_weights=True)
model.fit(X_train, y_train, epochs=100, batch_size=32,
          validation_split=0.1, callbacks=[es], verbose=1)

# Predict and inverse transform
preds = scaler.inverse_transform(model.predict(X_test))
actual = scaler.inverse_transform(y_test.reshape(-1, 1))

from sklearn.metrics import mean_absolute_error, mean_squared_error
mae  = mean_absolute_error(actual, preds)
rmse = np.sqrt(mean_squared_error(actual, preds))
print(f'MAE: {mae:.2f} | RMSE: {rmse:.2f}')

Choosing the Right Model

Use ARIMA when data is stationary and you have limited training data (under 2 years). Use Prophet when you have business time series with holidays and multiple seasonalities and need interpretable components. Use LSTM when you have large datasets (3+ years daily), multiple input features, or when classical models fail to capture the pattern. For production, always ensemble: combine Prophet and LSTM predictions with a weighted average for best accuracy.

Model Evaluation Metrics

from sklearn.metrics import mean_absolute_error, mean_squared_error
import numpy as np

def evaluate_forecast(actual, predicted, model_name):
    mae   = mean_absolute_error(actual, predicted)
    rmse  = np.sqrt(mean_squared_error(actual, predicted))
    mape  = np.mean(np.abs((actual - predicted) / actual)) * 100
    print(f'{model_name}: MAE={mae:.2f} | RMSE={rmse:.2f} | MAPE={mape:.2f}%')

evaluate_forecast(actual, preds, 'LSTM')

Conclusion

Time series forecasting in Python has never been more accessible. Start with Prophet for quick wins on business data, add ARIMA when you need statistical rigor, and graduate to LSTM when your data is complex and plentiful. The key is always to understand your data's structure before selecting a model — decompose it, test for stationarity, and validate on a held-out test set before deploying to production.

Leave feedback about this

  • Rating

Durgesh Kekare
Durgesh Kekarehttps://www.dataexpertise.in
Durgesh Kekare is a data science educator and founder of DataExpertise.in. With expertise in Python, machine learning, and analytics, he helps 10,000+ learners break into data careers.

Latest Posts

List of Categories