6

使用 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 的包/工具的建议。我知道不鼓励提出有关包/工具选择的问题,但是对于这样一个特定的用例,了解该领域的其他人使用什么技术会非常有帮助。

4

3 回答 3

2

也许关于最初问题的几句话可以让我们给出更好的答案。

由于问题的性质,对非常大的矩阵进行矩阵分解总是会很慢。

建议:减少n_components到 < 20 会加快速度。但是,唯一真正提高速度的方法是限制矩阵的大小。使用您描述的矩阵,您可能会认为您正在尝试分解术语频率矩阵。如果是这样,您可以尝试使用 scikit-learn 中的向量化函数来限制矩阵的大小。它们中的大多数都有一个max_features参数。例子:

vectorizer = TfidfVectorizer(
    max_features=10000,
    ngram_range=(1,2))
tfidf = vectorizer.fit_transform(data)

这将大大加快解决问题的速度。

如果我完全错误并且这不是术语频率问题,我仍然会寻找限制您尝试分解的初始矩阵的方法。

于 2015-07-23T13:14:23.183 回答
2

您可能想看看这篇讨论 NMF 最新技术的文章:http ://www.cc.gatech.edu/~hpark/papers/nmf_blockpivot.pdf

这个想法是只对非零条目进行分解,这减少了计算时间,特别是当所涉及的矩阵/矩阵非常稀疏时。

此外,同一篇文章中的一位作者在 github 上创建了 NMF 实现,包括他们文章中提到的那些。这是链接:https ://github.com/kimjingu/nonnegfac-python

希望有帮助。

于 2015-12-14T13:33:34.803 回答
0

老问题,新答案。

OP 要求“零掩码”NMF,其中零被视为缺失值。这永远不会比正常的 NMF 更快。通过交替最小二乘来考虑 NMF,这里方程组的左侧通常是常数(它只是tcrossprodWH,但在零掩码 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% 的稀疏矩阵来说应该不会太慢。

于 2021-09-03T00:33:22.407 回答