Skip to content

pelinker.dim_selection.grids

PCA / UMAP dimension search grids and winner selection.

coarse_cells(pca_grid, umap_grid)

Cartesian product of coarse PCA × UMAP grids (stable order).

Source code in pelinker/dim_selection/grids.py
def coarse_cells(
    pca_grid: Sequence[int],
    umap_grid: Sequence[int],
) -> list[tuple[int, int]]:
    """Cartesian product of coarse PCA × UMAP grids (stable order)."""
    return [(int(p), int(u)) for p in pca_grid for u in umap_grid]

parse_int_grid(spec, *, name)

Parse a comma-separated int grid or pass through a sequence of ints.

Source code in pelinker/dim_selection/grids.py
def parse_int_grid(spec: str | Sequence[int], *, name: str) -> tuple[int, ...]:
    """Parse a comma-separated int grid or pass through a sequence of ints."""
    if isinstance(spec, str):
        parts = [p.strip() for p in spec.split(",") if p.strip()]
        if not parts:
            raise ValueError(f"{name} grid must be non-empty")
        values = [int(p) for p in parts]
    else:
        values = [int(v) for v in spec]
    if not values:
        raise ValueError(f"{name} grid must be non-empty")
    if any(v < 1 for v in values):
        raise ValueError(f"{name} grid values must be >= 1; got {values}")
    # Preserve order, drop duplicates.
    seen: set[int] = set()
    out: list[int] = []
    for v in values:
        if v not in seen:
            seen.add(v)
            out.append(v)
    return tuple(out)

pick_winner_row(df_results)

Choose the best (pca, umap) row by outer DBCV+ARI score.

outer_score = min–max pooled mean DBCV + mean ARI across candidate cells (same pooling as inner dbcv_ari_mean_minmax). Ties: lower outer std, then smaller pca_components, then smaller umap_dim.

Source code in pelinker/dim_selection/grids.py
def pick_winner_row(df_results: pd.DataFrame) -> dict[str, object]:
    """
    Choose the best (pca, umap) row by outer DBCV+ARI score.

    ``outer_score`` = min–max pooled mean DBCV + mean ARI across candidate cells
    (same pooling as inner ``dbcv_ari_mean_minmax``). Ties: lower outer std, then
    smaller ``pca_components``, then smaller ``umap_dim``.
    """
    from pelinker.clustering_search_ranking import pick_best_row

    if df_results.empty:
        raise ValueError("df_results must be a non-empty DataFrame")
    required = {
        "best_score",
        "best_score_std",
        "pca_components",
        "umap_dim",
    }
    missing = required - set(df_results.columns)
    if missing:
        raise ValueError(f"df_results missing columns: {sorted(missing)}")

    return pick_best_row(
        df_results,
        tie_break_cols=("pca_components", "umap_dim"),
        use_minmax=True,
    )

refine_cells(best_pca, best_umap, *, already=None)

Local neighborhood around the coarse winner.

PCA: best±40 step 20 (clipped to >= 2). UMAP: best±2 step 1 (clipped to >= 2). Skips cells already evaluated when already is provided.

Source code in pelinker/dim_selection/grids.py
def refine_cells(
    best_pca: int,
    best_umap: int,
    *,
    already: set[tuple[int, int]] | None = None,
) -> list[tuple[int, int]]:
    """
    Local neighborhood around the coarse winner.

    PCA: best±40 step 20 (clipped to >= 2).
    UMAP: best±2 step 1 (clipped to >= 2).
    Skips cells already evaluated when ``already`` is provided.
    """
    done = already or set()
    pcas = _range_around(
        best_pca,
        delta=REFINE_PCA_DELTA,
        step=REFINE_PCA_STEP,
        lo=MIN_PCA_COMPONENTS,
    )
    umaps = _range_around(
        best_umap,
        delta=REFINE_UMAP_DELTA,
        step=REFINE_UMAP_STEP,
        lo=MIN_UMAP_COMPONENTS,
    )
    out: list[tuple[int, int]] = []
    for p in pcas:
        for u in umaps:
            # UMAP dim must not exceed PCA dim for a sensible pipeline.
            if u > p:
                continue
            cell = (p, u)
            if cell not in done:
                out.append(cell)
    return out