| Title: | Smooth L0 Penalty Approximations for Gaussian Graphical Models |
|---|---|
| Description: | Provides smooth approximations to the L0 norm penalty for estimating sparse Gaussian graphical models (GGMs). Network estimation is performed using the Local Linear Approximation (LLA) framework (Fan & Li, 2001 <doi:10.1198/016214501753382273>; Zou & Li, 2008 <doi:10.1214/009053607000000802>) with five penalty functions: arctangent (Wang & Zhu, 2016 <doi:10.1155/2016/6495417>), EXP (Wang, Fan, & Zhu, 2018 <doi:10.1007/s10463-016-0588-3>), Gumbel, Log (Candes, Wakin, & Boyd, 2008 <doi:10.1007/s00041-008-9045-x>), and Weibull. Adaptive penalty parameters for EXP, Gumbel, and Weibull are estimated via maximum likelihood, and model selection uses information criteria including AIC, BIC, and EBIC (Extended BIC). Data simulation from GGMs is provided by the companion package 'psychNetwoRk'. |
| Authors: | Alexander Christensen [aut, cre] (ORCID: <https://orcid.org/0000-0002-9798-7037>), Jeongwon Choi [ctb] (ORCID: <https://orcid.org/0000-0001-6087-2124>), John Fox [cph, ctb] (Original implementation of polyserial correlations in auto_correlate.R), Yves Rosseel [cph, ctb] (Original implementation of rmsea_ci in network_fit.R), Alan Genz [cph, ctb] (Fortran implementation of the bivariate normal CDF (TVPACK MVBVU) in polychoric_matrix.c, translated via the pbivnorm R package) |
| Maintainer: | Alexander Christensen <[email protected]> |
| License: | AGPL (>= 3.0) |
| Version: | 0.2.0 |
| Built: | 2026-11-04 01:36:29 UTC |
| Source: | https://github.com/alexchristensen/l0ggm |
Implements L0 norm regularization penalties for Gaussian graphical models
Alexander P. Christensen <[email protected]>
Useful links:
Report bugs at https://github.com/AlexChristensen/L0ggm/issues
Automatically computes the proper correlations between
continuous and categorical variables. NA values are not treated
as categories
auto_correlate( data, corr = c("kendall", "pearson", "spearman"), ordinal_categories = 7, forcePD = TRUE, na_data = c("pairwise", "listwise"), empty_method = c("none", "zero", "all"), empty_value = c("none", "point_five", "one_over"), forceReturn = FALSE, verbose = FALSE, ... )auto_correlate( data, corr = c("kendall", "pearson", "spearman"), ordinal_categories = 7, forcePD = TRUE, na_data = c("pairwise", "listwise"), empty_method = c("none", "zero", "all"), empty_value = c("none", "point_five", "one_over"), forceReturn = FALSE, verbose = FALSE, ... )
data |
Matrix or data frame. Should consist only of variables to be used in the analysis |
corr |
Character (length = 1).
The standard correlation method to be used.
Defaults to |
ordinal_categories |
Numeric (length = 1).
Up to the number of categories before a variable is considered continuous.
Defaults to |
forcePD |
Boolean (length = 1).
Whether positive definite matrix should be enforced.
Defaults to |
na_data |
Character (length = 1).
How should missing data be handled?
Defaults to
|
empty_method |
Character (length = 1).
Method for empty cell correction in
|
empty_value |
Character (length = 1).
Value to add to the joint frequency table cells in
|
forceReturn |
Boolean (length = 1).
Whether correlation matrix should be forced to return.
Defaults to |
verbose |
Boolean (length = 1).
Whether messages should be printed.
Defaults to |
... |
Not actually used but makes it easier for general functionality in the package |
A symmetric numeric matrix of dimension , where
is the number of variables in data, with values in
and ones on the diagonal. The correlation method used for
each pair of variables depends on their types when corr = "pearson"
(the default): polychoric for ordinal-ordinal pairs, polyserial for
ordinal-continuous pairs, and Pearson's for continuous-continuous pairs,
where ordinal means having at most ordinal_categories unique
values. When corr is "kendall" or "spearman",
cor is used for all pairs regardless of variable
type. Row and column names are inherited from data. When
forcePD = TRUE (default) and the resulting matrix is not positive
definite, the nearest positive definite matrix is returned via
nearPD.
Alexander P. Christensen <[email protected]>
# Obtain correlations R <- auto_correlate(basic_smallworld)# Obtain correlations R <- auto_correlate(basic_smallworld)
A toy small-world network example (n = 500)
data(basic_smallworld)data(basic_smallworld)
A 500 20 continuous response matrix
# Generated using the {psychNetwoRk} package: # basic_smallworld <- psychNetwoRk::simulate_smallworld( # nodes = 20, # 20 nodes in the network # density = 0.30, # moderate initial lattice connectivity # rewire = 0.20, # 20% rewiring probability # sample_size = 500 # number of cases = 500 # )$data data("basic_smallworld")# Generated using the {psychNetwoRk} package: # basic_smallworld <- psychNetwoRk::simulate_smallworld( # nodes = 20, # 20 nodes in the network # density = 0.30, # moderate initial lattice connectivity # rewire = 0.20, # 20% rewiring probability # sample_size = 500 # number of cases = 500 # )$data data("basic_smallworld")
Computes many commonly used confusion matrix metrics
edge_confusion( base, comparison, metric = c("all", "sen", "spec", "ppv", "npv", "fdr", "fom", "ba", "f1", "csi", "mcc"), full.names = FALSE )edge_confusion( base, comparison, metric = c("all", "sen", "spec", "ppv", "npv", "fdr", "fom", "ba", "f1", "csi", "mcc"), full.names = FALSE )
base |
Matrix or data frame.
Network that will be treated as the "ground truth" such that
a false positive represents an edge that is present in |
comparison |
Matrix or data frame.
Network that will be treated as the estimator such that a
false positive represents an edge that is present in this network
but not in |
metric |
Character vector.
Defaults to
|
full.names |
Boolean (length = 1).
Whether full or abbreviated names should be used.
Defaults to |
A named numeric vector of the requested confusion matrix metrics.
Values are generally in , with the exception of "mcc"
(Matthews Correlation Coefficient), which ranges from to
where 1 indicates perfect agreement, 0 indicates chance-level performance,
and -1 indicates perfect disagreement. The vector contains only the elements
specified by metric (all ten metrics when metric = "all",
which is the default). Names are abbreviated (e.g., "sen") when
full.names = FALSE (default), or expanded
(e.g., "Sensitivity") when full.names = TRUE. Any metric
whose denominator is zero (e.g., sensitivity when no edges exist in
base) is returned as NA.
Alexander P. Christensen <[email protected]>
# Set split split <- sample( 1:nrow(basic_smallworld), round(nrow(basic_smallworld) / 2) ) # Estimate networks split1 <- network_estimation(basic_smallworld[split,]) split2 <- network_estimation(basic_smallworld[-split,]) # Estimate metrics edge_confusion(split1, split2)# Set split split <- sample( 1:nrow(basic_smallworld), round(nrow(basic_smallworld) / 2) ) # Estimate networks split1 <- network_estimation(basic_smallworld[split,]) split2 <- network_estimation(basic_smallworld[-split,]) # Estimate metrics edge_confusion(split1, split2)
A general function to estimate Gaussian graphical models using L0 penalty approximations. All penalties are implemented using either single-pass or full Local Linear Approximation (LLA: Fan & Li, 2001; Zou & Li, 2008)
network_estimation( data, n = NULL, corr = c("auto", "pearson", "spearman"), na_data = c("pairwise", "listwise"), penalty = c("atan", "exp", "gumbel", "log", "weibull"), gamma = NULL, adaptive = TRUE, nlambda = 50, lambda_min_ratio = 0.01, penalize_diagonal = TRUE, ic = c("AIC", "AICc", "BIC", "BIC0", "EBIC", "MBIC"), ebic_gamma = 0.5, fast = TRUE, LLA = TRUE, LLA_threshold = 0.001, LLA_iter = 10000, network_only = TRUE, verbose = FALSE, ... )network_estimation( data, n = NULL, corr = c("auto", "pearson", "spearman"), na_data = c("pairwise", "listwise"), penalty = c("atan", "exp", "gumbel", "log", "weibull"), gamma = NULL, adaptive = TRUE, nlambda = 50, lambda_min_ratio = 0.01, penalize_diagonal = TRUE, ic = c("AIC", "AICc", "BIC", "BIC0", "EBIC", "MBIC"), ebic_gamma = 0.5, fast = TRUE, LLA = TRUE, LLA_threshold = 0.001, LLA_iter = 10000, network_only = TRUE, verbose = FALSE, ... )
data |
Matrix or data frame. Should consist only of variables to be used in the analysis |
n |
Numeric (length = 1).
Sample size must be provided if |
corr |
Character (length = 1).
Method to compute correlations.
Defaults to
For other similarity measures, compute them first and input them
into |
na_data |
Character (length = 1).
How should missing data be handled?
Defaults to
|
penalty |
Character (length = 1).
Defaults to
|
gamma |
Numeric (length = 1). Adjusts the shape of the penalty. Defaults:
|
adaptive |
Boolean (length = 1).
Whether data-adaptive (gamma) parameters should be used.
Defaults to
When |
nlambda |
Numeric (length = 1).
Number of lambda values to test.
Defaults to |
lambda_min_ratio |
Numeric (length = 1).
Ratio of lowest lambda value compared to maximal lambda.
Defaults to |
penalize_diagonal |
Boolean (length = 1).
Should the diagonal be penalized?
Defaults to |
ic |
Character (length = 1). What information criterion should be used for model selection? Available options include:
Term definitions:
Defaults to |
ebic_gamma |
Numeric (length = 1)
Value to set gamma parameter in EBIC (see above).
Defaults to Only used if |
fast |
Boolean (length = 1).
Whether the The fast results may differ by less than floating point of the original
GLASSO implemented by |
LLA |
Boolean (length = 1).
Should Local Linear Approximation be used to find optimal minimum?
Defaults to |
LLA_threshold |
Numeric (length = 1).
When performing the Local Linear Approximation, the maximum threshold
until convergence is met.
Defaults to |
LLA_iter |
Numeric (length = 1).
Maximum number of iterations to perform to reach convergence.
Defaults to |
network_only |
Boolean (length = 1).
Whether the network only should be output.
Defaults to |
verbose |
Boolean (length = 1).
Whether messages and (insignificant) warnings should be output.
Defaults to |
... |
Additional arguments to be passed on to |
When network_only = TRUE (default), returns a
numeric matrix of partial correlations representing the estimated Gaussian
graphical model. Off-diagonal entry is the partial correlation
between variables and controlling for all other variables,
with values in ; a value of zero indicates the absence of an
edge. Diagonal entries are zero. Row and column names are inherited from
data.
When network_only = FALSE, returns a named list with the following
elements:
network |
The |
K |
The |
R |
The |
penalty |
Character string naming the penalty function used
(one of |
lambda |
Numeric scalar giving the regularization parameter value selected by the information criterion. Larger values correspond to sparser networks |
gamma |
Numeric scalar giving the shape parameter of the
penalty actually used. For adaptive penalties ( |
correlation |
The |
criterion |
Character string naming the information criterion
used for model selection (e.g., |
IC |
Numeric scalar giving the value of the information criterion at the optimal lambda |
MLE |
List containing the MLE estimated parameters if
|
Alexander P. Christensen <[email protected]>
Log penalty
Candes, E. J., Wakin, M. B., & Boyd, S. P. (2008).
Enhancing sparsity by reweighted l1 minimization.
Journal of Fourier Analysis and Applications, 14(5), 877–905.
Adaptive regularization
Christensen, A. P., & Choi, J. (2026).
Adaptive regularization via extreme value distributions for Gaussian graphical models.
PsyArXiv.
BIC0
Dicker, L., Huang, B., & Lin, X. (2013).
Variable selection and estimation with the seamless-L0 penalty.
Statistica Sinica, 23(2), 929–962.
Local Linear Approximation
Fan, J., & Li, R. (2001).
Variable selection via nonconcave penalized likelihood and its oracle properties.
Journal of the American Statistical Association, 96(456), 1348–1360.
EXP penalty
Wang, Y., Fan, Q., & Zhu, L. (2018).
Variable selection and estimation using a continuous approximation to the L0 penalty.
Annals of the Institute of Statistical Mathematics, 70(1), 191–214.
Atan penalty
Wang, Y., & Zhu, L. (2016).
Variable selection and parameter estimation with the Atan regularization method.
Journal of Probability and Statistics, 2016, 1–12.
Seminal simulation in network psychometrics
Williams, D. R. (2020).
Beyond lasso: A survey of nonconvex regularization in Gaussian graphical models.
PsyArXiv.
One-step Local Linear Approximation
Zou, H., & Li, R. (2008).
One-step sparse estimates in nonconcave penalized likelihood models.
Annals of Statistics, 36(4), 1509–1533.
# Obtain default estimator (adaptive Weibull) weibull_network <- network_estimation( data = basic_smallworld, LLA = TRUE ) # Obtain Atan network atan_network <- network_estimation( data = basic_smallworld, penalty = "atan", LLA = TRUE ) # Obtain static EXP network exp_network <- network_estimation( data = basic_smallworld, penalty = "exp", adaptive = FALSE, LLA = TRUE )# Obtain default estimator (adaptive Weibull) weibull_network <- network_estimation( data = basic_smallworld, LLA = TRUE ) # Obtain Atan network atan_network <- network_estimation( data = basic_smallworld, penalty = "atan", LLA = TRUE ) # Obtain static EXP network exp_network <- network_estimation( data = basic_smallworld, penalty = "exp", adaptive = FALSE, LLA = TRUE )
Computes several traditional fit metrics for networks including
chi-square ()
root mean square error of approximation (RMSEA) with confidence intervals
confirmatory fit index (CFI)
Tucker-Lewis index (TLI)
standardized root mean residual (SRMR)
log-likelihood
Akaike's information criterion (AIC)
Bayesian information criterion (BIC)
network_fit(network, n, S, ci = 0.95)network_fit(network, n, S, ci = 0.95)
network |
Matrix or data frame. A p by p square network matrix |
n |
Numeric (length = 1). Sample size |
S |
Matrix or data frame.
A p by p square zero-order correlation matrix corresponding
with the input |
ci |
Numeric (length = 1).
Confidence interval for RMSEA.
Defaults to |
A named numeric vector of traditional and likelihood-based fit indices. The vector always contains the following elements:
chisqChi-square statistic
(), where is the maximum
likelihood discrepancy function between the model-implied and empirical
correlation matrices
dfDegrees of freedom: total number of unique off-diagonal
correlations minus the number of non-zero edges in network
chisq.p.valuep-value for the chi-square test of exact fit (H0: model-implied covariance equals the population covariance)
RMSEARoot mean square error of approximation. Values
0.05 indicate close fit; values 0.08 indicate
acceptable fit
RMSEA.XX.lower, RMSEA.XX.upper
Lower and upper
bounds of the ci-level confidence interval for RMSEA, where
XX is the integer percentage (e.g., RMSEA.95.lower and
RMSEA.95.upper for a 95% CI)
RMSEA.p.valuep-value for the one-sided test of close fit
(H0: RMSEA 0.05)
CFIComparative fit index, comparing the target model to
an independence (null) baseline. Values 0.95 indicate
acceptable fit
TLITucker-Lewis index (non-normed fit index). Values
0.95 indicate acceptable fit; can fall outside
for severely misspecified models
SRMRStandardized root mean residual: the root mean squared
difference between the model-implied and observed correlation matrices.
Values 0.08 indicate acceptable fit
logLikGaussian log-likelihood of the model-implied correlation matrix, assuming zero mean structure (means are not estimated)
AICAkaike's information criterion:
, where is the number of
non-zero edges in network
BICBayesian information criterion:
Alexander P. Christensen <[email protected]>
Epskamp, S., Rhemtulla, M., & Borsboom, D. (2017). Generalized network psychometrics: Combining network and latent variable models. Psychometrika, 82(4), 904–927.
# Obtain correlation matrix S <- auto_correlate(basic_smallworld) # Obtain Weibull network weibull_network <- network_estimation(data = basic_smallworld, LLA = TRUE) # Obtain fit (expects continuous variables!) network_fit(network = weibull_network, n = nrow(basic_smallworld), S = S) # Scaled metrics are not yet available for # dichotomous or polytomous data!# Obtain correlation matrix S <- auto_correlate(basic_smallworld) # Obtain Weibull network weibull_network <- network_estimation(data = basic_smallworld, LLA = TRUE) # Obtain fit (expects continuous variables!) network_fit(network = weibull_network, n = nrow(basic_smallworld), S = S) # Scaled metrics are not yet available for # dichotomous or polytomous data!
A fast implementation of polychoric correlations in C. Uses the Beasley-Springer-Moro algorithm (Boro & Springer, 1977; Moro, 1995) to estimate the inverse univariate normal CDF, Genz's approximation (Genz, 2004), a double-precision extension of Drezner and Wesolosky (1990) developed by Genz and Ge, to estimate the bivariate normal CDF, and Newton-Raphson (Fisher scoring, with an exact-Hessian arcsin-reparameterized fallback) for optimization of rho
polychoric_matrix( data, na_data = c("pairwise", "listwise"), empty_method = c("none", "zero", "all"), empty_value = c("none", "point_five", "one_over"), ... )polychoric_matrix( data, na_data = c("pairwise", "listwise"), empty_method = c("none", "zero", "all"), empty_value = c("none", "point_five", "one_over"), ... )
data |
Matrix or data frame.
A dataset with all ordinal values
(rows = cases, columns = variables).
Data are required to be between |
na_data |
Character (length = 1).
How should missing data be handled?
Defaults to
|
empty_method |
Character (length = 1).
Method for empty cell correction.
Defaults to
|
empty_value |
Character (length = 1).
Value to add to the joint frequency table cells.
Defaults to
|
... |
Not used but made available for easier argument passing |
A symmetric numeric matrix of dimension , where
is the number of variables (columns) in data. Each
off-diagonal entry is the polychoric correlation between
variables and — the estimated Pearson correlation between
the latent continuous variables assumed to underlie the observed ordinal
categories — with values in . Diagonal entries are .
Row and column names are inherited from data. If any variable has
zero variance, its corresponding row and column are set to NA and
a warning is issued.
Alexander P. Christensen <[email protected]> with assistance from GPT-4
Beasley-Moro-Springer algorithm
Beasley, J. D., & Springer, S. G. (1977).
Algorithm AS 111: The percentage points of the normal distribution.
Journal of the Royal Statistical Society. Series C (Applied Statistics), 26(1), 118-121.
Moro, B. (1995). The full monte. Risk 8 (February), 57-58.
Newton-Raphson (Fisher scoring) optimization
Olsson, U. (1979).
Maximum likelihood estimation of the polychoric correlation coefficient.
Psychometrika, 44(4), 443-460.
Genz bivariate normal approximation
Genz, A. (2004).
Numerical computation of rectangular bivariate and trivariate normal and t probabilities.
Statistics and Computing, 14(3), 251-260.
Drezner, Z., & Wesolowsky, G. O. (1990). On the computation of the bivariate normal integral. Journal of Statistical Computation and Simulation, 35(1-2), 101-107.
# Categorize data (5 equal-frequency categories) basic_categorized <- apply( basic_smallworld, 2, function(x){ as.numeric(cut(x, breaks = quantile(x, probs = 0:5 / 5), include.lowest = TRUE)) } ) # Compute polychoric correlation matrix correlations <- polychoric_matrix(basic_categorized) # Randomly assign missing data basic_categorized[sample(1:length(basic_categorized), 1000)] <- NA # Compute polychoric correlation matrix with pairwise missing pairwise_correlations <- polychoric_matrix( basic_categorized, na_data = "pairwise" ) # Compute polychoric correlation matrix with listwise missing pairwise_correlations <- polychoric_matrix( basic_categorized, na_data = "listwise" )# Categorize data (5 equal-frequency categories) basic_categorized <- apply( basic_smallworld, 2, function(x){ as.numeric(cut(x, breaks = quantile(x, probs = 0:5 / 5), include.lowest = TRUE)) } ) # Compute polychoric correlation matrix correlations <- polychoric_matrix(basic_categorized) # Randomly assign missing data basic_categorized[sample(1:length(basic_categorized), 1000)] <- NA # Compute polychoric correlation matrix with pairwise missing pairwise_correlations <- polychoric_matrix( basic_categorized, na_data = "pairwise" ) # Compute polychoric correlation matrix with listwise missing pairwise_correlations <- polychoric_matrix( basic_categorized, na_data = "listwise" )