DFM._bai_ng#

static DFM._bai_ng(standardized, max_factors)[source]#

Bai-Ng ICp2 over candidate counts, and its argmin.

ICp2(r) = ln V(r) + r ((N + T) / (N T)) ln(min(N, T)) with V(r) the mean squared residual of the r-component approximation – the paper’s preferred penalty, consistent as both dimensions grow. One finite-sample honesty note: when the common component explains nearly all of the panel, the log criterion measures each spurious eigenvalue against a tiny remainder and overselects – a known property of the criterion, not of this implementation. If the reported count looks generous next to the variance shares, state n_factors yourself.

Parameters:
  • standardized (NDArray[double]) – The (nobs, n_series) panel with zero column means and unit column variances.

  • max_factors (int) – The largest candidate count, at most min(nobs, n_series).

Return type:

tuple[int, NDArray[double]]

Returns:

(count, values) – the minimizing count, from 1, and the criterion at each candidate 1 .. max_factors.

Example

>>> import numpy as np
>>> rng = np.random.default_rng(0)
>>> f = np.zeros((200, 2))
>>> for t in range(1, 200):
...     f[t] = 0.7 * f[t - 1] + rng.standard_normal(2)
>>> panel = f @ rng.standard_normal((30, 2)).T + 1.5 * rng.standard_normal((200, 30))
>>> z = (panel - panel.mean(axis=0)) / panel.std(axis=0)
>>> count, values = DFM._bai_ng(z, 6)
>>> count, values.shape, int(np.argmin(values)) + 1
(2, (6,), 2)