NMFMerge improves nonnegative matrix factorization (NMF) by over-factorizing and then merging components in pairs. It projects NMF solutions from a higher-dimensional space to a lower-dimensional one by optimally and sequentially merging NMF component pairs, which tends to reach better and more reproducible optima than factorizing directly into the target number of components.
This approach is motivated by the idea that convergence of NMF becomes poor when one is forced to make difficult tradeoffs in describing different features of the data matrix; performing an initial factorization with an excessive number of components grants the opportunity to escape such constraints and reliably describe the full behavior of the data matrix. Later, any redundant or noisy components are identified and merged together.
The package implements the technique in An optimal pairwise merge algorithm improves the quality and consistency of nonnegative matrix factorization (Guo & Holy, IEEE Trans. Signal Process. 2025, doi:10.1109/TSP.2025.3585893).
The concept of NMF-Merge in an illustrative example:

The data matrix is
NMFMerge is a registered package. From the Julia REPL, type ] to enter package
mode and run:
pkg> add NMFMergeBuild your nonnegative data matrix X and call nmfmerge:
using NMFMerge
result = nmfmerge(X, 5 => 4) # factorize with 5 components, merge down to 4
W, H = result.W, result.Hncomponents may be a pair n1 => n2 (overcomplete count => final count) or a
single integer final count (in which case nmfmerge defaults to an approximate
20% component excess before merging).
The exported building blocks — colnormalize, merge_pq, and merge_replay —
let you drive merging yourself, for example when choosing the number of
components by merging all the way down and locating a "knee" in the merge-error
sequence.
See the documentation for a full worked example, the lower-level workflow, and the complete API reference.
Thanks for citing this work! See the "Cite this repository" link in the "About" bar for format options.