2016-10-27 194 views
0

我想在R代碼在線PCA,這個代碼沒有現有的實現可用,因此,它可能對其他人有用。可以找到僞代碼here(算法1)。我到目前爲止已經完成如下:在線PCA在R

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) 
} 

爲了測試我使用了著名的漁民虹膜數據代碼:

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

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

似乎是在代碼中的錯誤,這是不對我來說如此明顯,while循環從不停止,有人可以幫忙嗎?

+1

這個算法不是一般的,有一個2算法在同一篇論文的附錄中更有用 – Jamil

回答

1

這是因爲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語句是診斷問題的好方法。

+0

給讀者的提示:這個答案不會給出正確的算法實現,它只包含額外的'print '陳述。 – knb