Detecting Time‑Series Change Points with Grid Search and Piecewise Regression
This article shows how to turn change‑point detection into an optimization problem by exhaustively searching knot configurations with grid search, selecting the best model using a penalised likelihood criterion (BIC), and applying piecewise regression to automatically locate trend breakpoints, illustrated with R and Python code on California natural‑gas consumption data.
Grid‑search for change‑point detection
Traditional statistical methods for time‑series analysis become impractical when dozens or hundreds of series must be examined, and manual visual inspection of weak, noisy trend changes is unreliable. The article frames change‑point detection as an optimization problem solved by exhaustive grid search combined with piecewise‑regression.
Grid‑search principle
Grid search evaluates a discrete set of candidate parameters—in this case the number and positions of knots (potential change points). For each configuration a piecewise‑regression model is fitted, scored by a cost function, and the best‑scoring configuration is selected.
Cost functions and penalisation
Unpenalised error metrics such as Mean Squared Error (MSE), Mean Absolute Error (MAE) or Negative Log‑Likelihood (NLL) measure fit quality but ignore model complexity. To avoid over‑fitting the article adopts penalised criteria:
AIC : AIC = -2·log(L) + 2k BIC : BIC = -2·log(L) + k·log(n) where L is the maximised likelihood, k the number of estimated parameters, and n the number of observations. BIC imposes a heavier penalty, typically yielding fewer knots.
Search‑space constraints
To reduce over‑fitting and computational cost, three constraints are applied:
Edge buffer: a proportion of observations at the series start and end are excluded.
Minimum segment length: each segment must contain at least a specified number of observations.
Maximum number of knots: caps the search space.
Workflow
Prepare the data and define the search‑space parameters ( max_knots, min_segment_length, edge_buffer, grid_resolution).
Fit a piecewise‑regression model for each knot configuration.
Evaluate each fit with the penalised cost function (BIC).
Select the configuration with the lowest BIC.
The function input is the time series and the search‑space parameters; the output is the optimal set of knots.
R implementation
library(dplyr)
library(tsibble)
library(plotly)Auxiliary functions, including piecewise_regression, are sourced from the repository:
fun_path <- "https://raw.githubusercontent.com/RamiKrispin/the-forecaster/refs/heads/main/functions.R"
source(fun_path)Data loading and tidying (annual California natural‑gas consumer counts):
path <- "https://raw.githubusercontent.com/RamiKrispin/the-forecaster/refs/heads/main/data/ca_natural_gas_consumers.csv"
ts <- read.csv(path) |
arrange(index) |
filter(index > 1986) |
as_tsibble(index = "index")Grid‑search call:
grid <- piecewise_regression(
data = ts,
time_col = "index",
value_col = "y",
max_knots = 4,
min_segment_length = 8,
edge_buffer = 0.05,
grid_resolution = 20
)Search‑space definition: max_knots – maximum number of knots (set to 4). min_segment_length – minimum observations between consecutive knots (8). edge_buffer – proportion of observations excluded at each end (0.05). grid_resolution – maximum number of candidate configurations per knot count (20).
Resulting BIC scores:
Testing 0 knot(s)...
Best BIC: 919.28 | RSS: 1.006639e+12 | Tested 1 configurations
Testing 1 knot(s)...
Best BIC: 858.05 | RSS: 182625404855 | Tested 18 configurations
Testing 2 knot(s)...
Best BIC: 844.26 | RSS: 115452860424 | Tested 25 configurations
Testing 3 knot(s)...
Best BIC: 852.94 | RSS: 131838198802 | Tested 5 configurations
Testing 4 knot(s)...
Warning: Cannot fit 4 knots with min segment length 8
Optimal model: 2 knot(s) with BIC = 844.26The optimal knot dates are 1999 and 2007:
grid$optimal_knots
# [1] 2
grid$knot_dates
# [1] 1999 2007Visualization (overlaying knots on the original series) is performed with plot_knots.
Limitations
The method works best on "clean" series where the dominant signal is the underlying trend. Seasonal patterns, abrupt level shifts, or outliers can mislead the grid search, producing false or missed change points. A recommended preprocessing step is to decompose the series (e.g., STL) and apply the grid search to the extracted trend component. For structurally complex or noisy series, joint modeling of trend and seasonality may be more appropriate.
Summary
Change‑point detection can be cast as an optimization problem solved by exhaustive grid search. BIC balances fit quality against model complexity, while constraints on edge buffer, minimum segment length, and maximum knots improve stability and reduce computational cost. Grid search offers transparency and serves as a solid baseline, with the possibility of extending the framework using advanced optimization or Bayesian change‑point techniques.
Code repository:
https://github.com/RamiKrispin/the-forecaster/Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
DeepHub IMBA
A must‑follow public account sharing practical AI insights. Follow now. internet + machine learning + big data + architecture = IMBA
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
