在 R 中执行非负矩阵分解

Posted

技术标签:

【中文标题】在 R 中执行非负矩阵分解【英文标题】:Perform nonnegative matrix factorization in R 【发布时间】:2012-05-02 13:50:21 【问题描述】:

我在 R 中有一个稀疏矩阵

我现在希望对 R 执行非负矩阵分解

data.txt 是我使用 python 创建的一个文本文件,它由 3 列组成,其中第一列指定行号,第二列指定列号,第三列指定值

数据.txt

1 5 10
3 2 5
4 6 9

原始 data.txt 包含 164009 行,是 250000x250000 稀疏矩阵的数据

我用过 NMF 库,我正在做

x=scan('data.txt',what=list(integer(),integer(),numeric()))
library('Matrix')
R=sparseMatrix(i=x[[1]],j=x[[2]],x=x[[3]]) 
res<-nmf(R,3)

它给了我一个错误:

函数错误(类、fdef、mtable):无法找到继承的 函数 nmf 的方法,用于签名“dgCMAtrix”,“缺失”, “失踪”

谁能帮我弄清楚我做错了什么?

【问题讨论】:

提供代码来构建示例稀疏矩阵,以及(工作)代码来运行您的示例。你的意思是 -> 那里,还是应该是 你仍然缺少一块。我没有data.txt。最好发布创建“x”的 R 代码,但发布示例数据本身几乎同样易于使用。 (我不能说其他人,但我更喜欢使用不带 > 提示的示例代码,所以我可以直接将其从网站粘贴到 R 中。) oh data.txt 是我使用 python 创建的一个文本文件,它由 3 列组成,其中第一列指定行号,第二列指定列号,第三列指定值。 重点不是我们不知道data.txt 会有什么样的结构,而是提供一个可重现的例子大大降低了提供问题的障碍;可能的回答者可以从诊断/回答问题开始,而不是从构建示例开始。中途见面:tinyurl.com/reproducible-000 我昨晚刚开始用 R 编码,我有一个非常大的稀疏矩阵数据集......我的稀疏矩阵尺寸是 250000x250000,我真的不知道如何提供可重现的......但是我真的非常感谢您对此提供任何帮助.. 我正在为此工作 24 小时,但在网络上没有得到任何结果 【参考方案1】:

第一个问题是您正在向 nmf 提供 dgCMatrix。

> class(R)
[1] "dgCMatrix"
attr(,"package")
[1] "Matrix"

帮助在这里:

help(nmf)

请参阅方法部分。它需要一个真实的矩阵。由于条目的数量,使用 as.matrix 进行强制可能对您没有多大帮助。

现在,即使使用您的示例数据,对矩阵的强制也是不够的:

> nmf(as.matrix(R))
Error: NMF::nmf : when argument 'rank' is not provided, argument 'seed' is required to inherit from class 'NMF'. See ?nmf.

让我们给它一个排名:

> nmf(as.matrix(R),2)
Error in .local(x, rank, method, ...) : 
  Input matrix x contains at least one null row.

确实如此:

> R
4 x 6 sparse Matrix of class "dgCMatrix"

[1,] . . . . 10 .
[2,] . . . .  . .
[3,] . . 5 .  . .
[4,] . . . .  . 9

【讨论】:

好的,那么解决方案是什么?你是说不可能吗? 您的原始数据以矩阵形式呈现,可能确实是您想要的(但问题中没有指定排名)。不幸的是,这样的矩阵不太可能适合您的记忆。 好的,如果您的答案不是答案,请您删除它,以免其他人误解这个答案 你问,“我做错了什么。”为了让某人回答如何“正确”地做这件事,您需要告诉我们您实际上想要做什么。 @MatthewLundberg:问题是您的“解决方案”不适用于 250000x250000 稀疏矩阵。将其强制为密集矩阵会让您耗尽内存(除非您有 1 TB 的 RAM ... :-)【参考方案2】:

大约 10 年后,有了解决方案。这是一个快速的。

如果您的dgCMatrix 具有 250k 平方的 dgCMatrix,且稀疏度接近 1%,则需要稀疏分解算法。

我为大型稀疏矩阵写了RcppML::NMF

library(RcppML)
A <- rsparsematrix(1000, 10000, 0.01)
model <- RcppML::nmf(A, k = 10)
str(model)

这在笔记本电脑上应该需要几秒钟的时间。

您也可以查看rsparse::WRMF,尽管速度没有那么快。

【讨论】:

【参考方案3】:

现在有一个优秀的 NMF 包可用: https://cran.r-project.org/web/packages/NMF/NMF.pdf

提供各种热图、纯度/熵、一系列不同的 NMF 算法(Brunet、Lee、sNMF、nsNMF、欧几里得/K-L 散度等)以及创建您自己的框架。

试试:

library(NMF)
x = read.table('data.txt')
# estimate rank
estim.x = nmf(x, 2:5, nrun=50, method = 'nsNMF', seed = 'random', .options = "v")
# plot clustering accuracy
plot(estim.x, what = c("cophenetic", "dispersion"))
# inspect consensus matrices
consensusmap(estim.x)

【讨论】:

以上是关于在 R 中执行非负矩阵分解的主要内容,如果未能解决你的问题,请参考以下文章

推荐系统中矩阵分解算法-funkSVD和ALS

推荐算法——非负矩阵分解(NMF)

文本主题模型之非负矩阵分解(NMF)

基于R语言利用NMF(非负矩阵分解)替代层次聚类进行肿瘤分型

推荐系统笔记:基于非负矩阵分解的协同过滤

什么是矩阵的奇异值分解?