Skip to main content

A PyTorch implementation of Incremental PCA

Project description

PyTorch Incremental PCA

PyPI Version License

torch-incremental-pca is a PyTorch implementation of incremental principal component analysis. It follows the numerical update used by scikit-learn's IncrementalPCA, works with CPU and CUDA tensors, and processes datasets in batches so the full input does not need to fit in memory.

Installation

pip install torch-incremental-pca

PyTorch is the only direct runtime dependency. Development and comparison dependencies can be installed from a source checkout with:

pip install -e ".[dev]"

Fit a tensor

fit() divides a nonempty 2D tensor into batches and resets any model state learned by an earlier fit() call.

import torch

from torch_incremental_pca import IncrementalPCA

X = torch.randn(100_000, 512, device="cuda")

pca = IncrementalPCA(n_components=64, batch_size=2048)
pca.fit(X)

print(pca.components_.shape)  # torch.Size([64, 512])

When batch_size=None, fit() records an inferred size in batch_size_ without changing the constructor parameter. The usual inferred size is five times the feature count; Gram mode may choose a smaller, wide-matrix-friendly batch. Likewise, an inferred component count is stored in n_components_ while n_components remains None.

Stream batches

Call partial_fit() when data already arrives in batches:

pca = IncrementalPCA(n_components=64)

for X_batch in dataloader:
    pca.partial_fit(X_batch.to("cuda"))

The first batch must contain at least n_components samples. Later batches may be smaller, but every batch must have the same number of features and be on the same device as the fitted model. Inputs are converted to float32 unless they are already float32 or float64.

With copy=False, the first tensor passed to partial_fit() may be centered in place. The default, copy=True, preserves the input.

Transform data

Z = pca.transform(X_new.to("cuda"))

transform() returns (X_new - mean_) @ components_.T. It accepts input with a different floating-point dtype and casts it to the component dtype, but a tensor on a different device is rejected. The mean projection is cached, so the implementation does not need to allocate a centered copy during transformation.

SVD backends

The default backend uses torch.linalg.svd and is the reference exact implementation.

pca = IncrementalPCA(n_components=64)

Gram mode is intended for wide augmented matrices, especially on GPUs where matrix multiplication and symmetric eigendecomposition can be faster than a full SVD:

pca = IncrementalPCA(n_components=64, gram=True)

It forms X @ X.T, applies scale-aware diagonal loading only while solving the eigenproblem, and recovers singular values from the original unshifted matrix. It falls back to full SVD when the matrix is tall, when torch.linalg.eigh fails, or when a retained singular value is nonfinite or no larger than gram_eps. This fallback gives rank-deficient inputs a valid orthonormal null-space basis. gram_eps is an absolute singular-value safety threshold and is not added to reported singular values or variances.

Low-rank mode uses PyTorch's randomized torch.svd_lowrank:

pca = IncrementalPCA(
    n_components=64,
    lowrank=True,
    lowrank_q=128,
    lowrank_niter=4,
    lowrank_seed=0,
)

If lowrank_q=None, the effective rank defaults to twice n_components_ and is capped by the matrix dimensions. Increasing lowrank_q or lowrank_niter generally improves the approximation at additional cost. Set lowrank_seed for repeatable randomized decompositions.

gram=True and lowrank=True are mutually exclusive. CUDA full-SVD behavior can also be tuned with svd_driver; matrix multiplication can be controlled with allow_tf32 and matmul_precision.

Statistics and learned attributes

Means and variances use stats_dtype when provided. Supported values are torch.float32, torch.float64, and None; the default chooses float64 on CPU and float32 on CUDA before converting stored statistics to the input dtype.

After fitting, the estimator exposes:

  • components_
  • singular_values_
  • mean_ and var_
  • explained_variance_ and explained_variance_ratio_
  • noise_variance_
  • n_components_
  • n_features_ and n_samples_seen_
  • batch_size_ after fit()

The cached mean_proj_ is also available for the optimized transform path.

Approximation semantics

Incremental PCA summarizes earlier batches by their retained components, so results can depend on batch size and order even with the exact backend. They should be numerically close to scikit-learn when batching, dtype, and component count match.

The Gram backend targets the same singular triplets as full SVD, but forming a Gram matrix squares the condition number. Its scale-aware loading and full-SVD fallback protect degenerate cases without reporting ridge-shifted singular values. Gram tail energy is computed from the original Frobenius norm.

The low-rank backend is intentionally approximate. Its explained variances use the retained approximate singular values, while noise_variance_ uses total Frobenius energy minus retained approximate energy over the full discarded dimension. Consequently, residual noise remains meaningful even when lowrank_q == n_components_.

Benchmarking

The CUDA timing and optional scikit-learn comparison are executable code rather than pytest tests:

python benchmarks/benchmark_backends.py

The regular test suite is run with:

python -m pytest -q

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

torch_incremental_pca-0.1.0.tar.gz (18.2 kB view details)

Uploaded Source

Built Distribution

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

torch_incremental_pca-0.1.0-py3-none-any.whl (12.3 kB view details)

Uploaded Python 3

File details

Details for the file torch_incremental_pca-0.1.0.tar.gz.

File metadata

  • Download URL: torch_incremental_pca-0.1.0.tar.gz
  • Upload date:
  • Size: 18.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for torch_incremental_pca-0.1.0.tar.gz
Algorithm Hash digest
SHA256 2d2150b993b911d73c906ec969d72823007470f29ed1a16a6a0941f1c8057891
MD5 3a75fab6645e702e0b822804e4c91acb
BLAKE2b-256 46592efb82d01386fb3924d5a3faa5e419b793996165868bc0f58b1d19d65ce1

See more details on using hashes here.

File details

Details for the file torch_incremental_pca-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for torch_incremental_pca-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7b3db96ca82451bd5b623176ac223df9be204f615d0c0327c1a404194583aa56
MD5 d48f2dea21cc5101a1dfa1ff5bafeb45
BLAKE2b-256 4ddfe72a4879d7313496e67faa7bada644c047d1f2a3d64ab5554ab14d8c0388

See more details on using hashes here.

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