R 中的在线 PCA

Online PCA in R

我正在尝试用 R 编写在线 PCA 代码,目前没有可用的此代码实现,因此,它可能对其他人也有用。可以找到伪代码 here(算法 1)。目前我所做的如下:

PCA<-function(X,k,epsilon){
    X_f<-norm(as.matrix(X),"f")
    d<-nrow(X)
    n<-ncol(X)
    l<-floor((8*k)/(epsilon^2))
    U<-matrix(0,d,l)
    C<-matrix(0,d,d)
    Y<-matrix(0,n,l)
    for(t in 1:n){
        r<-X[,t]-(U%*%t(U)%*%X[,t])
        n<-C + r%*%t(r)
        while(norm(n,"2") >= 2*(X_f^2)/l){
            lamb<-eigen(C)$values[1]
            u<-eigen(C)$vectors[,1]
            U<-cbind(U,u)
            #U[,which(!apply(U==0,2,all))]
            C<-C-(lamb*(u%*%t(u)))
            r<-X[,t]-(U%*%t(U)%*%X[,t])
        }
        C<-C+(r%*%t(r))
        y<-matrix(0,1,l)    
        y<-t(U)%*%x_t
        Y[t,]<-y
    }
    return(Y)
}

为了测试代码,我使用了著名的 fisher iris 数据:

log.ir <- log(iris[, 1:4])
ir.species <- iris[, 5]

ir.pca <- PCA(log.ir,50,0.2) 

代码中似乎有一个错误,这对我来说不是很明显,while 循环永远不会停止,有人可以帮忙吗?

因为while(norm(n,"2") >= 2*(X_f^2)/l)永远不会结束,2*(X_f^2)/l)总是小于norm(n,"2")

事实上,如果你打印出这些值,debug(PCA)你会发现它们永远不会改变

function(X,k,epsilon){
  X_f<-norm(as.matrix(X),"f")
  d<-nrow(X)
  n<-ncol(X)
  l<-floor((8*k)/(epsilon^2))
  U<-matrix(0,d,l)
  C<-matrix(0,d,d)
  Y<-matrix(0,n,l)
  for(t in 1:n){
    r<-X[,t]-(U%*%t(U)%*%X[,t])
    n<-C + r%*%t(r)
    while(norm(n,"2") >= 2*(X_f^2)/l){
      print(norm(n,"2") )
      print(2*(X_f^2)/l)
      lamb<-eigen(C)$values[1]
      u<-eigen(C)$vectors[,1]
      U<-cbind(U,u)
      U[,which(!apply(U==0,2,all))]
      C<-C-(lamb*(u%*%t(u)))
      r<-X[,t]-(U%*%t(U)%*%X[,t])
    }
    C<-C+(r%*%t(r))
    y<-matrix(0,1,l)    
    y<-t(U)%*%x_t
    Y[t,]<-y
  }
  return(Y)
}

debug(PCA)

一般来说,在要调试的函数中使用 print 语句是诊断问题的好方法。