nmf.rrr.signed: Signed-Bottleneck NMF-AE: Three-Layer NMF-AE with Signed...

View source: R/nmfae.signed.R

nmf.rrr.signedR Documentation

Signed-Bottleneck NMF-AE: Three-Layer NMF-AE with Signed Bottleneck

Description

nmfae.signed fits a three-layer non-negative matrix factorization autoencoder with a signed bottleneck, solving

Y_1 \approx X_1 (C_{+} - C_{-}) X_2 Y_2, \quad X_1 \ge 0,\; C_{+} \ge 0,\; C_{-} \ge 0,\; X_2 \ge 0,

where \Theta = C_{+} - C_{-} is the signed bottleneck. The basis matrices X_1 (columns sum to 1) and X_2 (rows sum to 1) retain their non-negative "parts-based" interpretability, while \Theta can express anti-correlations (e.g., refractive index up vs. Abbe number down).

The algorithm uses Direct Multiplicative Updates derived from Ding et al. (2010) sign-splitting technique, applied block-wise to the four non-negative blocks (C_{+}, C_{-}, X_1, X_2). Each block update monotonically decreases the true objective \|Y_1 - X_1(C_{+} - C_{-})X_2 Y_2\|_F^2 (Lee-Seung auxiliary function method).

Relation to nmfae: When \Theta \ge 0 suffices (the nmfae case), nmfae.signed reduces to nmfae up to the C_{+} - C_{-} parameterization. Use nmfae.signed when the data exhibit negative cross-property correlations that tri-NMF-AE cannot express (e.g., high refractive index <-> low Abbe number trade-off).

Usage

nmf.rrr.signed(
  Y1,
  Y2 = Y1,
  rank1 = 2,
  rank2 = NULL,
  epsilon = 1e-04,
  maxit = 5000,
  verbose = FALSE,
  ...,
  rank = NULL,
  rank.encoder = NULL
)

Arguments

Y1

Output matrix Y_1 (P1 x N). Negative entries allowed (Y.signed = TRUE is auto-detected).

Y2

Input matrix Y_2 (P2 x N). Must be non-negative. Default Y1 (autoencoder).

rank1

Integer. Response-basis rank Q. Default 2.

rank2

Integer. Covariate-basis rank R. Default (NULL) = rank1.

epsilon

Relative convergence tolerance on the objective. Default 1e-4.

maxit

Maximum iterations. Default 5000.

verbose

Logical. Print progress. Default FALSE.

...

Additional arguments:

warm.start

One of TRUE (default, hybrid: warm-start X_1, X_2 from nmfae but initialize C_{+}, C_{-} randomly), "full" (warm-start everything including C_{+} = C_{\mathrm{tri}}, C_{-} = \delta), or FALSE (random for all blocks). The hybrid default avoids the C_{-} = 0 local-minimum trap inherited from tri-NMF-AE while still benefiting from good X_1, X_2 initialization. Ignored when Y_1 has negative entries.

nstart

Integer, default 1 (cf. kmeans). Number of random restarts for C_{+}, C_{-}. Each restart uses seed seed + 7919 * (s-1). Returns the best run by final objective. Signed models have more local minima than non-negative ones because the bottleneck \Theta = C_{+} - C_{-} can take both positive and negative values; during exploration a larger nstart (e.g., 10-50) reduces the chance of being trapped at an inferior stationary point (particularly the C_{-} = 0 trap from warm-start from non-negative tri-NMF-AE). Use the default 1 for fast development and raise for publication-grade runs.

X1.L2.ortho, X2.L2.ortho

Non-negative L2 orthogonality penalties (default 0) on the columns of X_1 and the rows of X_2, penalizing (\lambda/2)\lVert\mathrm{offdiag}(X_1^\top X_1)\rVert^2 and (\lambda/2)\lVert\mathrm{offdiag}(X_2 X_2^\top)\rVert^2 respectively. Same convention as nmfae; encourage more distinct (less overlapping) response / covariate bases.

C.L2

Non-negative ridge penalty (default 0) on the signed bottleneck C = C_{+} - C_{-}, adding \lambda\lVert C_{+} - C_{-}\rVert^2. Shrinks \Theta toward zero (with zero gradient on the unidentified common mode C_{+} + C_{-}), injected into both the unweighted and weighted C_{+}/C_{-} updates.

Y1.weights

Optional non-negative weight matrix (P1 x N) or vector (length N) for Y_1, analogous to the weights argument of lm. Loss becomes \sum W_{ij} \, (Y_{1,ij} - \hat Y_{1,ij})^2 (lm()-style, linear in W). Logical matrices (TRUE / FALSE) are also accepted. Used by nmfae.signed.ecv to hold out test elements via a binary mask W \in \{0,1\}; real-valued weights for importance weighting are also supported. Default: if Y1 has NA, a binary mask is auto-generated (0 for NA, 1 elsewhere).

Cp.init, Cn.init

Explicit Q \times R non-negative matrices for initialization. Overrides warm.start.

C.init

Explicit signed Q \times R matrix, internally split into (C_{+}, C_{-}).

X1.init, X2.init

Explicit basis matrices.

seed

RNG seed. Default 123.

print.trace

Logical. Print iteration trace. Default FALSE.

prefix.dec, prefix.enc

Label prefixes for the response/covariate bases. Default "Resp", "Cov".

rank, rank.encoder

Deprecated aliases of rank1 / rank2 (Q / R also accepted via ...).

Value

An object of class c("nmfae.signed", "nmfae", "nmf") with:

X1

Decoder basis (P1 x Q), column sum 1.

Cp, Cn

Non-negative parts of \Theta (each Q x R).

C

Signed bottleneck \Theta = C_{+} - C_{-} (Q x R).

X2

Encoder basis (R x P2), row sum 1.

Y1hat

Fitted values X_1 (C_{+} - C_{-}) X_2 Y_2.

H

Encoding (C_{+} - C_{-}) X_2 Y_2 (Q x N, signed).

rank

c(Q = Q, R = R).

dims

c(P1, P2, N).

objfunc, objfunc.iter

Final and per-iteration objective values.

r.squared

\mathrm{cor}(Y_1, \widehat Y_1)^2 (Pearson; in [0,1]).

r.squared.uncentered

Uncentered R^2 = 1 - \|Y_1 - \widehat Y_1\|_F^2 / \|Y_1\|_F^2 (baseline = zero matrix).

r.squared.centered

Row-mean centered 1 - \|Y_1 - \widehat Y_1\|_F^2 / \|Y_1 - \bar Y_{p\cdot}\|_F^2.

sigma, mae

Residual SE and mean absolute error.

niter, runtime

Iterations and elapsed seconds.

Y.signed

Logical; whether Y_1 contained negative entries.

call

Matched call.

Lifecycle

This function is experimental; interface may change.

References

Ding, C.H.Q., Li, T., and Jordan, M.I. (2010). Convex and Semi-Nonnegative Matrix Factorizations. IEEE TPAMI, 32(1), 45-55.

Satoh, K. (2026). Signed-Bottleneck NMF-AE: Signed-Bottleneck 3-Layer NMF (research memo, 2026-04-18).

Ding, C. H. Q., Li, T., & Jordan, M. I. (2010). Convex and semi-nonnegative matrix factorizations. IEEE Transactions on Pattern Analysis and Machine Intelligence, 32(1), 45–55.

See Also

nmfae, predict.nmfae.signed, summary.nmfae.signed, nmfae.signed.rename

Examples


set.seed(1)
Y1 <- matrix(abs(rnorm(12)), 3, 4)
Y2 <- matrix(abs(rnorm(20)), 5, 4)
res <- nmf.rrr.signed(Y1, Y2, rank1 = 2, rank2 = 2, maxit = 500)
summary(res)


nmfkc documentation built on July 14, 2026, 1:07 a.m.