大型稀疏矩阵上的快速非负矩阵分解
Posted
技术标签:
【中文标题】大型稀疏矩阵上的快速非负矩阵分解【英文标题】:Fast non-negative matrix factorization on large sparse matrix 【发布时间】:2015-10-11 22:50:02 【问题描述】:使用 Scikit-learn (v 0.15.2) 对大型稀疏矩阵(小于 1% 的值 > 0)进行非负矩阵分解。我想通过仅在矩阵的非零值上最小化错误来找到因子(即,不计算零条目的错误),并支持稀疏性。我不确定我正在尝试的内容是否有问题。 scikit-learn 包的 NMF 和 ProjectedGradientNMF 以前对我很有效。但似乎当矩阵大小增加时,分解速度非常慢。
我说的是具有 > 10^10 个单元格的矩阵。对于具有 ~10^7 单元格的矩阵,我发现执行时间很好。
我使用的参数如下:nmf_model = NMF(n_components = 100, init='nndsvd', random_state=0, tol = 0.01, sparseness='data')
。
当我尝试稍微不同的参数(更改为 init=random
)时,我收到以下警告。警告后,脚本的执行将停止。
/lib/python2.7/site-packages/sklearn/decomposition/nmf.py:252: UserWarning: Iteration limit reached in nls subproblem.
warnings.warn("Iteration limit reached in nls subproblem.")
有没有办法让它更快并解决上述问题?我尝试过使用 numpy 稀疏矩阵(列和行稀疏),但令人惊讶的是 - 在我使用较小矩阵(~10^7 单元格)进行的测试中速度较慢。
考虑到必须对这种分解进行多次迭代(以选择理想数量的因子和 k 倍交叉验证),因此非常需要一种更快的方法来解决这个问题。
我也愿意接受不基于 sklearn 或 Pyhon 的包/工具的建议。我知道不鼓励提出有关包/工具选择的问题,但对于这样一个特定的用例,了解该领域的其他人使用哪些技术会非常有帮助。
【问题讨论】:
【参考方案1】:也许关于最初的问题的几句话可以让我们给出更好的答案。
由于问题的性质,对非常大的矩阵进行矩阵分解总是会很慢。
建议:
将n_components
减少到 max_features 参数。示例:
vectorizer = TfidfVectorizer(
max_features=10000,
ngram_range=(1,2))
tfidf = vectorizer.fit_transform(data)
这将大大加快问题的解决速度。
如果我完全错了并且这不是词频问题,我仍然会寻找限制您尝试分解的初始矩阵的方法。
【讨论】:
scipy 的 NMF 方法是否仅针对矩阵的非零条目计算错误?零条目意味着缺失值。是否使用正则化来确保解决方案的稀疏性?我没有在文档中找到详细信息。也许需要挖掘代码。一个一般用例,也涉及词频,但也涉及项目标签之类的东西。这个矩阵非常稀疏。您的解决方案听起来不错,但是当矩阵很大时,仍然无法扩展。假设我想找出被标记少于 2 次的项目,或者属于少于 5 个项目的标签。如何将它们全部过滤掉? 我假设您的意思是 scikit 的 NMF 方法而不是 scipy 的?算法如何处理稀疏可以由参数“稀疏”设置。它在文档中。对于最后两种情况,我不明白您为什么要为此使用 NMF。我认为还有其他更合适的工具。 是的,scikit。你在说什么其他工具? 我说的是 scikit-learn。你是那个提到 scipy 的人。 我的意思是 scikit-learn。我很抱歉造成混乱。 scipy 甚至没有 NMF。【参考方案2】:您可能想看看这篇讨论 NMF 最新技术的文章:http://www.cc.gatech.edu/~hpark/papers/nmf_blockpivot.pdf
这个想法是只对非零项进行分解,从而减少计算时间,尤其是当涉及的矩阵/矩阵非常稀疏时。
此外,同一篇文章中的一位作者在 github 上创建了 NMF 实现,包括他们文章中提到的那些。这是链接:https://github.com/kimjingu/nonnegfac-python
希望对您有所帮助。
【讨论】:
【参考方案3】:老问题,新答案。
OP 要求“零掩码”NMF,其中零被视为缺失值。这永远不会比正常的 NMF 更快。通过交替最小二乘法考虑 NMF,这里方程组的左侧通常是常数(它只是 W
或 H
的 tcrossprod
),但在零掩码 NMF 中它需要重新为每个样本或特征计算。
我在 RcppML R 包中实现了零掩码 NMF。您可以从 CRAN 安装它并使用 nmf
函数将 mask_zeros
参数设置为 TRUE
:
install.packages("RcppML")
A <- rsparsematrix(1000, 1000, 0.1) # simulate random matrix
model <- RcppML::nmf(A, k = 10, mask_zeros = TRUE)
我的 NMF 实现比没有屏蔽零的 scikit-learn 更快,并且对于 99% 的稀疏矩阵来说应该不会太慢。
【讨论】:
以上是关于大型稀疏矩阵上的快速非负矩阵分解的主要内容,如果未能解决你的问题,请参考以下文章