ERICA - Evaluating Replicability via Iterative Clustering Assignments
Project description
ERICA - Evaluating Replicability via Iterative Clustering Assignments
Evaluating replicability via iterative clustering assignments (ERICA) is a Python library for assessing and quantifying clustering replicability via Monte Carlo (MC) subsampling and various clustering techniques. It provides robust evaluation of clustering stability across different savmpled versions of your dataset.
Features
- ๐ฏ Multiple Clustering Methods: Support for K-Means and agglomerative (hierarchical) clustering with Ward or single linkage. This will be extended to additonal linkages (for hierarchical clustering) and more clustering methods.
- ๐ Replicability Metrics: Compute CRI, WCRI, and TWCRI metrics for stability assessment
- โญ Optimal K Selection: Automatic K* selection via Algorithm 2 which attempts to mitigate the under-clustering phenomenon.
- ๐ Iterative Analysis: Monte Carlo subsampling for robust evaluation.
- ๐ Interactive Visualization: Create important plots with Plotly.
- ๐จ Optional GUI: User-friendly Gradio web interface.
- ๐ฌ Reproducible: Deterministic mode for scientific reproducibility.
- โก Optimized I/O: Smart caching for efficient processing.
- ๐ Flexible Data Loading: Automatic detection of CSV orientation (samples in rows/columns).
Quick Start
Installation
# Basic installation
pip install erica-clustering
# With plotting support
pip install erica-clustering[plots]
# With GUI support
pip install erica-clustering[gui]
# Full installation
pip install erica-clustering[all]
Basic Usage
import numpy as np
from erica import ERICA
# Load your data (samples ร features)
data = np.random.rand(100, 50)
# Run ERICA analysis
erica = ERICA(
data=data,
k_range=[2, 3, 4, 5],
n_iterations=200,
method='both'
)
results = erica.run()
# Get results
clam_matrix = erica.get_clam_matrix(k=3)
metrics = erica.get_metrics()
# Get optimal K* (automatically computed)
k_star = erica.get_k_star('TWCRI')
print(f"Optimal K* = {k_star['kmeans']}")
print(f"CRI: {metrics[3]['kmeans']['CRI']:.3f}")
print(f"WCRI: {metrics[3]['kmeans']['WCRI']:.3f}")
print(f"TWCRI: {metrics[3]['kmeans']['TWCRI']:.3f}")
# Visualize results
fig1, fig2 = erica.plot_metrics()
fig1.show()
Input Dataset Orientation
ERICA expects data in (n_samples, n_features) format. The transpose parameter controls how your input data is interpreted:
Default (Genomics Format):
from erica import ERICA
from erica.data import load_data
# For genomics data: features in rows, samples in columns
# Example: 22,283 genes ร 344 samples
data = load_data('gene_expression.npy')
erica = ERICA(data=data) # transpose=True by default
# Result: 344 samples ร 22,283 features โ
Standard ML Format:
# For standard ML data: samples in rows, features in columns
# Example: 344 samples ร 3 features
data = load_data('samples.csv')
erica = ERICA(data=data, transpose=False)
# Result: 344 samples ร 3 features โ
Important Notes:
.npyfiles: If your array is already numeric, it's used as-is (no transposition)- CSV files: Automatically removes ID columns and converts to numeric
- If you get an error about insufficient samples, try toggling
transpose=True/False
What is ERICA?
ERICA evaluates clustering stability through:
- Iterative Monte Carlo Subsampling: Repeatedly split data into train/test sets
- Clustering: Run clustering algorithms on each subsample
- Alignment: Align cluster identities across iterations
- CLAM Matrix Generation: Track cluster assignments across iterations
- Metrics Computation: Calculate replicability scores
Replicability Metrics
- CRI (Clustering Replicability Index): Measures how consistently samples are assigned to their primary cluster
- WCRI (Weighted CRI): CRI weighted by cluster sizes
- TWCRI (Total Weighted CRI): Sum of weighted CRI values for overall assessment
Higher values = Higher replicability
Empty Cluster Handling
ERICA carefully addresses cases where there are empty (null) clusters - i.e. cluster(s) with no datapoints assigned to them:
- Detection: Any K value with one or more empty clusters is flagged
- Disqualification: Metrics (CRI, WCRI, TWCRI) are marked as
NaNfor that K value - K Selection: NaN values are automatically skipped per Algorithm 2
- Tracking: Disqualified K values are tracked and accessible via
get_disqualified_k() - Output: Clear warning message: "NaN (DISQUALIFIED - empty cluster detected)"
This ensures that only valid clustering configurations are considered for K* selection, maintaining compliance with the ERICA algorithm specification.
# Get disqualified K values
disqualified = erica.get_disqualified_k()
print(f"Disqualified K values: {disqualified}")
# Output: {'kmeans': [8], 'agglomerative_ward': [7, 8]}
# Check if specific K was disqualified
if 8 in erica.get_disqualified_k('kmeans'):
print("K=8 had empty clusters and was disqualified")
Advanced Usage
Using Individual Components
from erica.clustering import kmeans_clustering, iterative_clustering_subsampling
from erica.metrics import compute_metrics_for_clam
from erica.data import prepare_samples_array
# Prepare data
samples = prepare_samples_array(your_data)
# Perform subsampling
train_size = int(len(samples) * 0.8)
_, indices_folder = iterative_clustering_subsampling(
samples, len(samples), 200, train_size, './output'
)
# Run clustering
result = kmeans_clustering(
samples, k=3, n_iterations=200,
indices_folder=indices_folder,
output_dir='./output'
)
# Compute metrics
metrics = compute_metrics_for_clam(result['clam_matrix'], k=3)
Custom Plotting
from erica.plotting import plot_metrics, plot_clam_heatmap
# Plot metrics
fig = plot_metrics(k_values, cri_values, wcri_values, twcri_values)
fig.show()
# Visualize CLAM matrix
fig = plot_clam_heatmap(clam_matrix, k=3)
fig.show()
Documentation
- ๐ Getting Started Guide
- ๐ API Reference
- ๐งฌ Methodology
- ๐ฆ PyPI Publishing Guide
Project Structure
erica/
โโโ __init__.py # Main package interface
โโโ core.py # ERICA main class
โโโ clustering.py # Clustering algorithms
โโโ metrics.py # Replicability metrics
โโโ data.py # Data loading and preparation
โโโ plotting.py # Visualization functions
โโโ utils.py # Utility functions
Requirements
Core Dependencies:
- Python >= 3.8
- NumPy >= 1.21.0
- Pandas >= 1.3.0
- scikit-learn >= 1.0.0
- PyYAML >= 6.0
Optional Dependencies:
- Plotly >= 5.0.0 (for plotting)
- Matplotlib >= 3.5.0 (for additional plots)
- Gradio >= 4.0.0 (for GUI)
Use Cases
Bioinformatics
- Gene expression clustering analysis
- Single-cell RNA-seq clustering validation
- Patient stratification assessment
General Machine Learning
- Evaluating clustering stability before downstream analysis
- Comparing different clustering methods objectively
- Selecting optimal k with stability criterion
- Identifying outliers or ambiguous samples
Examples
Example 1: Gene Expression Analysis (.npy files)
from erica import ERICA
from erica.data import load_data
# Load genomics data (features in rows, samples in columns)
# Example: vdx_dict.npy contains 22,283 genes ร 344 samples
data = load_data('vdx_dict.npy')
# Run ERICA (default transpose=True handles genomics format)
erica = ERICA(
data=data,
k_range=[2, 3, 4, 5, 6, 7, 8],
n_iterations=200
)
results = erica.run()
# Get optimal K* (automatically computed by ERICA)
k_star = erica.get_k_star('TWCRI')
optimal_k = k_star['kmeans']
print(f"Recommended number of clusters: {optimal_k}")
Example 1b: CSV Files with Different Orientations
from erica import ERICA
from erica.data import load_data
# Case 1: Genomics CSV (features in rows, samples in columns)
# File structure: each row = gene, each column = sample
# Example: 22,283 rows ร 345 columns (1 ID + 344 samples)
data = load_data('gene_expression.csv')
erica = ERICA(data=data, transpose=True) # Default
results = erica.run()
# Result: 344 samples ร 22,283 features
# Case 2: Standard ML CSV (samples in rows, features in columns)
# File structure: each row = sample, each column = feature
# Example: VDX_3_SV.csv with 344 rows ร 4 columns (1 ID + 3 genes)
data = load_data('VDX_3_SV.csv')
erica = ERICA(data=data, transpose=False) # Must specify!
results = erica.run()
# Result: 344 samples ร 3 features
Troubleshooting: If you get an error like "Dataset has 3 samples but k=4 clusters requested", your data orientation is likely incorrect. Try toggling transpose=True/False.
Example 2: Method Comparison
from erica import ERICA
# Test K-Means
erica_km = ERICA(data=data, k_range=[2, 3, 4], method='kmeans')
results_km = erica_km.run()
# Test Agglomerative
erica_agg = ERICA(data=data, k_range=[2, 3, 4], method='agglomerative')
results_agg = erica_agg.run()
# Compare metrics
metrics_km = erica_km.get_metrics()
metrics_agg = erica_agg.get_metrics()
Performance Tips
Forthcoming...
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Patterns and Technology
Core Technologies
- Python 3.8+: Primary programming language
- NumPy: Numerical computing and array operations
- pandas: Data manipulation and I/O
- scikit-learn: Clustering algorithms (KMeans, AgglomerativeClustering)
- Plotly: Interactive visualizations
- Gradio: Web-based GUI interface
Design Patterns
- Object-Oriented Design: Main
ERICAclass encapsulates analysis workflow - Modular Architecture: Separate modules for clustering, metrics, plotting, and data handling
- Deterministic Execution: Reproducibility through controlled random seeds
- Lazy Computation: CLAM matrices computed on-demand with caching
- Strategy Pattern: Multiple clustering methods via pluggable algorithms
- Factory Pattern: Automatic method selection and configuration
- Iterator Pattern: Monte Carlo subsampling iterations
Code Organization
erica/
โโโ core.py # Main ERICA class and workflow orchestration
โโโ clustering.py # Clustering algorithms (KMeans, Agglomerative)
โโโ metrics.py # Replicability metrics (CRI, WCRI, TWCRI) and K* selection
โโโ plotting.py # Visualization functions
โโโ data.py # Data loading and preprocessing
โโโ utils.py # Utility functions and helpers
Key Algorithms
- Monte Carlo Subsampling (MCSS): Iterative train/test splitting for stability evaluation
- CLAM Matrix Construction: Co-occurrence matrix tracking cluster assignments
- Algorithm 2 (K Selection): Non-decreasing metric approach for optimal K determination
- CRI/WCRI/TWCRI Metrics: Replicability indices for clustering quality
Development Workflow
- Version Control: Git/GitHub
- Testing: pytest with comprehensive test suite
- Code Quality: black (formatting), flake8 (linting), mypy (type checking)
- Documentation: Markdown documentation and inline docstrings
- Packaging: setuptools with pyproject.toml
Recent Enhancements (November 2025)
- โ Enhanced NA handling per Algorithm 2
- โ Improved K* selection documentation with line-by-line algorithm mapping
- โ Gradio demo with professional UI (3-tab design)
- โ Load previous runs feature for demo interface
- โ Comprehensive testing and validation
License
This project is licensed under the MIT License - see the LICENSE file for details.
Citation
If you use ERICA in your research, please cite:
@software{erica2025,
title = {ERICA: Evaluating Replicability via Iterative Clustering Assignments},
author = {Sorooshyari, Siamak and Shirazi, Shawn},
year = {2025},
url = {https://github.com/yourusername/erica-clustering}
}
Acknowledgments
- Original Monte Carlo Subsampling for Clustering Replicability (MCSS) methodology
- scikit-learn for clustering algorithms
- Plotly for interactive visualizations
- Gradio for web interface capabilities
Support
- ๐ง Email: siamak_sorooshyari@yahoo.com
- ๐ Issues: GitHub Issues
- ๐ฌ Discussions: GitHub Discussions
Project details
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 erica-0.1.3.tar.gz.
File metadata
- Download URL: erica-0.1.3.tar.gz
- Upload date:
- Size: 48.7 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
de2f3d73c95ad49640931a3091153e9dbacb0dec85c1c8705639391f498ea733
|
|
| MD5 |
053f85303125a2e1e887420af2e9283a
|
|
| BLAKE2b-256 |
dc4a0db86d354a9f01083e4452026fed6180966b7c4d46844d5df22005d7fb95
|
Provenance
The following attestation bundles were made for erica-0.1.3.tar.gz:
Publisher:
publish.yml on sorooshyari/ERICA
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
erica-0.1.3.tar.gz -
Subject digest:
de2f3d73c95ad49640931a3091153e9dbacb0dec85c1c8705639391f498ea733 - Sigstore transparency entry: 704316714
- Sigstore integration time:
-
Permalink:
sorooshyari/ERICA@e0c40018066063520ea2f5259b864148993a80c4 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/sorooshyari
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@e0c40018066063520ea2f5259b864148993a80c4 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file erica-0.1.3-py3-none-any.whl.
File metadata
- Download URL: erica-0.1.3-py3-none-any.whl
- Upload date:
- Size: 31.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
df7b43591896cda0c9449148df2572ab24f9fda64d547fc6df4a356ce2b9d39f
|
|
| MD5 |
be5b814d991bdbce05d993f15b754a48
|
|
| BLAKE2b-256 |
0c36c1304ceeb467c9c2faaf5a36e61e9008f0b05e23a0f9d8e9188bdd9706eb
|
Provenance
The following attestation bundles were made for erica-0.1.3-py3-none-any.whl:
Publisher:
publish.yml on sorooshyari/ERICA
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
erica-0.1.3-py3-none-any.whl -
Subject digest:
df7b43591896cda0c9449148df2572ab24f9fda64d547fc6df4a356ce2b9d39f - Sigstore transparency entry: 704316717
- Sigstore integration time:
-
Permalink:
sorooshyari/ERICA@e0c40018066063520ea2f5259b864148993a80c4 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/sorooshyari
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@e0c40018066063520ea2f5259b864148993a80c4 -
Trigger Event:
workflow_dispatch
-
Statement type: