The Problem
High-dimensional datasets hide structure that standard clustering misses. The Mapper algorithm builds a graph that captures topological shape—clusters, loops, and transitions—but implementations are often slow and don't integrate with existing ML tooling. tda-mapper-python addresses this with an optimized, scikit-learn-compatible library.
What This Does
The library implements the full Mapper pipeline: lens functions (lens_pca, lens_umap in src/tdamapper/app.py), covers (BallCover, CubicalCover in src/tdamapper/cover.py), clustering (TrivialClustering in src/tdamapper/learn.py), and graph construction (mapper_graph in src/tdamapper/core.py). It includes three visualization backends—Plotly, Matplotlib, PyVis—under src/tdamapper/plot_backends/.
A Streamlit web app (app/streamlit_app.py) provides interactive parameter exploration. The package also ships benchmark scripts (benchmarks/benchmark.py) and 23 test files covering units, benchmarks, and integration with scikit-learn.
How It Is Wired
Execution starts at main in src/tdamapper/app.py:1032, which reaches 135 functions. The CLI path calls run in src/tdamapper/_run_app.py, which reaches 136 functions. The core pipeline flows: run_mapper (reaches 68 functions) → fit_transform (called from 27 places) → MapperAlgorithm (called from 20 places) → mapper_connected_components (9 callers).
The most-connected hub is src/tdamapper/cover.py—31 functions, 7 classes, called from 9 files. src/tdamapper/utils/vptree_flat/common.py follows with 16 functions called from 15 files; it implements the vantage-point tree spatial index that powers efficient neighbor searches. src/tdamapper/core.py owns graph assembly and clustering orchestration.
The code touches the outside world minimally: one function runs an external command, two read/write files. The module graph shows no circular dependencies—13 import edges across 60 internal modules—so changing one component won't cascade through cycles.
How To Use It
git clone https://github.com/moses-y/tda-mapper-python
cd tda-mapper-python
pip install -e . # from pyproject.toml
python -m tdamapper.app # CLI entry point
streamlit run app/streamlit_app.py # web UI
Configuration happens through the CLI or Streamlit UI—no required environment variables. The Makefile provides convenience targets for testing and benchmarking. Docker users can build from app/Dockerfile.
Real-World Use
from tdamapper import MapperAlgorithm
from tdamapper.cover import BallCover
from tdamapper.learn import TrivialClustering
mapper = MapperAlgorithm(
lens='pca', # or 'umap', or custom
cover=BallCover(radius=0.3),
clustering=TrivialClustering()
)
graph = mapper.fit_transform(X) # returns networkx graph
This fits into pipelines where you need to visualize cluster topology before choosing a segmentation strategy—e.g., customer segmentation from high-dimensional behavioral data.
Code Health & Issues
Static analysis found 11 issues (2 high, 9 medium):
- High - Duplicated code blocks: 174 repeated 6-line blocks across 27 files, notably in
docs/source/notebooks/andtests/example.py. Extract shared helpers. - High - Deep nesting (depth 8) in
benchmarks/benchmark.py,src/tdamapper/_common.py,src/tdamapper/plot_backends/plot_plotly.py. Use early returns. - Medium - File opened without context manager in
tests/test_unit_app.py. - Medium - Oversized files:
app/streamlit_app.py,src/tdamapper/app.py(834 lines),plot_plotly.py. - Medium - High branching density in
docs/source/notebooks/cover.py(24 branches over 79 lines).
SDLC gaps: no lockfile (non-reproducible builds), GitHub Actions pinned to mutable tags (use SHA pins), no Dependabot, Docker base image unpinned, no non-root user in container, no dependency vulnerability scan in CI.
The Bottom Line
A solid, well-tested Mapper implementation with clean module boundaries and no circular dependencies. The main risks are maintainability (duplication, large files) and supply-chain hygiene (unpinned dependencies, mutable CI tags). Use it if you need topological data analysis in a scikit-learn workflow; fix the lockfile and CI pins before production.