cv.missoNet {missoNet} | R Documentation |
Cross-validation for missoNet
Description
This function performs k-fold cross-validation for ‘missoNet
’. The regularization path is computed
for all possible combinations of values given in the two regularization parameter sequences, namely λB
and λΘ
.
‘cv.missoNet
’ will select the most suitable model among all cross-validated fits along the path.
See the details of ‘missoNet
’ for the model definition.
To help users, the ‘cv.missoNet
’ function is designed to automatically determine the likely ranges
of the regularization parameters over which the cross-validation searches.
Usage
cv.missoNet(
X,
Y,
kfold = 5,
rho = NULL,
lambda.Beta = NULL,
lambda.Theta = NULL,
lamBeta.min.ratio = NULL,
lamTheta.min.ratio = NULL,
n.lamBeta = NULL,
n.lamTheta = NULL,
lamBeta.scale.factor = 1,
lamTheta.scale.factor = 1,
Beta.maxit = 1000,
Beta.thr = 1e-04,
eta = 0.8,
Theta.maxit = 1000,
Theta.thr = 1e-04,
eps = 1e-08,
penalize.diagonal = TRUE,
diag.penalty.factor = NULL,
standardize = TRUE,
standardize.response = TRUE,
fit.1se = FALSE,
fit.relax = FALSE,
permute = TRUE,
with.seed = NULL,
parallel = FALSE,
cl = NULL,
verbose = 1
)
Arguments
X |
Numeric predictor matrix (n×p ): columns correspond to predictor variables and rows correspond to samples. Missing values are not allowed. There is no need for centering or scaling of the variables. 'X' should not include a column of ones for an intercept.
|
Y |
Numeric response matrix (n×q ): columns correspond to response variables and rows correspond to samples. Missing values should be coded as either 'NA' s or 'NaN' s. There is no need for centering or scaling of the variables.
|
kfold |
Number of folds for cross-validation – the default is '5' .
|
rho |
(Optional) A scalar or a numeric vector of length q : the elements are user-supplied probabilities of missingness for the response variables. The default is 'rho = NULL' and the program will compute the empirical missing rates for each of the columns of 'Y' and use them as the working missing probabilities. The default setting should suffice in most cases; misspecified missing probabilities would introduce biases into the model.
|
lambda.Beta |
(Optional) Numeric vector: a user-supplied sequence of non-negative values for {λB } penalizing the elements of the coefficient matrix B among which the cross-validation procedure searches. The default is 'lambda.Beta = NULL' , in which case the program computes an appropriate range of λB values using 'n.lamBeta' and 'lamBeta.min.ratio' . Supplying a vector overrides this default. Note that the supplied sequence will be automatically arranged, internally, in a descending order.
|
lambda.Theta |
(Optional) Numeric vector: a user-supplied sequence of non-negative values for {λΘ } penalizing the (off-diagonal) elements of the precision matrix Θ among which the cross-validation procedure searches. The default is 'lambda.Theta = NULL' , in which case the program computes an appropriate range of λΘ values using 'n.lamTheta' and 'lamTheta.min.ratio' . Supplying a vector overrides this default. Note that the supplied sequence will be automatically arranged, internally, in a descending order.
|
lamBeta.min.ratio |
The smallest value of λB is calculated as the data-derived max(λB) multiplied by 'lamBeta.min.ratio' . The default depends on the sample size, n , relative to the number of predictors, p . If n>p , the default is '1.0E-4' , otherwise it is '1.0E-3' . A very small value of 'lamBeta.min.ratio' may significantly increase runtime and lead to a saturated fit in the n≤p case. This is only needed when 'lambda.Beta = NULL' .
|
lamTheta.min.ratio |
The smallest value of λΘ is calculated as the data-derived max(λΘ) multiplied by 'lamTheta.min.ratio' . The default depends on the sample size, n , relative to the number of responses, q . If n>q , the default is '1.0E-4' , otherwise it is '1.0E-3' . A very small value of 'lamTheta.min.ratio' may significantly increase runtime and lead to a saturated fit in the n≤q case. This is only needed when 'lambda.Theta = NULL' .
|
n.lamBeta |
The number of λB values. If n>p , the default is '40' , otherwise it is '30' . Avoid supplying an excessively large number since the program will fit ('n.lamBeta' * 'n.lamTheta' ) models in total for each fold of the cross-validation. Typically we suggest 'n.lamBeta' = -log10('lamBeta.min.ratio') * c , where c ∈ [10 , 20 ]. This is only needed when 'lambda.Beta = NULL' .
|
n.lamTheta |
The number of λΘ values. If n>q , the default is '40' , otherwise it is '30' . Avoid supplying an excessively large number since the program will fit ('n.lamBeta' * 'n.lamTheta' ) models in total for each fold of the cross-validation. Typically we suggest 'n.lamTheta' = -log10('lamTheta.min.ratio') * c , where c ∈ [10 , 20 ]. This is only needed when 'lambda.Theta = NULL' .
|
lamBeta.scale.factor |
A positive multiplication factor for scaling the entire λB sequence; the default is '1' . A typical usage is when the magnitudes of the auto-computed λB values are inappropriate. For example, this factor would be needed if the optimal value of λB selected by the cross-validation (i.e. λBmin with the minimum cross-validated error) approaches either boundary of the search range. This is only needed when 'lambda.Beta = NULL' .
|
lamTheta.scale.factor |
A positive multiplication factor for scaling the entire λΘ sequence; the default is '1' . A typical usage is when the magnitudes of the auto-computed λΘ values are inappropriate. For example, this factor would be needed if the optimal value of λΘ selected by the cross-validation (i.e. λΘmin with the minimum cross-validated error) approaches either boundary of the search range. This is only needed when 'lambda.Theta = NULL' .
|
Beta.maxit |
The maximum number of iterations of the fast iterative shrinkage-thresholding algorithm (FISTA) for updating B^ . The default is 'Beta.maxit = 1000' .
|
Beta.thr |
The convergence threshold of the FISTA algorithm for updating B^ ; the default is 'Beta.thr = 1.0E-4' . Iterations stop when the absolute parameter change is less than ('Beta.thr' * sum(abs( B^ )) ).
|
eta |
The backtracking line search shrinkage factor; the default is 'eta = 0.8' . Most users will be able to use the default value, some experienced users may want to tune 'eta' according to the properties of a specific dataset for a faster convergence of the FISTA algorithm. Note that 'eta' must be in (0, 1).
|
Theta.maxit |
The maximum number of iterations of the ‘glasso ’ algorithm for updating Θ^ . The default is 'Theta.maxit = 1000' .
|
Theta.thr |
The convergence threshold of the ‘glasso ’ algorithm for updating Θ^ ; the default is 'Theta.thr = 1.0E-4' . Iterations stop when the average absolute parameter change is less than ('Theta.thr' * ave(abs(offdiag( Σ^ ))) ), where Σ^ denotes the empirical working covariance matrix.
|
eps |
A numeric tolerance level for the L1 projection of the empirical covariance matrix; the default is 'eps = 1.0E-8' . The empirical covariance matrix will be projected onto a L1 ball to have min(eigen( Σ^ )$value) == 'eps' , if any of the eigenvalues is less than the specified tolerance. Most users will be able to use the default value.
|
penalize.diagonal |
Logical: should the diagonal elements of Θ be penalized? The default is 'TRUE' .
|
diag.penalty.factor |
Numeric: a separate penalty multiplication factor for the diagonal elements of Θ when 'penalize.diagonal = TRUE' . λΘ is multiplied by this number to allow a differential shrinkage of the diagonal elements. The default is 'NULL' and the program will guess a value based on an initial estimate of Θ . This factor could be '0' for no shrinkage (equivalent to 'penalize.diagonal = FALSE' ) or '1' for an equal shrinkage.
|
standardize |
Logical: should the columns of 'X' be standardized so each has unit variance? The default is 'TRUE' . The estimated results will always be returned on the original scale. ‘cv.missoNet ’ computes appropriate λ sequences relying on standardization, if 'X' has been standardized prior to fitting the model, you might not wish to standardize it inside the algorithm.
|
standardize.response |
Logical: should the columns of 'Y' be standardized so each has unit variance? The default is 'TRUE' . The estimated results will always be returned on the original scale. ‘cv.missoNet ’ computes appropriate λ sequences relying on standardization, if 'Y' has been standardized prior to fitting the model, you might not wish to standardize it inside the algorithm.
|
fit.1se |
Logical: the default is 'FALSE' . If 'TRUE' , two additional models will be fitted with the largest values of λB and λΘ respectively at which the cross-validated error is within one standard error of the minimum.
|
fit.relax |
Logical: the default is 'FALSE' . If 'TRUE' , the program will re-estimate the edges in the active set (i.e. nonzero off-diagonal elements) of the network structure Θ^ without penalization (λΘ=0 ). This debiased estimate of Θ could be useful for some interdependency analyses. WARNING: there may be convergence issues if the empirical covariance matrix is not of full rank (e.g. n<q) ).
|
permute |
Logical: should the subject indices for the cross-validation be permuted? The default is 'TRUE' .
|
with.seed |
A random number seed for the permutation.
|
parallel |
Logical: the default is 'FALSE' . If 'TRUE' , the program uses clusters to compute the cross-validation folds in parallel. Must register parallel clusters beforehand, see examples below.
|
cl |
A cluster object created by ‘parallel::makeCluster ’ for parallel evaluations. This is only needed when 'parallel = TRUE' .
|
verbose |
Value of '0' , '1' or '2' . 'verbose = 0' – silent; 'verbose = 1' (the default) – limited tracing with progress bars; 'verbose = 2' – detailed tracing. Note that displaying the progress bars slightly increases the computation overhead compared to the silent mode. The detailed tracing should be used for monitoring progress only when the program runs extremely slowly, and it is not supported under 'parallel = TRUE' .
|
Details
The ‘cv.missoNet
’ function fits ‘missoNet
’ models ('kfold'
*
'n.lamBeta'
*
'n.lamTheta'
)
times in the whole cross-validation process. That is, for the k
th-fold (k=1,...,K
) computation, the models are fitted at each of
the all ('n.lamBeta'
*
'n.lamTheta'
) possible combinations of the regularization parameters (λB
, λΘ
), with the k
th
fold of the training data omitted. The errors are accumulated, and the averaged errors as well as the standard deviations are computed over all folds.
Note that the results of ‘cv.missoNet
’ are random, since the samples are randomly split into k-folds. Users can eliminate this randomness
by setting 'permute = FALSE'
, or by explicitly assigning a seed to the permutation of samples.
A user-supplied sequence for {λB
} and/or {λΘ
} is permitted,
otherwise the program computes an appropriate range of values for the regularization parameters using other control arguments.
Note that ‘cv.missoNet
’ standardizes 'X'
and 'Y'
to have unit variances before computing its λ
sequences (and then unstandardizes the resulting coefficients); if you wish to reproduce/compare results with those of other softwares,
it is best to supply pre-standardized 'X'
and 'Y'
. If the algorithm is running slowly, track its progress with 'verbose = 2'
.
In most cases, choosing a sparser grid for the regularization parameters (e.g. smaller 'n.lamBeta'
and/or 'n.lamTheta'
) or setting 'Beta.thr = 1.0E-3'
(or even bigger)
allows the algorithm to make faster progress.
After cross-validation, the regression coefficient matrix B
and the precision matrix Θ
can be
estimated at three special λ
pairs, by reapplying ‘missoNet
’ to the entire training dataset:
"lambda.min
" := (λBmin,λΘmin
), at which the minimum mean cross-validated error is achieved;
"lambda.1se.Beta
" := (λB1se,λΘmin
), where λB1se
is the largest λB
at which the mean cross-validated error is within one standard error of the minimum;
"lambda.1se.Theta
" := (λBmin,λΘ1se
), where λΘ1se
is the largest λΘ
at which the mean cross-validated error is within one standard error of the minimum.
The corresponding estimates, along with the λ
values, are stored in three separate lists inside the returned object:
'est.min'
, 'est.1se.B'
and 'est.1se.Tht'
('est.1se.B'
and 'est.1se.Tht'
are 'NULL'
unless the argument 'fit.1se = TRUE'
when calling ‘cv.missoNet
’).
The ‘cv.missoNet
’ function returns an R object of S3 class 'cv.missoNet'
for which there are a set of accessory functions available.
The plotting function ‘plot.cv.missoNet
’ can be used to graphically identify the optimal pair of the regularization parameters,
and the prediction function ‘predict.cv.missoNet
’ can be used to make predictions of response values given new input 'X'
.
See the vignette for examples.
Value
This function returns a 'cv.missoNet'
object containing a named 'list'
with all the ingredients of the cross-validated fit:
est.min |
A 'list' of results estimated at "lambda.min " := (λBmin,λΘmin ) that gives the minimum mean cross-validated error. It consists of the following components:
-
Beta : the penalized estimate of the regression coefficient matrix B^ (p×q ).
-
Theta : the penalized estimate of the precision matrix Θ^ (q×q ).
-
mu : a vector of length q storing the model intercept μ^ .
-
lambda.Beta : the value of λB (i.e. λBmin ) used to fit the model.
-
lambda.Theta : the value of λΘ (i.e. λΘmin ) used to fit the model.
-
relax.net : the relaxed (debiased) estimate of the conditional network structure Θ^rlx (q×q ) if 'fit.relax = TRUE' when calling ‘cv.missoNet ’.
|
est.1se.B |
A 'list' of results estimated at "lambda.1se.Beta " := (λB1se,λΘmin ) if 'fit.1se = TRUE' when calling ‘cv.missoNet ’. "lambda.1se.Beta " refers to the largest λB at which the mean cross-validated error is within one standard error of the minimum, by fixing λΘ at λΘmin . This 'list' consists of the same components as 'est.min' .
|
est.1se.Tht |
A 'list' of results estimated at "lambda.1se.Theta " := (λBmin,λΘ1se ) if 'fit.1se = TRUE' when calling ‘cv.missoNet ’. "lambda.1se.Theta " refers to the largest λΘ at which the mean cross-validated error is within one standard error of the minimum, by fixing λB at λBmin . This 'list' consists of the same components as 'est.min' .
|
rho |
A vector of length q storing the working missing probabilities for the q response variables.
|
fold.index |
The subject indices identifying which fold each observation is in.
|
lambda.Beta.vec |
A flattened vector of length ('n.lamBeta' * 'n.lamTheta' ) storing the λB values along the regularization path. More specifically, 'lambda.Beta.vec' = rep('lambda.Beta', each = 'n.lamTheta') .
|
lambda.Theta.vec |
A flattened vector of length ('n.lamBeta' * 'n.lamTheta' ) storing the λΘ values along the regularization path. More specifically, 'lambda.Theta.vec' = rep('lambda.Theta', times = 'n.lamBeta') .
|
cvm |
A flattened vector of length ('n.lamBeta' * 'n.lamTheta' ) storing the (standardized) mean cross-validated errors along the regularization path.
|
cvup |
Upper cross-validated errors.
|
cvlo |
Lower cross-validated errors.
|
penalize.diagonal |
Logical: whether the diagonal elements of Θ were penalized.
|
diag.penalty.factor |
The additional penalty multiplication factor for the diagonal elements of Θ when 'penalize.diagonal' was returned as 'TRUE' .
|
Author(s)
Yixiao Zeng yixiao.zeng@mail.mcgill.ca, Celia M.T. Greenwood and Archer Yi Yang.
Examples
## Simulate a dataset with response values missing completely at random (MCAR),
## the overall missing rate is around 10%.
set.seed(123) # reproducibility
sim.dat <- generateData(n = 300, p = 50, q = 20, rho = 0.1, missing.type = "MCAR")
tr <- 1:240 # training set indices
tst <- 241:300 # test set indices
X.tr <- sim.dat$X[tr, ] # predictor matrix
Y.tr <- sim.dat$Z[tr, ] # corrupted response matrix
## Perform a five-fold cross-validation WITH specified 'lambda.Beta' and 'lambda.Theta'.
## 'standardize' and 'standardize.response' are 'TRUE' by default.
lamB.vec <- 10^(seq(from = 0, to = -1, length.out = 5))
lamTht.vec <- 10^(seq(from = 0, to = -1, length.out = 5))
cvfit <- cv.missoNet(X = X.tr, Y = Y.tr, kfold = 5,
lambda.Beta = lamB.vec, lambda.Theta = lamTht.vec)
## Perform a five-fold cross-validation WITHOUT specified 'lambda.Beta' and 'lambda.Theta'.
## In this case, a grid of 'lambda.Beta' and 'lambda.Theta' values in a (hopefully) reasonable
## range will be computed and used by the program.
##
## < This simplest command should be a good start for most analyses. >
cvfit <- cv.missoNet(X = X.tr, Y = Y.tr, kfold = 5)
## Alternatively, compute the cross-validation folds in parallel on a cluster with 2 cores.
##
## 'fit.1se = TRUE' tells the program to make additional estimations of the parameters at the
## largest value of 'lambda.Beta' / 'lambda.Theta' that gives the most regularized model such
## that the cross-validated error is within one standard error of the minimum.
cl <- parallel::makeCluster(min(parallel::detectCores()-1, 2))
cvfit <- cv.missoNet(X = X.tr, Y = Y.tr, kfold = 5, fit.1se = TRUE,
parallel = TRUE, cl = cl,
permute = TRUE, with.seed = 486) # permute with seed for reproducibility
parallel::stopCluster(cl)
## Use PRE-STANDARDIZED training data if you wish to compare the results with other softwares.
X.tr.std <- scale(X.tr, center = TRUE, scale = TRUE)
Y.tr.std <- scale(Y.tr, center = TRUE, scale = TRUE)
cvfit.std <- cv.missoNet(X = X.tr.std, Y = Y.tr.std, kfold = 5,
standardize = FALSE, standardize.response = FALSE)
## Plot the (standardized) mean cross-validated errors in a heatmap.
plot(cvfit, type = "cv.heatmap")
## Plot the (standardized) mean cross-validated errors in a 3D scatterplot.
plot(cvfit, type = "cv.scatter", plt.surf = TRUE)
## Extract the estimates at "lambda.min".
Beta.hat1 <- cvfit$est.min$Beta
Theta.hat1 <- cvfit$est.min$Theta
## Extract the estimates at "lambda.1se.Beta" (if 'fit.1se' = TRUE).
Beta.hat2 <- cvfit$est.1se.B$Beta
Theta.hat2 <- cvfit$est.1se.B$Theta
## Extract the estimates at "lambda.1se.Theta" (if 'fit.1se' = TRUE).
Beta.hat3 <- cvfit$est.1se.Tht$Beta
Theta.hat3 <- cvfit$est.1se.Tht$Theta
## Make predictions of response values on the test set.
newy1 <- predict(cvfit, newx = sim.dat$X[tst, ], s = "lambda.min")
newy2 <- predict(cvfit, newx = sim.dat$X[tst, ], s = "lambda.1se.Beta") # 'fit.1se' = TRUE
newy3 <- predict(cvfit, newx = sim.dat$X[tst, ], s = "lambda.1se.Theta") # 'fit.1se' = TRUE
[Package
missoNet version 1.2.0
Index]