Skip to main content

Bayesian time‑series model with Beta/Gaussian heads, smooth changepoints and seasonality

Project description

📈 Murphet — Prophet's (0-1) Cousin for Probabilities & Rates

PyPI version Python License: MIT

A Stan-powered time-series model that never breaks the 0 - 1 bounds and still feels like Prophet.


1 · Why Murphet?

Problem with vanilla Prophet How Murphet fixes it
Forecasts of rates can shoot < 0 or > 1 Beta head maps μ → (0, 1) automatically
Constant-variance Gaussian noise mis-prices tails Mean-dependent Beta / Student-t likelihoods
Hard CPs create kinks; few data → over-fit Smooth logistic changepoints + Laplace shrinkage
Season coefficients often blow up Weak-Normal (σ≈10) priors, optional horseshoe
Residual AR left untreated Latent AR(1) disturbance (ρ, μ₀)
One-size-fits-all variance Heteroscedastic φᵢ/σᵢ via log-linear link

2 · Installation

pip install murphet              # wheels include pre-compiled Stan models

Requirements

  • Python >= 3.8 & CmdStanPy >= 1.0 (auto-installed)
  • A recent CmdStan toolchain (gcc/clang) — cmdstanpy.install_cmdstan() will fetch it.

3 · Quick start

import pandas as pd, numpy as np
from murphet import fit_churn_model

df = pd.read_csv("churn_data.csv")        # cols: ds, y  (0<y<1)
df["ds"] = pd.to_datetime(df["ds"])
df["t"]  = np.arange(len(df))             # integer index

mod = fit_churn_model(
        t              = df["t"],
        y              = df["y"],
        periods        = 12, num_harmonics = 3,    # yearly seasonality
        n_changepoints = 4,
        likelihood     = "beta",                   # default & safest
        inference      = "nuts",                   # full posterior
      )

future_t = np.arange(len(df), len(df)+6)
fcst     = mod.predict(future_t)

4 · Model internals (nutshell)

Component Equation Note
Trend μdet(t) = k·t + m + ∑ δj σ(γ (t − sj)) smooth CP ramps
Seasonality Fourier blocks on raw t (fmod) multiple periods OK
Link / saturation μlogit⁻¹p optional
Likelihoods Beta(p·φᵢ,(1-p)·φᵢ) or Student-tν(μ,σᵢ) φᵢ / σᵢ heteroscedastic
Latent error y* = μdet + ρ·lag AR(1) disturbance

Add-ons implemented

✔ add-on Stan code snippet Effect
AR(1) latent error real<lower=-1,upper=1> rho; real mu0; + update in partial_sum_* absorbs slow drifts / residual autocorr
Heteroscedastic precision / scale phi_i = exp(log_phi0 - beta_phi*abs(mu_det)); (Beta) / sigma_i = exp(log_sigma0 + beta_sigma*abs(mu_det)); (Gauss) wider tails when level high
Heavy-tail option `student_t_lpdf(y ν, μ, σᵢ)withν ~ Exp(1/30)`

5 · Case-studies

5 a · Hong-Kong hotel occupancy (monthly, 2020-2025)

Source link

Hotel hold-out

Hold-out horizon RMSE
Murphet β 0.0916
Prophet (optimised) 0.1159

5 b · U.S. Retail Inventories-to-Sales Ratio (FRED RETAILIRNSA)

Retail hold-out

Hold-out (24 mo) RMSE SMAPE
Murphet β 0.0496 5.15 %
Prophet 0.1140 13.21 %

Residual check:

Residual diagnostics

Murphet's AR(1)+heteroscedastic head slashes autocorrelation; Prophet still shows structure.


6 · Which head to choose?

Head Use-case Link Likelihood
β (default) Proportions, CTR, churn %, conversion % logit⁻¹ Beta(p·φᵢ,(1-p)·φᵢ)
Gaussian / Student-t Ratios "around" 0.4–1.0 or unbounded KPI identity Normal/Student-t(μ,σᵢ)

Switch with likelihood="gaussian"; all other API calls identical.


7 · API cheat-sheet

Function Purpose
fit_churn_model(t, y, **kwargs) fit (MAP, ADVI, or NUTS)
model.predict(t_new) fast vectorised prediction
model.fit_result access raw CmdStanPy object
model.summary() pretty DataFrame of posteriors

Key kwargs:

periods, num_harmonics         # seasonality
n_changepoints, delta_scale    # trend flexibility
gamma_scale                    # CP steepness
season_scale                   # weaken/strengthen Fourier priors
likelihood  = "beta"|"gaussian"
inference   = "map"|"advi"|"nuts"

8 · Road-map

  • Holiday regressors (Prophet style)
  • Prophet-like plotting helpers
  • Automatic Stan/C++ speed-ups for long MCMC chains

9 · Citing Murphet

If you use Murphet in academic work, please cite:

Murphy, S. (2025). Murphet: A Bayesian Time-Series Model for Bounded Rates.
https://github.com/halsted312/murphet

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

murphet-1.3.0.tar.gz (15.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

murphet-1.3.0-py3-none-any.whl (13.0 kB view details)

Uploaded Python 3

File details

Details for the file murphet-1.3.0.tar.gz.

File metadata

  • Download URL: murphet-1.3.0.tar.gz
  • Upload date:
  • Size: 15.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.10.17

File hashes

Hashes for murphet-1.3.0.tar.gz
Algorithm Hash digest
SHA256 298f7c0d8bad410b00ac70fcb33bc1daed53559acb9369785d33413dbc920e46
MD5 7dc61cb50bf39be0841f91cc3d45d112
BLAKE2b-256 40636c2a7e2af596d8205273b1f7b3f035430e3b6fcafcc022ed52a467577472

See more details on using hashes here.

File details

Details for the file murphet-1.3.0-py3-none-any.whl.

File metadata

  • Download URL: murphet-1.3.0-py3-none-any.whl
  • Upload date:
  • Size: 13.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.10.17

File hashes

Hashes for murphet-1.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f27d8a0391d5e54050f11a20df466564911e2be36a1570a44776b40b27b84507
MD5 d0ae4e4003a9d737c14b74f7eea579c9
BLAKE2b-256 adc751b45937a2b5bd2321422ab9cd8886948fab157e34c8927b6605b9cd05fa

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page