Gaussian Graphical Models with StARS, EBIC, and Nonparanormal methods
Project description
PyGGM: Gaussian Graphical Models in Python
A Python package for Gaussian Graphical Models with multiple regularization selection methods and nonparanormal transformations.
Features
-
Multiple Regularization Selection Methods:
- StARS (Stability Approach to Regularization Selection)
- EBIC (Extended Bayesian Information Criterion)
- Cross-Validation
-
Nonparanormal Methods:
- Gaussian copula transformation
- Rank-based correlations (Spearman/Kendall) with sine transformation
-
Robust Utilities:
- PSD projection for numerical stability
- Comprehensive input validation
-
Visualization Tools:
- Network graphs with customizable layouts
- Precision matrix heatmaps
- Diagnostic plots for model selection
-
Performance:
- Parallelization support via joblib
- Scikit-learn compatible API
Installation
From source
git clone https://github.com/naandip/pyggm.git
cd pyggm
pip install -e .
Development installation
pip install -e ".[dev]"
Quick Start
import numpy as np
from pyggm import GaussianGraphicalModel
from pyggm.visualization import plot_network, plot_stars_path
# Generate or load data
np.random.seed(42)
X = np.random.randn(200, 50)
# Fit model with StARS selection
model = GaussianGraphicalModel(
method='stars',
correlation='pearson',
n_subsamples=50,
n_jobs=-1 # Use all cores
)
model.fit(X)
# Results
print(f"Selected alpha: {model.alpha_:.4f}")
print(f"Number of edges: {model.n_edges_}")
# Visualize
import matplotlib.pyplot as plt
fig, axes = plt.subplots(1, 2, figsize=(14, 6))
plot_network(model.precision_, ax=axes[0])
plot_stars_path(model, ax=axes[1])
plt.show()
Usage Examples
1. Basic Usage with Different Methods
StARS (Recommended for sparse graphs)
from pyggm import GaussianGraphicalModel
model = GaussianGraphicalModel(
method='stars',
beta=0.05, # Instability threshold
n_subsamples=50, # Number of subsamples
n_jobs=-1 # Parallel processing
)
model.fit(X)
EBIC (Good for model selection)
model = GaussianGraphicalModel(
method='ebic',
gamma=0.5 # Sparsity penalty (0 = BIC, 0.5 = recommended)
)
model.fit(X)
Cross-Validation
model = GaussianGraphicalModel(
method='cv',
cv=5, # Number of folds
n_jobs=-1
)
model.fit(X)
2. Nonparanormal Transformation
For non-Gaussian data, use the nonparanormal transformer:
from pyggm import NonparanormalTransformer, GaussianGraphicalModel
# Transform data to approximately Gaussian
transformer = NonparanormalTransformer()
X_transformed = transformer.fit_transform(X)
# Fit graphical model
model = GaussianGraphicalModel(method='stars')
model.fit(X_transformed)
3. Rank-Based Correlations
Use rank correlations for robustness to outliers:
# Spearman correlation
model = GaussianGraphicalModel(
method='stars',
correlation='spearman' # or 'kendall'
)
model.fit(X)
4. Fixed Regularization Parameter
If you already know the regularization parameter:
model = GaussianGraphicalModel(alpha=0.1)
model.fit(X)
5. Model Evaluation
# Compute log-likelihood on test data
score = model.score(X_test)
# Access model attributes
print(f"Precision matrix: {model.precision_.shape}")
print(f"Covariance matrix: {model.covariance_.shape}")
print(f"Adjacency matrix: {model.adjacency_.shape}")
print(f"Number of edges: {model.n_edges_}")
6. Network Analysis
Convert the estimated graph to NetworkX for further analysis:
import networkx as nx
# Convert to NetworkX graph
G = model.to_networkx(threshold=0.01, weighted=True)
# Network statistics
print(f"Number of nodes: {G.number_of_nodes()}")
print(f"Number of edges: {G.number_of_edges()}")
print(f"Average degree: {sum(dict(G.degree()).values()) / G.number_of_nodes():.2f}")
# Centrality measures
degree_centrality = nx.degree_centrality(G)
betweenness_centrality = nx.betweenness_centrality(G)
# Find connected components
components = list(nx.connected_components(G))
print(f"Number of connected components: {len(components)}")
7. Visualization
from pyggm.visualization import (
plot_network,
plot_precision_matrix,
plot_stars_path,
plot_edge_stability,
plot_model_selection
)
import matplotlib.pyplot as plt
# Create comprehensive visualization
fig = plt.figure(figsize=(16, 10))
# Network plot
ax1 = plt.subplot(2, 3, 1)
plot_network(model.precision_, threshold=0.01, layout='spring', ax=ax1)
# Precision matrix heatmap
ax2 = plt.subplot(2, 3, 2)
plot_precision_matrix(model.precision_, ax=ax2)
# StARS path (if using StARS)
if hasattr(model, 'instabilities_'):
ax3 = plt.subplot(2, 3, 3)
plot_stars_path(model, ax=ax3)
ax4 = plt.subplot(2, 3, 4)
plot_edge_stability(model, ax=ax4)
# Model selection plot
ax5 = plt.subplot(2, 3, 5)
plot_model_selection(model, ax=ax5)
plt.tight_layout()
plt.show()
8. Complete Pipeline Example
import numpy as np
from pyggm import GaussianGraphicalModel, NonparanormalTransformer
from pyggm.visualization import plot_network, plot_stars_path
import matplotlib.pyplot as plt
# 1. Load/generate data
np.random.seed(42)
n, p = 200, 30
# Create data with known structure
true_precision = np.eye(p)
true_precision[0, 1] = true_precision[1, 0] = 0.5
true_precision[2, 3] = true_precision[3, 2] = 0.4
true_cov = np.linalg.inv(true_precision)
X = np.random.multivariate_normal(np.zeros(p), true_cov, n)
# 2. Optional: Apply nonparanormal transformation
# (Skip if data is already Gaussian)
transformer = NonparanormalTransformer()
X_transformed = transformer.fit_transform(X)
# 3. Fit model
model = GaussianGraphicalModel(
method='stars',
beta=0.05,
n_subsamples=50,
n_jobs=-1,
random_state=42,
verbose=1
)
model.fit(X_transformed)
# 4. Evaluate
print(f"\nModel Summary:")
print(f" Selected alpha: {model.alpha_:.4f}")
print(f" Number of edges: {model.n_edges_}")
print(f" Sparsity: {1 - model.n_edges_ / (p * (p-1) / 2):.2%}")
# 5. Visualize
fig, axes = plt.subplots(1, 2, figsize=(14, 6))
plot_network(model.precision_, threshold=0.01, ax=axes[0])
plot_stars_path(model, ax=axes[1])
plt.savefig('ggm_results.png', dpi=300, bbox_inches='tight')
plt.show()
# 6. Export to NetworkX for further analysis
G = model.to_networkx(threshold=0.01)
print(f"\nNetwork statistics:")
print(f" Nodes: {G.number_of_nodes()}")
print(f" Edges: {G.number_of_edges()}")
print(f" Density: {2 * G.number_of_edges() / (p * (p-1)):.3f}")
API Reference
GaussianGraphicalModel
Main estimator class for Gaussian Graphical Models.
Parameters:
method(str): Regularization selection method ('stars', 'ebic', or 'cv')correlation(str): Correlation type ('pearson', 'spearman', or 'kendall')alpha(float or None): Fixed regularization parametern_alphas(int): Number of alpha values to evaluatealpha_min_ratio(float): Ratio of min to max alphabeta(float): StARS instability thresholdn_subsamples(int): Number of subsamples for StARSgamma(float): EBIC gamma parametercv(int): Number of CV foldsensure_psd(bool): Project correlation matrix to PSDn_jobs(int): Number of parallel jobsrandom_state(int or None): Random seedverbose(int): Verbosity level
Attributes:
precision_: Estimated precision matrixcovariance_: Estimated covariance matrixadjacency_: Binary adjacency matrixalpha_: Selected regularization parametern_edges_: Number of edgesalphas_: Grid of alphas evaluatedinstabilities_: StARS instabilities (if method='stars')ebic_scores_: EBIC scores (if method='ebic')cv_scores_: CV scores (if method='cv')
Methods:
fit(X): Fit the modelscore(X): Compute average log-likelihoodto_networkx(threshold, weighted, labels): Convert to NetworkX graph
NonparanormalTransformer
Gaussian copula transformation for non-Gaussian data.
Parameters:
truncate(bool): Whether to truncate extreme values
Methods:
fit(X): Learn empirical CDFstransform(X): Apply transformationfit_transform(X): Fit and transform in one step
Algorithm Details
StARS (Stability Approach to Regularization Selection)
StARS selects the regularization parameter by evaluating the stability of edge selection across multiple subsamples. It chooses the smallest alpha where the instability is below a threshold β (default 0.05).
Key parameters:
n_subsamples: More subsamples = more stable selection (default 50)subsample_size: Defaults to floor(10 * sqrt(n))beta: Lower values = sparser graphs (default 0.05)
Reference: Liu, H., Roeder, K., & Wasserman, L. (2010). Stability approach to regularization selection (stars) for high dimensional graphical models. NIPS.
EBIC (Extended BIC)
EBIC extends the standard BIC with an additional penalty for graph sparsity:
EBIC = -2 * log_likelihood + |E| * log(n) + 4 * |E| * gamma * log(p)
Key parameters:
gamma: Controls sparsity penalty (0 = standard BIC, 0.5 recommended for high-dimensional settings)
Reference: Foygel, R., & Drton, M. (2010). Extended Bayesian information criteria for Gaussian graphical models. NIPS.
Nonparanormal
The nonparanormal assumes a Gaussian copula: after transforming each variable's marginal distribution to Gaussian, the joint distribution is multivariate Gaussian.
Transformations:
- Copula: X_j → Φ^(-1)(F_hat_j(X_j))
- Spearman: ρ → 2 * sin(π/6 * ρ)
- Kendall: τ → sin(π/2 * τ)
Reference: Liu, H., Lafferty, J., & Wasserman, L. (2009). The nonparanormal: Semiparametric estimation of high dimensional undirected graphs. JMLR.
Performance Tips
- Use parallelization: Set
n_jobs=-1to use all CPU cores - For large p: Consider using
method='ebic'(faster than StARS) - For robust estimation: Use
correlation='spearman'or applyNonparanormalTransformer - For interpretability: Use
method='stars'with defaultbeta=0.05
Testing
Run the test suite:
# Install test dependencies
pip install -e ".[dev]"
# Run all tests
pytest
# Run with coverage
pytest --cov=pyggm --cov-report=html
# Run specific test file
pytest tests/test_ggm.py -v
Development
Code formatting
# Format code
black src/ tests/
# Check with ruff
ruff check src/ tests/ --fix
Type checking
mypy src/pyggm/
Citation
If you use PyGGM in your research, please cite the relevant papers:
@article{liu2010stars,
title={Stability approach to regularization selection (stars) for high dimensional graphical models},
author={Liu, Han and Roeder, Kathryn and Wasserman, Larry},
journal={Advances in neural information processing systems},
volume={23},
year={2010}
}
@article{foygel2010ebic,
title={Extended Bayesian information criteria for Gaussian graphical models},
author={Foygel, Rina and Drton, Mathias},
journal={Advances in neural information processing systems},
volume={23},
pages={604--612},
year={2010}
}
@article{liu2009nonparanormal,
title={The nonparanormal: Semiparametric estimation of high dimensional undirected graphs},
author={Liu, Han and Lafferty, John and Wasserman, Larry},
journal={Journal of Machine Learning Research},
volume={10},
number={10},
year={2009}
}
License
This project is licensed under the MIT License - see the LICENSE file for details.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Acknowledgments
This package wraps scikit-learn's GraphicalLasso implementation and implements the StARS and EBIC selection procedures based on the cited papers.
Support
- Issues: GitHub Issues
- Documentation: docs/
PyGGM - A Python package for Gaussian Graphical Models
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyggm-0.1.0.tar.gz.
File metadata
- Download URL: pyggm-0.1.0.tar.gz
- Upload date:
- Size: 27.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
219ba716c020b790728677473176e9f703bff143f9b0bb23d77425c2d140a55d
|
|
| MD5 |
089f46a3f81079276ce9569af334977f
|
|
| BLAKE2b-256 |
4a45cc41149a2dace03eb7fdd0e07bba50dc3d4922b2d9166a13aeac2f97ab17
|
File details
Details for the file pyggm-0.1.0-py3-none-any.whl.
File metadata
- Download URL: pyggm-0.1.0-py3-none-any.whl
- Upload date:
- Size: 25.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a05622691456a5bab0995b7ff3ae5902259ff38d707742d89308a60bb9e3d649
|
|
| MD5 |
0265b95325d6b541065da0509a11d8e3
|
|
| BLAKE2b-256 |
97e80a652119f51fa011abc42fbf2c71ed6d59a5934e3fbd2ea12afffeb090ff
|