Skip to content

Add Common and Individual Feature Extraction Transformers AJIVE and CIFE for Multiblock Data - #20

Open
shuo-zhou wants to merge 3 commits into
mainfrom
cife-jive
Open

Add Common and Individual Feature Extraction Transformers AJIVE and CIFE for Multiblock Data #20
shuo-zhou wants to merge 3 commits into
mainfrom
cife-jive

Conversation

@shuo-zhou

Copy link
Copy Markdown
Member

Description

Add two new algorithms, AJIVE and CIFE, under the transformer API

Status

Work in progress

Types of changes

  • Non-breaking change (fix or new feature that would not break existing functionality).
  • Breaking change (fix or new feature that would cause existing functionality to change).
  • New tests added to cover the changes.
  • In-line docstrings updated and documentation docs updated.

@codecov

codecov Bot commented Aug 22, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.24390% with 36 lines in your changes missing coverage. Please review.
✅ Project coverage is 89.00%. Comparing base (b3c9360) to head (fc4e26f).

Files with missing lines Patch % Lines
kalelinear/transformer/_multiblock.py 81.44% 18 Missing ⚠️
kalelinear/transformer/_ajive.py 92.70% 10 Missing ⚠️
kalelinear/transformer/_cife.py 93.89% 8 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #20      +/-   ##
==========================================
+ Coverage   88.71%   89.00%   +0.28%     
==========================================
  Files          21       24       +3     
  Lines        1506     1873     +367     
==========================================
+ Hits         1336     1667     +331     
- Misses        170      206      +36     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds two new multiblock feature transformers—CIFE and AJIVE—to the kalelinear.transformer API, along with tests and documentation updates so they can be used via both kalelinear.transformer and the PyKale-style kalelinear.embed module.

Changes:

  • Implement CIFE and AJIVE, plus a shared multiblock base/validation layer.
  • Add unit tests and shared synthetic multiblock dataset generator for validating common/individual subspace recovery.
  • Update README, tutorials, and Sphinx API docs to surface the new transformers.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
TUTORIALS.md Adds a usage example for CIFE/AJIVE common + individual feature extraction.
README.md Lists CIFE/AJIVE as supported transformers and adds citations.
tests/utils/test_utils.py Adds a synthetic multiblock dataset generator for common/individual structure.
tests/transformer/test_cife.py Adds test coverage for CIFE fit/transform behavior and validation.
tests/transformer/test_ajive.py Adds test coverage for AJIVE fit/transform behavior and validation.
tests/test_public_api.py Ensures new transformers are exposed via the public API modules.
kalelinear/transformer/_multiblock.py Introduces shared multiblock input handling and a base transformer class.
kalelinear/transformer/_cife.py Implements the CIFE algorithm and its COBE-based common subspace extraction.
kalelinear/transformer/_ajive.py Implements the AJIVE algorithm including Wedin-bound based rank selection.
kalelinear/transformer/init.py Exposes CIFE and AJIVE in the transformer package namespace.
kalelinear/embed.py Exposes CIFE and AJIVE via the PyKale-style embed module.
docs/source/introduction.rst Updates the “Main Features” list to include CIFE/AJIVE.
docs/source/api_transformers.rst Adds API doc entries for CIFE and AJIVE.
docs/source/api_embed.rst Adds API doc entries for CIFE and AJIVE under kalelinear.embed.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread kalelinear/transformer/_multiblock.py
Comment thread kalelinear/transformer/_multiblock.py
Comment thread kalelinear/transformer/_multiblock.py
Comment thread kalelinear/transformer/_ajive.py

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated no new comments.

Suppressed comments (3)

Previously missed (3) — in code that hasn't changed since the last review.

kalelinear/transformer/_multiblock.py:167

  • transform() uses _check_multiblock_input(X) for list/tuple inputs, which enforces a minimum of two blocks. This prevents projecting a single new block at transform-time even though the common projection does not require multiple blocks (and the docstring suggests any “list of blocks” is acceptable). Consider validating list inputs here without the “>= 2 blocks” constraint, and just stack the blocks for projection.
        if isinstance(X, (list, tuple)):
            blocks, _ = _check_multiblock_input(X)
            X_stacked = np.vstack(blocks)

kalelinear/transformer/_ajive.py:208

  • percentile is a configurable parameter, but the branch choosing between random_ssv_bound and the Wedin-based bound compares against a hard-coded 5th percentile (np.percentile(wedin_ssv_bounds, 5)). This makes behavior inconsistent when percentile is not 5 and likely ignores the user-configured setting.
        wedin_ssv_bound = np.percentile(wedin_ssv_bounds, self.percentile)
        random_ssvs = _random_direction_ssv(D, ranks, 100, self.random_state_)
        random_ssv_bound = np.percentile(random_ssvs, 95)
        if random_ssv_bound > np.percentile(wedin_ssv_bounds, 5):
            joint_rank = int(np.sum(s_stacked**2 + _FERROR > random_ssv_bound))

tests/utils/test_utils.py:133

  • make_common_individual_dataset is parameterized by n_blocks, but it indexes individual_ranks[k] / n_samples[k] without validating their lengths. Calling it with a different n_blocks than the default will raise an IndexError instead of a clear error message.
    for k in range(n_blocks):
        individual_basis, _ = np.linalg.qr(random_state.randn(n_features, individual_ranks[k]))
        individual_basis -= common_basis @ (common_basis.T @ individual_basis)
        individual_basis, _ = np.linalg.qr(individual_basis)
        block = random_state.randn(n_samples[k], n_common) @ common_basis.T

@shuo-zhou shuo-zhou changed the title Add AJIVE and CIFE Add Common and Individual Feature Extraction Transformers AJIVE and CIFE for Multiblock Data Aug 25, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 17 out of 18 changed files in this pull request and generated 2 comments.

Comment thread docs/source/index.rst
Comment on lines 17 to 22
.. toctree::
:maxdepth: 2

api_embed
api_transformers
api_predict
api_estimators
api_utilities

Comment on lines +67 to +68
block_ids = np.unique(groups)
blocks = [X[groups == block_id] for block_id in block_ids]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants