gpt4 book ai didi

r - R中的对称非负矩阵分解

转载 作者:行者123 更新时间:2023-12-03 19:54:11 28 4
gpt4 key购买 nike

我正在尝试根据以下公式在 R 中实现 NMF:
H 最初是猜测,然后根据这个公式迭代更新。我写了这段代码,但它需要像以往一样执行。我怎样才能重写这段代码? W 是相似度矩阵。

sym.nmf <- function ( W )
{
N <- ncol(W)
set.seed(1234)
H <- matrix(runif(N * k, 0, 1),N,k)

J1 <- 0

while (0 < 1)
{
HT <- t(H)
A <- W %*% H
B <- H %*% HT %*% H
H <- 0.5 * ( H * ( 1 + ( A / B )))
J = W - (H %*% t(H))
J = sum (J^2)
if ( (J1 != 0 ) && (J > J1) )
return (H1)
H1 <- H
J1 <- J
}

}

最佳答案

这是 sym.nmf 的返工功能在此过程中具有一些统计上重要的改进和速度增益。

  • 添加 相对公差 ( rel.tol ) 当 J[i] 在 rel.tol 内时中断循环的参数J[i-1] 的百分比。按照您的设置方式,您只会在 0 == 1 或机器精度变得比拟合本身更易变时停止循环。理论上,您的函数永远不会收敛。
  • 添加 种子 ,因为可重复性很重要。沿着这条路线,您可能会考虑使用非负双 SVD 进行初始化以抢占先机。但是,根据您的应用程序,这可能会使您的 NMF 进入不代表全局最小值的局部最小值,因此可能很危险。在我的情况下,我被锁定在一个类似于 SVD 的最小值中,并且 NMF 最终会收敛到一个完全不同于随机初始化分解的状态。
  • 添加 最大迭代次数 ( max.iter ),因为有时您不想运行一百万次迭代来达到您的容忍阈值。
  • 代入 crossprodtcrossprod 基础函数 %*%功能。根据矩阵大小,这将获得大约 2 倍的速度增益。
  • 减少检查收敛的次数 ,因为计算W中的残差信号减去 HH^T 后占用了近一半的计算时间。您可以假设需要数百到数千次迭代才能收敛,因此只需每 100 个周期检查一次收敛。

  • 更新功能:
    sym.nmf <- function (W, k, seed = 123, max.iter = 10000, rel.tol = 1e-10) {
    set.seed(seed)
    H <- matrix(runif(ncol(W) * k, 0, 1),ncol(W),k)
    J <- c()
    for(i in 1:max.iter){
    H <- 0.5*(H*(1+(crossprod(W,H)/tcrossprod(H,crossprod(H)))))

    # check for convergence every 100 iterations
    if(i %% 100 == 0){
    J <- c(J,sum((W - tcrossprod(H))^2))
    plot(J, xlab = "iteration", ylab = "total residual signal", log = 'y')
    cat("Iteration ",i,": J =",tail(J)[1],"\n")
    if(length(J) > 3 && (1 - tail(J, 1)/tail(J, 2)[1]) < rel.tol){
    return(H)
    }
    }
    if(i == max.iter){
    warning("Max.iter was reached before convergence\n")
    return(H)
    }
    }
    }
    目标函数也可以隔离,Rfast可以用于 Rfast::Crossprod()的并行计算和 Rfast::Tcrossprod()以及。
    sym.nmf <- function (W, k, seed = 123, max.iter = 100, rel.tol = 1e-10) {
    set.seed(seed)
    require(Rfast)
    H <- matrix(runif(ncol(W) * k, 0, 1),ncol(W),k)
    J <- c()
    for(i in 1:max.iter){
    H <- 0.5 * fit_H(W,H, num.iter = 100)
    J <- c(J,sum((W - tcrossprod(H))^2))
    plot(J, xlab = "iteration", ylab = "total residual signal", log = 'y')
    cat("Iteration ",i,": J =",tail(J, n = 1),"\n")
    if(length(J) > 3 && (1 - tail(J, 1)/tail(J, 2)[1]) < rel.tol){
    return(H)
    }
    if(i == max.iter){
    warning("Max.iter was reached before convergence\n")
    return(H)
    }
    }
    }

    fit_H <- function(W,H, num.iter){
    for(i in 1:num.iter){
    H <- 0.5*(H*(1+(Rfast::Crossprod(W,H)/Rfast::Tcrossprod(H,Rfast::Crossprod(H,H)))))
    }
    H
    }
    现在可以将此目标函数转换为 Rcpp 以进一步提高速度。并行化还可以在目标函数(并行化 crossprodtcrossprod )内或通过并行运行多个分解(因为通常需要多次重新启动才能发现稳健的解决方案)来获得进一步的 yield 。

    关于r - R中的对称非负矩阵分解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35347453/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com