<-function(W,r,weights=NULL,rsvd.use=FALSE){
BONMI#Input:
##W: a list of PPMI matrices, with rownames and colnames being the features
##r: rank
##weights: the weight vector for the PPMI matrices. If weights = NULL, then it will be estimated from data.
##rsvd.use: If rsvd.use=TRUE, we will use the 'rsvd' function to calculate the svd, which is much faster than the 'svd' function when r is small.
= length(W)
m = NULL
codes for(s in 1:m){
= union(codes,rownames(W[[s]]))
codes
}= sort(codes)
codes
if(is.null(weights)){
= sapply(1:m, function(s){
weights if(rsvd.use){
set.seed(1)
= rsvd(W[[s]],r+1)
fit else{
}= svd(W[[s]],r+1,r+1)
fit
}= fit$d[r+1]/sqrt(nrow(W[[s]]))
w return(w)
})
}
= matrix(0,nrow=length(codes),ncol=length(codes))
Wc = matrix(0,nrow=length(codes),ncol=length(codes))
C = matrix(0,nrow=length(codes),ncol=length(codes))
Weis
rownames(Wc) = colnames(Wc) = codes
rownames(C) = colnames(C) = codes
rownames(Weis) = colnames(Weis) = codes
for(s in 1:m){
= match(rownames(W[[s]]),codes)
id = Wc[id,id] + weights[s]*W[[s]]
Wc[id,id] = C[id,id]+1
C[id,id] = Weis[id,id]+weights[s]
Weis[id,id]
}>0] = Wc[C>0]/Weis[C>0]
Wc[C= Wc; Wo[C==0] = NA
Wo
= list()
W.new for(s in 1:m){
= match(rownames(W[[s]]),rownames(Wc))
Is = Wc[Is,Is]
W.new[[s]]
}
= lapply(1:m, function(s){
fits if(rsvd.use){
set.seed(1)
return(rsvd(W.new[[s]],r))
else{
}return(svd(W.new[[s]],r,r))
}
})
= lapply(1:m, function(s){
Xs = embedding(fits[[s]],r)
U rownames(U) = rownames(W[[s]])
U
})
= matrix(0,nrow=nrow(Wc),ncol=ncol(Wc))
Wm = matrix(0,nrow=nrow(Wc),ncol=ncol(Wc))
M rownames(Wm) = colnames(Wm) = rownames(Wc)
rownames(M) = colnames(M) = rownames(Wc)
for(s in 1:(m-1)){
for(k in (s+1):m){
= intersect(rownames(W[[s]]),rownames(W[[k]]))
name12 = match(name12,rownames(W[[s]]))
ids = match(name12,rownames(W[[k]]))
idk = Procrustes(Xs[[s]][ids,],Xs[[k]][idk,])
Osk = Xs[[s]][-ids,]%*%t(Osk)%*%t(Xs[[k]][-idk,])
Wsk = match(rownames(W[[s]])[-ids],rownames(Wm))
id1 = match(rownames(W[[k]])[-idk],rownames(Wm))
id2 = Wm[id1,id2]+Wsk; Wm[id2,id1] = Wm[id2,id1]+t(Wsk)
Wm[id1,id2] = M[id1,id2] + 1; M[id2,id1] = M[id2,id1] + 1
M[id1,id2]
}
}>0] = Wm[M>0]/M[M>0]
Wm[M>0] = Wc[C>0]
Wm[C
if(rsvd.use){
set.seed(1)
= rsvd(Wm,r)
fit.W else{
}= svd(Wm,r,r)
fit.W
}
= embedding(fit.W,r)
X rownames(X) = rownames(Wm)
return(X)
}
BONMI function
Description
The BONMI
function is the main function for learning a unified low-dimensional representation from a list of PPMI matrices. It performs dimensionality reduction and aligns the matrices to ensure consistency across datasets, optionally using randomized SVD for efficiency.
Arguments
W
: A list of PPMI matrices, where each matrix has row and column names corresponding to features.r
: The target rank for dimensionality reduction (number of components to retain).weights
(optional): A vector of weights for each matrix inW
, used to influence their contributions during the embedding process.rsvd.use
(optional, defaultFALSE
): A boolean flag indicating whether to use randomized SVD (TRUE
) or standard SVD (FALSE
).
Output
- Returns a list containing the learned low-dimensional representations of the input matrices and the aligned transformation matrices for consistency across datasets.
See also
See BONMI_package for code example.