Skip to main content

ERICA - Evaluating Replicability via Iterative Clustering Assignments

Project description

ERICA - Evaluating Replicability via Iterative Clustering Assignments

Python 3.8+ License: MIT PyPI version

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:

  • .npy files: 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:

  1. Iterative Monte Carlo Subsampling: Repeatedly split data into train/test sets
  2. Clustering: Run clustering algorithms on each subsample
  3. Alignment: Align cluster identities across iterations
  4. CLAM Matrix Generation: Track cluster assignments across iterations
  5. 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 NaN for 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

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 ERICA class 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

  1. Monte Carlo Subsampling (MCSS): Iterative train/test splitting for stability evaluation
  2. CLAM Matrix Construction: Co-occurrence matrix tracking cluster assignments
  3. Algorithm 2 (K Selection): Non-decreasing metric approach for optimal K determination
  4. 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

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

erica-0.1.3.tar.gz (48.7 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

erica-0.1.3-py3-none-any.whl (31.8 kB view details)

Uploaded Python 3

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

Hashes for erica-0.1.3.tar.gz
Algorithm Hash digest
SHA256 de2f3d73c95ad49640931a3091153e9dbacb0dec85c1c8705639391f498ea733
MD5 053f85303125a2e1e887420af2e9283a
BLAKE2b-256 dc4a0db86d354a9f01083e4452026fed6180966b7c4d46844d5df22005d7fb95

See more details on using hashes here.

Provenance

The following attestation bundles were made for erica-0.1.3.tar.gz:

Publisher: publish.yml on sorooshyari/ERICA

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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

Hashes for erica-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 df7b43591896cda0c9449148df2572ab24f9fda64d547fc6df4a356ce2b9d39f
MD5 be5b814d991bdbce05d993f15b754a48
BLAKE2b-256 0c36c1304ceeb467c9c2faaf5a36e61e9008f0b05e23a0f9d8e9188bdd9706eb

See more details on using hashes here.

Provenance

The following attestation bundles were made for erica-0.1.3-py3-none-any.whl:

Publisher: publish.yml on sorooshyari/ERICA

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page