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
语句是诊断问题的好方法。
我正在尝试用 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
语句是诊断问题的好方法。