Algorithm comparison

Cristian Castiglione

Workspace setup

Load the package in the workspace.

library(sgdGMF)

Load other useful packages in the workspace.

library(ggplot2)
library(ggpubr)
library(reshape2)

Ant traits data

Load the ant traits data in the workspace and define the response matrix Y and covariate matrices X and Z.

# install.packages("mvabund")
# data(antTraits, package = "mvabund")

load(url("https://raw.githubusercontent.com/cran/mvabund/master/data/antTraits.RData"))

Y = as.matrix(antTraits$abund)
X = as.matrix(antTraits$env[,-3])
Z = matrix(1, nrow = ncol(Y), ncol = 1)

n = nrow(Y)
m = ncol(Y)

Model specification

Set the model family to Poisson since the response matrix contain count data.

family = poisson()

Select the optimal number of latent factors using the function , which employs an adjusted eigenvalue thresholding method to identify the optimal elbow point of a screeplot.

ncomp = sgdgmf.rank(Y = Y, X = X, Z = Z, family = family)$ncomp
cat("Selected rank: ", ncomp)
#> Selected rank:  2

Model estimation

implements four estimation algorithms which are outlined below. Notice that we here describe the algorithms by assuming, without loss of generality, that \(B = 0\) and \(A = 0\) (see the documentation of the function for the notation). In the real implementation, where non-zero \(B\) and \(A\) are considered, we jointly optimize \([A, U]\) and \([B, V]\) following the same algorithmic strategy, but accounting for regression effects.

Estimate a Poisson GMF model using iterated least squares, diagonal quasi-Newton and stochastic gradient descent algorithms.

gmf.airwls = sgdgmf.fit(Y, X, Z, ncomp = ncomp, family = family, method = "airwls")
gmf.newton = sgdgmf.fit(Y, X, Z, ncomp = ncomp, family = family, method = "newton")
gmf.sgd    = sgdgmf.fit(Y, X, Z, ncomp = ncomp, family = family, method = "sgd", sampling = "block")

Model validation

Compute the correlation between the observed data and the predicted values.

cat(" AIRWLS: ", 100 * round(cor(c(Y), c(gmf.airwls$mu)), 4), "\n",
    " Newton: ", 100 * round(cor(c(Y), c(gmf.newton$mu)), 4), "\n",
    " SGD:    ", 100 * round(cor(c(Y), c(gmf.sgd$mu)), 4), sep = "")
#>  AIRWLS: 90.26
#>  Newton: 89.62
#>  SGD:    89.98

Compute the partial deviance residuals holding out from the model the estimated matrix factorization. Additionally, compute the spectrum of such a residual matrix.

res.airwls = residuals(gmf.airwls, partial = FALSE, spectrum = TRUE, ncomp = 20)
res.newton = residuals(gmf.newton, partial = FALSE, spectrum = TRUE, ncomp = 20)
res.sgd = residuals(gmf.sgd, partial = FALSE, spectrum = TRUE, ncomp = 20)

Analyze the residual distribution.

Plot the variance explained by each principal component of the residual matrix.

Observations vs fitted values

Plot the abundance predicted by each method comparing it with the observed matrix.

Latent scores and low-dimensional representation

Plot the latent scores and loadings in a biplot-like figure.