| nmfkc.ar.latent.inference | R Documentation |
This function is experimental. The interface may change in future versions: argument names, defaults and the contents of the returned object are not yet stable.
nmfkc.ar.latent.inference attaches a wild bootstrap to the quantities
reported by nmfkc.ar.latent: standard errors and intervals for
the spectral radius, the long-run mean, the long-run composition and the
entries of the latent transition matrices G_d.
nmfkc.ar.latent.inference(object, Y, A, ...)
object |
An object from |
Y, A |
The observation and covariate matrices the model was fitted on,
i.e. the |
... |
Additional arguments:
|
What is identified, and why that decides what can be inferred. The
factorization admits (X,\Theta)\to(XT,T^{-1}\Theta) for invertible
T, so an entry of \Theta means nothing across replicates;
nmfkc.inference deals with this by conditioning on the
estimated X. This function instead re-estimates the basis in every
replicate, propagating its uncertainty. That splits the output in two:
Inferential. \rho, the eigenvalues and the observed
long-run mean \bm\mu_y=X\bm\mu_b are invariant under the whole
family (G_d\to T^{-1}G_dT leaves the spectrum alone), so their
replicates need no alignment and their intervals mean what they say.
Conditional on identification. The entries
(G_d)_{qq'} and the composition \bm p^\ast need T to be
a permutation, and three conditions together deliver that: the column
scale fixed (X.restriction = "colSums"), an anchor row for
every column of X, and every row of \Theta pinned.
The anchor rows force T\ge0. The rows are then pinned one at a
time: row k joins the pinned set S when some covariate
(column of \Theta) is non-zero only for bases in S\cup\{k\},
including k, and, for every q\in S, such a covariate has a
zero coefficient for q. The first row pinned needs a pure
column (a covariate that loads on that basis alone); later rows only need
zeros that separate them from the rows already pinned, possibly in
different columns. Each pinned row makes e_k a column of T,
so pinning every row makes T a permutation. (This used to require a
pure column for every row, which is stronger: every fit that passed before
passes now.) Either condition alone is not enough: with
X=I_2,
\Theta=\left(\begin{smallmatrix}2&3\\1&1\end{smallmatrix}\right) and
T=\left(\begin{smallmatrix}0.9&0.1\\0.1&0.9\end{smallmatrix}\right)
the basis is perfectly separable and column-normalized, yet XT\ge0,
T^{-1}\Theta\ge0, X\Theta is unchanged, T is no
permutation, and G differs between the two representatives —
no row of \Theta can be pinned there. Nor are zeros that merely
separate every pair of rows enough: with anchors and the covariate columns
(0,1,1), (1,0,1), (1,1,0), T=(J-I)/2 is admissible.
A coefficient counts as zero when it is at most kkt.tol or at most
pin.tol times the coefficient of the same covariate for the basis
being pinned (that ratio is the mixing the covariate still allows), and a
covariate whose coefficients are all numerical noise is ignored.
The mirror route swaps the two factors and is checked as well,
with nothing to choose: a pure covariate for every basis (forcing
T^{-1}\ge0), and the bases pinned one at a time through the rows of
X – the first by an anchor row, the later ones by variables whose
zero loadings separate them from the bases already pinned (an entry of
X counts as zero when it is at most 1 - sep.tol times the
loading of the basis being pinned). Either route suffices; identification$route
names the one that passed. identified.approx reports
the verdict and identification its parts. What a pass
means, to the precision of the fit: multiplicative updates leave small
positive values where the argument wants exact zeros, so the check
treats values within the tolerances as zero and reports how exact they
are. The margin of the route that passed is the largest such value
relative to the entry it was compared with, i.e. the rotation slack:
every equivalent fit (XT, T^{-1}\Theta) mixes one basis into
another by at most about that much, so the entries of G_d are
determined to about that relative precision. print() states it
(e.g. "the zeros it rests on hold to 0.0024, so an equivalent fit mixes
the bases by at most about 0.24\
part that fails. Two things lie outside the check: whether the
estimated zeros are zeros in the population (a question for their
intervals), and other fits that are only nearly as good (different
starting values can reach one). Replicates are permutation-aligned to
the original basis regardless.
X.restriction = "fixed" is the one clean case for Q>1 — the
basis is not estimated, so T=I.
prob.nonstationary is not a unit-root test. It is the
bootstrap tail probability P^\ast(\rho^\ast\ge1), with replicates drawn
around the estimated model. Nothing imposes H_0:\rho=1, so it
does not have the interpretation of a p-value for that hypothesis; a proper
test would have to resample under the null.
The zeros of \Theta are only meaningful under
misspecification. The strict-complementarity diagnostic reports the dual
margin \delta_{\mathrm{dual}}=\min|\Lambda^\ast| over the zero
coefficients and the primal margin
\delta_{\mathrm{prim}}=\min\Theta over the positive ones. Both must be
bounded away from zero for the support to be recovered exactly and for the
active coefficients to attain the distribution that knowing the support would
give. If the model is correctly specified, \Xi_0=X\Theta makes
\Lambda^\ast=0 exactly, so strict complementarity fails at
every zero: P(\hat\theta_k=0) then tends to a constant in
(0,1) (one half for an isolated zero) instead of to one, and no
resampling scheme is consistent there. A small kkt$ratio is therefore
not a numerical defect — it says the zeros are not estimating a sign
restriction. What makes them estimate something is misspecification: they
recover the coordinates whose unconstrained population coefficient is
strictly negative.
Bootstrap validity at the boundary. A naive nonparametric bootstrap
is inconsistent for a parameter on the boundary. The scheme used here
resamples the residuals and re-imposes the non-negativity constraint in every
re-fit, which is the practical remedy. wild.unit = "block" in
addition keeps the serial dependence of the residuals within a block; the
lagged design itself stays fixed (see below).
Bootstrap p-values invert the centred distribution. Every replicate
of a non-negative coefficient is \ge 0, so comparing the raw replicates
with zero would return p = 0 for every entry. The reported
G.p.value is the basic-bootstrap two-sided p obtained from
P^\ast(\hat G^\ast \ge 2\hat G).
Resampling scheme. With \hat Y = X\Theta A and residuals
E=Y-\hat Y, each replicate forms Y^\ast=\hat Y+E\odot W and
re-fits nmfkc at the same rank. W carries one multiplier
per time point (wild.unit = "column", the default, which preserves the
contemporaneous covariance between series), one per block of consecutive
time points (wild.unit = "block", below), or one per cell.
With i.i.d. multipliers over time the intervals ignore residual
autocorrelation and may be too narrow when it is present. Negative entries
of Y^\ast are truncated at 0 to keep the response non-negative; the
truncation rate is reported, and a large one is a warning sign for the whole
procedure.
Block wild bootstrap (wild.unit = "block"). One multiplier
is drawn per block of L = \max(1, \mathrm{round}(n^{1/3})) consecutive time points and shared by all series, where
n is the number of time points, ncol(Y) (after the lags are
removed): L = 3 for n = 27, 5 for 100, 8 for 500, 10 for 1000,
and L = 1 (the same draws as "column") for n \le 3. The
block grid starts at a random offset in 0, \dots, L-1,
drawn anew in each replicate, so the first and last blocks may be shorter
and no time point is always at a block edge. Residuals within a block keep
their serial dependence, which matters when the residuals are autocorrelated
(for example when the lag order is too small); for a correctly specified VAR
the default "column" suffices. n^{1/3} is the usual rate
for the block length of block resampling. The length is fixed by n; it
cannot be set and is not stored in the result.
This is a fixed-design bootstrap: the covariate matrix A is
held at the observed lags rather than rebuilt from Y^\ast, so the
intervals are conditional on the observed past and do not propagate the
randomness of the lagged design itself. They may therefore be somewhat
optimistic.
An object of class "nmfkc.ar.latent.inference": a list with
coefficients |
Data frame of the |
G, G.se, G.ci.lower, G.ci.upper, G.p.value |
The same quantities as
lists of |
spectral.radius |
The radius of the |
prob.nonstationary |
Bootstrap tail probability
|
complex, complex.frac |
Whether the point estimate has complex roots, and the fraction of replicates that do. |
mu.y |
With |
p.star |
With |
kkt |
Strict-complementarity diagnostic: |
identified.approx |
Logical: is the factorization unique up to a
permutation of the bases, to the precision of the fit? |
identification |
The parts of the diagnostic: for the first route
|
refit.args |
The arguments the bootstrap re-fits actually used, so the replicates can be checked against the original estimator. |
Plus the bookkeeping entries wild.B, wild.B.requested,
n.fail, truncate.rate, wild.unit, wild.dist,
wild.level, dims.
Satoh, K. (2025). Applying non-negative matrix factorization with covariates to multivariate time series data as a vector autoregression model. Japanese Journal of Statistics and Data Science. arXiv:2501.17446. \Sexpr[results=rd]{tools:::Rd_expr_doi("10.1007/s42081-025-00314-0")}
nmfkc.ar.latent, nmfkc.ar.stationarity,
nmfkc.ar, nmfkc.inference
set.seed(1)
Y <- matrix(abs(rnorm(4 * 40)) + 1, 4, 40)
ar <- nmfkc.ar(Y, degree = 1)
fit <- nmfkc(ar$Y, ar$A, rank = 2, verbose = FALSE)
lat <- nmfkc.ar.latent(fit)
nmfkc.ar.latent.inference(lat, ar$Y, ar$A, wild.B = 50)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.