Skip to main content

A package for exploration of regularly sampled time series.

Project description

Time Series Explorer (tseda)

tseda banner

Time series exploration and decomposition for fast, reliable insights.

PyPI Python Read the Docs License: Apache 2.0

Read the Docs

An application for time series exploration.

Overview

tseda lets you explore regularly sampled time series with a sampling frequency of one hour or greater. It is currently limited to 2,000 samples (this is configurable).

Three-Step Exploration Workflow

(a) Initial Assessment

Explore the distribution and spread of values using a kernel density estimate and box plot. You get to see the raw distribution of the values. The PACF and ACF provide clues about seasonality and autoregressive components.

(b) Decomposition Using Singular Spectral Analysis

Window selection and component grouping are the two hardest decisions when applying SSA. Choosing the wrong window distorts the eigen spectrum and makes meaningful grouping impossible; grouping the wrong components together conflates trend with seasonality or buries signal in noise. tseda automates both steps: it selects a window from the sampling frequency and derives a grouping from the eigen spectrum using a variance-and-correlation heuristic. Expert users can override both — the window via a slider and the grouping via direct input — but the defaults are designed to produce a defensible starting point without manual tuning.

The app first computes an initial SSA window from the detected cadence, then validates whether the eigen spectrum has enough spread. If the smallest eigenvalue still explains too much variance, the window is doubled and SSA is recomputed until the criterion is satisfied (or the SSA half-length bound is reached).

Cadence Initial Window
Hourly 24
Daily 5
Weekly 4
Monthly 12

Algorithm: Initial SSA Window Setup

Input:  regular time series x, inferred cadence c
Params: min_tail_spread = 0.10

--- Cadence-based initialization ---
1.  If c = hourly  -> w ← 24
2.  If c = daily   -> w ← 5
3.  If c = weekly  -> w ← 4
4.  If c = monthly -> w ← 12
5.  If cadence is unknown -> fail with "invalid window"

--- Spectrum-spread refinement ---
6.  Build SSA(x, w) and compute eigenvalues λ₁ ≥ ... ≥ λ_w
7.  tail_ratio ← λ_w / Σᵢ λᵢ
8.  While tail_ratio ≥ min_tail_spread and 2w ≤ floor(N/2):
    w ← 2w
    Rebuild SSA(x, w)
    tail_ratio ← λ_w / Σᵢ λᵢ

--- Output ---
9.  Return final w as the decomposition default and slider value

This can be changed in the UI. Based on the eigen value distribution, observations from the ACF plot and the eigen vector plot, the seasonal components can be determined if present. Based on these initial plots, the user needs to input a set of groupings and reconstruct the series with these groupings. The reconstruction plots are shown.

Change point detection is run automatically after grouping, covering two independent analyses:

  • Trend shifts — detects permanent changes in the long-run mean level (PELT on the normalised Trend component).
  • Seasonal amplitude shifts — detects points where the seasonal pattern becomes noticeably stronger or weaker (PELT on the rolling-RMS envelope of the Seasonality component).
  • Noise — excluded from change-point analysis by design; noise has no persistent structure.

The plot overlays both sets of markers on a single continuous signal line, with a plain-language date summary below. See the User Guide — Change Point Detection section for the full algorithm and visualisation reference.

The explained variance from signal and noise components and the assessment of the noise structure (independent or correlated) is provided.

The decomposition step now also includes an automatic grouping heuristic. Components explaining at least 10% of the total SSA variance are scanned in rank order. Near-equal adjacent pairs within a 5% difference are suggested as seasonality, other components above the threshold are suggested as trend, and all remaining components are left to noise. The Durbin-Watson (DW) statistic is then computed on the noise residual; if DW falls outside [1.5, 2.5] the algorithm expands the assignment one component at a time, tracking the assignment closest to DW = 2.0, until the criterion is met or all components are consumed. If the criterion is never met the user is prompted to try a different window size. The UI renders the result as a suggested grouping table, prepopulates the Trend, Seasonality, and Noise inputs, and still lets you override before applying reconstruction. Changing the window size slider re-runs the heuristic automatically.

Algorithm: SSA Eigenvalue Group Assignment

Input:  eigenvalues λ₁ ≥ λ₂ ≥ ... ≥ λₖ (sorted descending),
        noise residual r
Params: variance_threshold = 0.10, pair_tolerance = 0.05,
        dw_low = 1.5, dw_high = 2.5

--- Initial classification ---
1.  total  ← Σᵢ λᵢ
2.  For each i: vᵢ ← λᵢ / total           // explained variance ratio
3.  Eligible ← { i : vᵢ ≥ variance_threshold }
4.  Noise   ← { i : vᵢ < variance_threshold }
5.  Trend ← ∅;  Seasonality ← ∅

--- Scan eligible components in rank order ---
6.  cursor ← 0
7.  While cursor < |Eligible|:
      j ← Eligible[cursor]
      k ← Eligible[cursor + 1]  (if it exists)
      if k = j + 1  and  |λⱼ − λₖ| / max(λⱼ, λₖ) ≤ pair_tolerance then
          Seasonality ← Seasonality ∪ { j, k }
          cursor ← cursor + 2
      else
          Trend ← Trend ∪ { j }
          cursor ← cursor + 1

--- Validate with Durbin-Watson ---
8.  r_noise ← r − Σᵢ∈(Trend∪Seasonality) component(i)
9.  dw ← DurbinWatson(r_noise)
10. best ← current assignment;  best_dist ← |dw − 2.0|

--- Iterative expansion from noise pool ---
11. While dw ∉ [dw_low, dw_high]  and  |Noise| > 2:
      candidate ← Noise[0]          // largest remaining noise eigenvalue
      next      ← Noise[1]  (if it exists)
      if next = candidate + 1  and  |λ_candidate − λ_next| / max(…) ≤ pair_tolerance then
          Seasonality ← Seasonality ∪ { candidate, next }
          Noise ← Noise \ { candidate, next }
      else
          Trend ← Trend ∪ { candidate }
          Noise ← Noise \ { candidate }
      r_noise ← r − Σᵢ∈(Trend∪Seasonality) component(i)
      dw ← DurbinWatson(r_noise)
      if |dw − 2.0| < best_dist then
          best ← current assignment;  best_dist ← |dw − 2.0|

--- Output ---
12. If dw ∉ [dw_low, dw_high]:
        Return best  with warning "DW criterion not met — try a different window size"
13. Else:
        Return (Trend, Seasonality, Noise)

(c) Observation Logging

The SSA is based on the eigen decomposition of the trajectory matrix. Though the raw signal is correlated, the eigenvectors are uncorrelated. If we assume that the signal is Gaussian, this also implies independence. We can use the Akaike Information Criterion for model selection and determine the AIC as a function of the rank of the model. This is shown in the observation page. An automatic summary of all the observations is provided.

Notebook Interface

The package also provides a notebook interface to these features. If you have a new dataset that you want to analyze, look at the data loader directory for examples. Download your dataset, clean it, produce your time series, and analyze it with tseda.

Requirements

Python 3.13 or higher is required to run this package.

Before starting the installation, verify your Python version:

python --version

Ensure the output shows Python 3.13 or higher. If not, please upgrade Python before proceeding.

Install And Run From PyPI

Recommended: Using Conda

Conda is the recommended package manager for development and installation (development was done with conda):

conda create -n tseda python=3.13
conda activate tseda
pip install tseda

Then run the app:

tseda

Non-Developer Quick Start

If you just want to run the app with minimal setup:

  1. Install with pipx:
pipx install tseda
  1. Launch the app:
tseda
  1. Open your browser at http://127.0.0.1:8050.

If pipx is not available, use the standard Python install instructions below.

1. Install

Verify you have Python 3.13 or higher installed:

python --version

Create and activate a virtual environment, then install from PyPI:

python -m venv .venv
source .venv/bin/activate        # Windows: .venv\Scripts\activate
pip install tseda

2. Run The Dash App

tseda

You can also launch with Python module execution:

python -m tseda

Note: python tseda is not a valid way to run an installed package because Python treats tseda as a local script path.

By default, the app starts at http://127.0.0.1:8050.

Optional runtime overrides:

TSEDA_HOST=0.0.0.0 TSEDA_PORT=8050 TSEDA_DEBUG=false tseda

3. Upload Your Data

  • Click "Drag and Drop or Select Files" in the Initial Assessment panel.
  • Your file must be a CSV or Excel file with at least two columns: a timestamp column (first) and a numeric value column (second).
  • The data must be regularly sampled at hourly or lower frequency (e.g., hourly, daily, monthly).
  • The dataset must contain no missing values (NA / NaN). Clean your data before uploading.
  • Files are limited to 2,000 rows (configurable via MAX_FILE_LINES in ts_analyze_ui.py).

4. Explore In Three Steps

Step Panel What to do
1 Initial Assessment of Time Series Review distribution plots (KDE, box plot) and the ACF / PACF for autocorrelation patterns.
2 Time Series Decomposition Review the suggested grouping table, adjust the prepopulated Trend, Seasonality, and Noise inputs if needed, then click Apply Grouping.
3 Observation Logging Review the AIC rank diagnostics, read the auto-generated summary, and add your own observations before saving the report.

Development Install (From Source)

If you are developing locally from source:

pip install -e .
tseda

Build With uv

  1. Build source and wheel distributions:
uv build
  1. Validate distributions before upload:
uvx twine check dist/*

Documentation (Sphinx)

Build locally

pip install -r docs/requirements.txt
sphinx-build -b html docs/source docs/_build/html

You can also use the Makefile:

make -C docs html

The generated site will be available in docs/_build/html.

Publish on Read the Docs

This repository includes .readthedocs.yaml configured to build docs from docs/source/conf.py.

  1. Push the repository to GitHub (or another supported provider).
  2. Sign in to Read the Docs and import the project.
  3. In Read the Docs project settings:
    • Set the default branch.
    • Confirm the config file path is .readthedocs.yaml.
  4. Trigger a build from the Read the Docs dashboard.
  5. Optionally enable a custom domain and versioned docs.

If the build fails, inspect the Read the Docs build logs and replicate locally using:

make -C docs html

User Guide

A detailed user guide is available at docs/user_guide.md. A video version of the user guide is also available on YouTube. The written guide covers:

  • Data requirements and input format
  • Step-by-step walkthrough of all three workflow phases
  • Interpreting SSA decomposition outputs (eigenvalue profile, component groupings, Durbin-Watson test)
  • Change point detection (trend shifts and seasonal amplitude shifts — see Change Point Detection)
  • AIC-based model order selection
  • Exporting reports and knowledge base entries
  • Setting up the Gemini chatbot integration

Contributing & Feature Requests

If you'd like to request a feature or report an issue, please open an issue on GitHub. You're also welcome to reach out to me directly.

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

tseda-2.0.0.tar.gz (870.5 kB view details)

Uploaded Source

Built Distribution

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

tseda-2.0.0-py3-none-any.whl (869.1 kB view details)

Uploaded Python 3

File details

Details for the file tseda-2.0.0.tar.gz.

File metadata

  • Download URL: tseda-2.0.0.tar.gz
  • Upload date:
  • Size: 870.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for tseda-2.0.0.tar.gz
Algorithm Hash digest
SHA256 9a75ee132e20c48c8eebb8e4dfea14884e8c1018fb5d912c7f21f923c45bc96b
MD5 cb9c22570bb980217494401b95afcca9
BLAKE2b-256 0d18ae593a5735b016bae2ebebaad763640dd05d9bd6fa648eca09e6f827b4ee

See more details on using hashes here.

File details

Details for the file tseda-2.0.0-py3-none-any.whl.

File metadata

  • Download URL: tseda-2.0.0-py3-none-any.whl
  • Upload date:
  • Size: 869.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for tseda-2.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b483c743ac990d59d22bb5b1034803d8e272e2a694c6716843dc0d7d3116251d
MD5 b91130a109734e2768f8859d862cadb4
BLAKE2b-256 85412bc2d8e971a64ab6bf86b7940b72118c7ffbe69e3ce473a1ac3c36b094e1

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