Solved – Project new data using independent components analysis

independent component analysispcar

I’m trying to project new data into a space I created with icafast. The R package ica does not come with it's own predict function. Here is my attempt to do so. This is in vein of what I can do with principle component analysis (PCA).

########## PCA #############
library(stats)
data = replicate(10, rnorm(20)) 
new.data = replicate(10, rnorm(20))
pca = princomp(data)
predict(pca, new.data)

####### trying ica #########
library(ica)
ica.model = icafast(data, nc=10)

### Trying to write my own based on the paragraph below ####
predict.ica = function(new.data, ica.model) {
  Q = ica.model$Q
      Y = tcrossprod(as.matrix(new.data), Q)
      Y %*% ica.model$R
}

# Should produce the same result as ica.model$S but none are equal
    any(ica.model$S == predict.ica(data, ica.model))

“Whitening Without loss of generality, we can write M=P%%R where P is a tall matrix and R is an
orthogonal rotation matrix. Letting Q denote the pseudoinverse of P, we can whiten the data using
Y=tcrossprod(X,Q). The goal is to find the orthongal rotation matrix R such that the source signal
estimates S=Y%
%R are as independent as possible. Note that W=crossprod(R,Q).“

Any ideas, what I’m doing wrong?

Best Answer

The function above doesn't work correct! When you predict you should scale using the original data, not the data you're tring to predict ('new.data' in your case).

One simple example. Let assume that you want to get prediction for just one observation (i.e. one row). What would be the prediction?

> scale(matrix(1:4, nrow = 1), scale = FALSE)
      [,1] [,2] [,3] [,4]
[1,]    0    0    0    0

So, the function returns zeros..

One way to fix the problem:

predict.ica = function(new.data, ica.model) {
    new.data <- scale(as.matrix(new.data), center = ica.model$center, scale = FALSE)
    Q = ica.model$Q
    Y = tcrossprod(new.data, Q)
    Y %*% ica.model$R
}

ica.model = icafast(data, nc=10)
ica.model$center = colMeans(data)
predict.ica(new.data, ica.model)