How to Auto‑Detect Trend Change Points with Grid Search & Piecewise Regression
This tutorial explains how to automatically locate trend change points in large collections of time series by combining grid search with piecewise regression, covering the underlying theory, cost functions, implementation in R and Python, and practical constraints to avoid over‑fitting.
Using Grid Search to Find Change Points
Grid search evaluates a predefined set of candidate parameters. In piecewise (segmented) regression the parameters are the number of knots (change points) and their positions. The procedure consists of defining a search space, fitting a model for each configuration, scoring the models with a penalised cost function, and selecting the configuration with the lowest score.
Defining the Cost Function
To compare models with different numbers of knots a metric that balances fit quality and model complexity is required. Common loss functions (MSE, MAE, negative log‑likelihood) measure fit but ignore complexity. Information criteria add a penalty term:
AIC = -2 * log(L) + 2 * k 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 penalises complexity more strongly than AIC, making it a conservative choice for change‑point selection.
Grid Search Workflow
Prepare the time‑series data and define the search‑space parameters.
For each candidate knot configuration, fit a piecewise regression model.
Compute the penalised cost (e.g., BIC) for each fitted model.
Select the configuration with the minimum cost; the output is the optimal set of knot locations.
R Implementation
Required packages :
library(dplyr)
library(tsibble)
library(plotly)Helper functions (including piecewise_regression) are sourced from the public repository:
fun_path <- "https://raw.githubusercontent.com/RamiKrispin/the-forecaster/refs/heads/main/functions.R"
source(fun_path)Data loading (annual natural‑gas consumer counts for California):
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")
head(ts)Running the grid search :
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 parameters : max_knots: maximum number of knots to consider. min_segment_length: minimum number of observations required between two knots. edge_buffer: proportion of observations excluded from the start and end of the series to avoid edge effects. grid_resolution: maximum number of candidate configurations evaluated for each knot count.
Sample output (truncated) shows the best BIC for each knot count and the optimal model:
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)... Optimal model: 2 knot(s) with BIC = 844.26
Warning: Cannot fit 4 knots with min segment length 8The optimal model contains two knots at years 1999 and 2007. These locations can be visualised with the helper function plot_knots (not shown).
Limitations
The grid‑search + piecewise‑regression approach works best on relatively clean series where the dominant signal is a smooth trend. In noisy, highly seasonal, or abruptly shifted series the method may detect spurious change points or miss genuine ones. Pre‑processing such as STL decomposition to isolate the trend before applying the grid search can improve robustness.
Conclusion
Change‑point detection can be framed as an optimisation problem: enumerate candidate knot configurations with grid search, evaluate each using a penalised likelihood criterion (BIC), and select the configuration that balances fit and complexity. While computationally simple and transparent, grid search serves as a solid baseline; more sophisticated methods (e.g., Bayesian change‑point detection) can be built on this foundation.
Source 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.
Data Party THU
Official platform of Tsinghua Big Data Research Center, sharing the team's latest research, teaching updates, and big data news.
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.
