bai_perron#
- cultivars.diagnostics.breaks.bai_perron(endog, exog=None, *, trend='c', max_breaks=5, trimming=0.15, criterion='bic', alpha=0.05, n_draws=5000, grid=2000, seed=None)[source]#
Bai-Perron estimation of multiple breaks in a linear regression.
The regression \(y_t = x_t^\top \beta_j + u_t\) is allowed a different \(\beta_j\) on each of \(m + 1\) segments, every coefficient breaking at once. The sum of squared residuals of every admissible segment, one of at least
trimmingtimes the sample and never fewer than \(q + 1\) observations, is tabled once, and the global least-squares partition for each \(m\) up tomax_breaksfollows by dynamic programming over that table, which is what makes the search over \(\binom{T}{m}\) partitions affordable. The number of breaks is then chosen three ways, all kept on the record, one reported. BIC and the Liu-Wu-Zidek criterion penalize the partition sequence, with \(p_m = (m + 1) q + m\) parameters; LWZ’s penalty grows as \((\ln T)^{2.1}\) rather than \(\ln T\), which is why the authors found it less prone to over-fitting. The sequential procedure starts from no break and, given the \(l\)-break partition, computes on each segment the largest single-break F statistic,\[\sup F(l + 1 \mid l) = \max_{\text{segments}} \max_{\tau} \frac{S_{\text{seg}} - S_{\text{split}}(\tau)} {S_{\text{split}}(\tau) / (n_{\text{seg}} - 2q)},\]tests \(l\) against \(l + 1\) with it, and stops at the first non-rejection at
alpha. Because the maximum is over \(l + 1\) independent segments, its p-value follows from the single-break sup-Wald limit \(G\) simulated at the trimming as \(1 - G(x)^{l + 1}\), and its critical values are the quantiles of \(G\) at \((1 - \alpha)^{1 / (l + 1)}\).- Parameters:
endog (
ArrayLike) – The target,(T,).exog (
ArrayLike|None) – Regressors(T, k)or(T,), orNone.trend (
str) – Deterministic terms,"n","c"or"ct", placed before the regressors in the design.max_breaks (
int) – Largest number of breaks considered; at least one.trimming (
float) – Minimum segment length as a fraction of the sample, in(0, 0.5);0.15is Bai and Perron’s default.criterion (
str) – Which selection to report:"bic","lwz"or"sequential".alpha (
float) – Level of the sequential tests, in(0, 1).n_draws (
int) – Limit-process paths for the sequential p-values, at least500.grid (
int) – Points on which each path is simulated, at least100.seed (
int|Generator|None) – Seed or generator for the limit simulation.
- Return type:
- Returns:
The
MultipleBreakTest, with the partition, SSR, BIC and LWZ for every count and the sequential tests taken.- Raises:
SpecificationError – If the criterion, trend, trimming, level, or counts are unusable, or if
max_breaks + 1segments of the minimum length do not fit the sample.DimensionError – If the regressors do not align with the target.
NumericalError – If a value is not finite or the design is rank deficient.
Note
The sequential F statistic here normalizes by the split segment’s own residual sum, with
n_seg - 2qdegrees of freedom, rather than by the full-sample residual sum of the \(l + 1\)-break model as in Bai and Perron’s Section 4; the two agree asymptotically and the segment form keeps each step a self-contained single-break test. Serial correlation and heteroskedasticity in \(u_t\) are not corrected for: include the lags the dynamics call for inexog, or read the selection as descriptive. The sequential tests are run under every criterion, socriterion="bic"still pays for the limit simulation;n_drawsis the lever if that matters.See also
MultipleBreakTest– the record, with the summary table over counts.sup_wald()– the single-break test with the same limit, when one break is the hypothesis.cusum()– a boundary test that needs no count of breaks.
References
Bai, J., & Perron, P. (1998). Estimating and testing linear models with multiple structural changes. Econometrica, 66(1), 47-78.
Bai, J., & Perron, P. (2003). Computation and analysis of multiple structural change models. Journal of Applied Econometrics, 18(1), 1-22.
Liu, J., Wu, S., & Zidek, J. V. (1997). On segmented multivariate regression. Statistica Sinica, 7(2), 497-525.
Example
One mean shift at observation 100. BIC, LWZ, and the sequential procedure agree on one break at the right date:
>>> import numpy as np >>> rng = np.random.default_rng(0) >>> y = np.concatenate([rng.standard_normal(100), 2.0 + rng.standard_normal(100)]) >>> bai_perron(y, max_breaks=3, seed=0) MultipleBreakTest(n_breaks=1, break_indices=(100,), criterion='bic', nobs=200) >>> bai_perron(y, max_breaks=3, criterion="lwz", seed=0).n_breaks 1 >>> test = bai_perron(y, max_breaks=2, criterion="sequential", seed=0) >>> test.n_breaks, [t.name for t in test.sequential] (1, ['sup F(1 | 0)', 'sup F(2 | 1)']) >>> test.sequential[0].pvalue, bool(test.sequential[1].pvalue > 0.05) (0.0, True)
Too many breaks for the sample at the requested trimming is refused rather than silently capped:
>>> bai_perron(y, max_breaks=10) Traceback (most recent call last): ... cultivars.exceptions.SpecificationError: 10 breaks with segments of at least 30 ...