I am trying to make a Python interface for the brilliant NMF package - https://cran.r-project.org/web/packages/NMF/NMF.pdf (as it is much more flexible than the Python options). So far so good.
I come up with something like this:
# Python rpy2
__NMF = importr("NMF")
n_comp_R = robjects.IntVector(n_components)
nmf_ro = self.__NMF.nmf(data, n_comp_R, methods, self.seed, nrun=10)
It works like a charm. Methods is a list of possible algorithms that I can use:
nmfAlgorithm()
[1] "brunet" "KL" "lee" "Frobenius" "offset"
[6] "nsNMF" "ls-nmf" "pe-nmf" "siNMF" "snmf/r"
[11] "snmf/l"
Other possibility is to use a custom algorithm, as it is described in the NMF documentation
# R code
my.algorithm <- function(x, seed, param.1, param.2) {
# do something with starting point ...
# return updated starting point
return(seed)
}
res <- nmf(data, n_comp, my.algorithm)
How can I reproduce this using rpy2
?
I've tried something like:
import rpy2.robjects as robjects
my_algorithm = robjects.r('''
function (x, seed, scale.factor = 1)
{
pca <- prcomp(t(x), retx = TRUE)
factorization.rank <- nbasis(seed)
cat(seed)
basis(seed) <- abs(pca$rotation[, 1:factorization.rank])
coef(seed) <- t(abs(pca$x[, 1:factorization.rank]))/scale.factor
return(seed)
}
''')
nmf_ro = __NMF.nmf(data, n_comp_R, my_algorithm.r_repr(), nrun=1)
But it didn't make the magic =(
NMF algorithm - No matching entry for key “key=function (x, seed, scale.factor >= 1)
{
pca <- prcomp(t(x), retx = TRUE)
factorization.rank <- nbasis(seed)
cat(seed)
basis(seed) <- abs(pca$rotation[, 1:factorization.rank])
coef(seed) <- t(abs(pca$x[, 1:factorization.rank]))/scale.factor
return(seed)
}” in the registry.
Use one of: 'brunet', 'Frobenius', 'KL', 'lee', 'ls-nmf', '.M#brunet', 'nsNMF', 'offset', 'pe-nmf', '.R#brunet', '.R#lee', '.R#nsNMF', '.R#offset', 'siNMF', '.siNMF', 'snmf/l', 'snmf/r'.
warnings.warn(x, RRuntimeWarning)
I wonder whether could someone help me here?
The original questioner had his question answered on the NMF project on Github. As described there, you define your new algorithm as a function, then use setNMFMethod to add the function to the registry of algorithms that perform Nonnegative Matrix Factorization, and then you can call it by name.