Metadata-Version: 2.4
Name: cosmap-dr
Version: 0.1.0
Summary: CosMAP: Contrastive Manifold Approximation and Projection
Author: Fenosoa Randrianjatovo
Project-URL: Homepage, https://github.com/FenosoaRandrianjatovo/CosMAP-dr
Project-URL: Repository, https://github.com/FenosoaRandrianjatovo/CosMAP-dr
Project-URL: Issues, https://github.com/FenosoaRandrianjatovo/CosMAP-dr/issues
Keywords: dimensionality reduction,manifold learning,contrastive learning,data visualization,single-cell RNA sequencing
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: BSD License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy
Requires-Dist: scipy
Requires-Dist: scikit-learn
Requires-Dist: torch
Requires-Dist: tqdm
Requires-Dist: umap-learn
Requires-Dist: pynndescent
Provides-Extra: gpu
Requires-Dist: faiss-gpu; extra == "gpu"
Provides-Extra: dev
Requires-Dist: matplotlib; extra == "dev"
Requires-Dist: pytest; extra == "dev"
Dynamic: license-file
Dynamic: requires-python

# CosMAP [![Python](https://img.shields.io/badge/Python-%E2%89%A53.9-3776AB?logo=python&logoColor=white)](https://www.python.org/) [![Python package](https://img.shields.io/badge/Python%20package-cosmap--dr-3776AB?logo=python&logoColor=white)](https://github.com/FenosoaRandrianjatovo/CosMAP-dr) [![Tests](https://github.com/FenosoaRandrianjatovo/CosMAP-dr/actions/workflows/package-checks.yml/badge.svg)](https://github.com/FenosoaRandrianjatovo/CosMAP-dr/actions/workflows/package-checks.yml) [![License: BSD 2-Clause](https://img.shields.io/badge/License-BSD%202--Clause-green.svg)](LICENSE)

<div align="justify">

We introduce **Contrastive Manifold Approximation and Projection** (CosMAP), a graph-based unsupervised dimensionality-reduction method designed to produce more faithful and interpretable low-dimensional representations. CosMAP extends the graph-based framework of Uniform Manifold Approximation and Projection by combining cosine-similarity-based affinities with a temperature-normalized contrastive formulation for constructing the high-dimensional neighbourhood graph. The resulting affinities are optimized in the low-dimensional space through an attractive–repulsive objective using Negative Sampling . CosMAP further incorporates a two-phase refinement strategy in which an intermediate higher-dimensional representation is first learned, then used to reconstruct the neighbourhood graph and initialize the final low-dimensional embedding.

</div>


## Installation

CosMAP can be installed directly from GitHub or from source.

### Prerequisites

- Python >= 3.9
- pip (Python package installer)
  

### Option 1 — Install from GitHub

This is the quickest way to install the latest version:

```bash
pip install git+https://github.com/FenosoaRandrianjatovo/CosMAP-dr.git
```




### Option 2 — Install from source (Recommended for development)

1. Clone the repository:

```bash
git clone https://github.com/FenosoaRandrianjatovo/CosMAP-dr.git
cd CosMAP-dr
```

2. Create and activate a virtual environment:

```bash
# Create virtual environment
python3 -m venv .venv

# Activate virtual environment
# On macOS/Linux:
source .venv/bin/activate

# On Windows:
# .venv\Scripts\activate
```

3. Install the package from the project root:

```bash
pip install .
```



## Check GPU / FAISS environment

```python
from cosmapdr import diagnose_cosmap_environment

diagnose_cosmap_environment()
```

## Benchmarks

To evaluate the visual quality of CosMAP embeddings, we applied the method to two standard handwritten digit datasets: **MNIST** and **USPS**. These datasets are widely used benchmarks in dimensionality reduction and manifold learning because they contain multiple visually similar classes, making cluster separation a non-trivial task.

The results below show that CosMAP produces well-structured two-dimensional embeddings with clearly separated digit clusters. In both datasets, samples belonging to the same digit tend to form compact neighborhoods, while different digit classes are projected into distinct regions of the embedding space. This suggests that CosMAP is able to preserve meaningful local relationships while maintaining a globally interpretable organization of the data.

Compared with other unsupervised dimensionality reduction methods under default settings, CosMAP provides visually sharper cluster boundaries and improved separation of true classes, particularly in regions where digit shapes are naturally ambiguous.


<!-- <h3 align="center"></h3> -->

### MNIST

<p align="center">
  <img src="https://github.com/FenosoaRandrianjatovo/CosMAP-dr/blob/main/images/mnist.png" alt="CosMAP visualization of MNIST" >
</p>

<p align="center">
  <strong>Figure 1. CosMAP embedding of the MNIST dataset.</strong><br>
    
  Two-dimensional visualization of the MNIST handwritten digit dataset containing <strong>70,000 samples</strong> and <strong>784 features</strong>. Each point represents one image, and colors correspond to the true digit labels.
</p>




<!-- <h3 align="center">MNIST</h3> -->

### USPS

<p align="center">
  <img src="https://github.com/FenosoaRandrianjatovo/CosMAP-dr/blob/main/images/usps.png" alt="CosMAP visualization of MNIST">
</p>

<p align="center">
  <strong>Figure 2. CosMAP embedding of the USPS dataset.</strong><br>



Two-dimensional visualization of the USPS handwritten digit dataset containing **9,298 samples** and **256 features**. Despite the smaller image resolution and the higher visual similarity between some digit classes, CosMAP still produces a well-organized embedding with clearly distinguishable clusters. This demonstrates the robustness of the method across different handwritten digit datasets.


## Quick Start

```python
import numpy as np
from cosmapdr import CosMAP
from sklearn.datasets import load_digits

# Load sample data
digits = load_digits()
X = digits.data

# Create CosMAP instance
cosmap_ = CosMAP(
    n_components=2,
    n_neighbors=15,
    temperature=0.5,
    random_state=None,          # no fixed seed, faster stochastic path
    deterministic=False,        # do not force slow deterministic CUDA kernels
    verbose=True,
    use_gpu=True,               # Using GPU acceleration 
    metric="euclidean",         # The default is  "cosine"
)

# Fit and transform the data
X_embedded = cosmap_.fit_transform(X)

# Plot the results
import matplotlib.pyplot as plt
plt.scatter(X_embedded[:, 0], X_embedded[:, 1], c=digits.target, cmap='tab10')
plt.colorbar()
plt.title('CosMAP embedding of digits dataset')
plt.show()
```

## Quick Start for MNIST

```python
import numpy as np
from cosmapdr import CosMAP
from sklearn.datasets import fetch_openml
import matplotlib.pyplot as plt

mnist = fetch_openml("mnist_784", version=1, as_frame=False)
X, y = mnist.data, mnist.target.astype(int)

cosmap_ = CosMAP(
    n_components=2,
    n_neighbors=15,
    temperature=0.5,
    n_epochs=200,
    random_state=None,          # no fixed seed, faster stochastic path
    deterministic=False,        # do not force slow deterministic CUDA kernels
    verbose=True,
    use_gpu=True,
    metric="cosine",
)

X_embedded = cosmap_.fit_transform(X)

plt.figure(figsize=(8, 6))
scatter = plt.scatter(X_embedded[:, 0], X_embedded[:, 1], c=y, cmap="tab10", s=1, alpha=0.7)
plt.colorbar(scatter)
plt.title("CosMAP embedding of MNIST dataset")
plt.show()
```

## Parameters
- `n_components`: Number of dimensions in the final embedding (default: 2).
- `n_neighbors`: Number of nearest neighbors used to build the high-dimensional graph (default: 15).
- `metric`: Metric used to build the graph: `"cosine"`, `"euclidean"`, or `"precomputed"` (default: `"cosine"`).
- `temperature`: Temperature controlling the sharpness of neighbor probabilities (default: 0.5).
- `n_epochs`: Number of optimization epochs (default: None).
- `learning_rate`: Initial learning rate (default: 1.0).
- `min_dist`: Minimum distance between embedded points (default: 0.1).
- `spread`: Scale of the embedded space (default: 1.0).
- `init`: Initialization method or initial embedding array (default: `"spectral"`).
- `random_state`: Random seed for reproducibility (default: None).
- `use_gpu`: Whether to use GPU acceleration if available (default: True).
- `verbose`: Whether to print progress information (default: False).
- `refinement`: Whether to use the two-phase refinement pipeline (default: True).
- `refinement_dim`: Intermediate dimension used in the first refinement phase (default: 30).
- `refinement_n_neighbors`: Number of neighbors used in the second refinement phase (default: 30).


## Reproducibility modes

Fast stochastic mode:

```python
CosMAP(random_state=None, deterministic=False)
```

Seeded but not strict deterministic GPU mode:

```python
CosMAP(random_state=42, deterministic=False)
```

Strict deterministic mode for experiments where exact repeatability is more important than speed:

```python
CosMAP(random_state=42, deterministic=True)
```


## API Compatibility

CosMAP follows the scikit-learn API conventions:

```python
# Similar to UMAP, PaCMAP, t-SNE
from cosmapdr import CosMAP
from pacmap import PaCMAP
from umap import UMAP
from sklearn.manifold import TSNE

# All have the same interface
cosmap_ = CosMAP(n_components=2)
pacmap_ = PaCMAP(n_components=2)
umap_ = UMAP(n_components=2)
tsne_ = TSNE(n_components=2)

# Fit and transform
X_cosmap = cosmap_.fit_transform(X)
X_pacmap = pacmap_.fit_transform(X)
X_umap = umap_.fit_transform(X)
X_tsne = tsne_.fit_transform(X)
```

## Requirements

- Python >= 3.7
- NumPy >= 1.19.0
- SciPy >= 1.5.0
- scikit-learn >= 0.24.0
- PyTorch >= 1.7.0
- umap-learn >= 0.5.0
- matplotlib >= 3.3.0
- tqdm >= 4.50.0

Optional:

- FAISS (for faster GPU-accelerated nearest neighbor search)

## License

BSD 2-Clause License


