Skip to main content

Knockoffs and importances for heterogeneous data with conditional residuals and random forests

Project description

heteroknockoffpy

Knockoffs and PRISM importances for heterogeneous (mixed numeric/categorical) data, using conditional residuals and random forests.


Installation

pip install heteroknockoffpy

categorical_method='forest' requires R and rpy2. Install the ranger R package before using it.


Knockoffs

from heteroknockoffpy import knockoff
import numpy as np

rng = np.random.default_rng(0)

# X is a polars DataFrame; categorical columns must have dtype pl.Categorical
Xk = knockoff.get_knockoffs(
    X,
    method="second_order",   # "second_order" | "GAN" | "GAN_torch" | "SCIP"
    rng=rng,
    categorical_method="forest",
)

categorical_method

Controls how categorical columns are encoded before knockoffs are generated.

value behavior
'forest' Fits a ranger random forest per categorical column; uses predicted class-probability logits as a soft numeric encoding
'linear' Same, but with logistic regression — lighter and faster
'ohe' Hard one-hot-encodes categories as floats; no probability smoothing
'scip' For numeric columns, operates on conditional residuals `X_j − E[X_j

'scip' is the most statistically principled approach for mixed data. 'forest' or 'linear' are convenient defaults when a quick approximation is acceptable.

conditional_expectations

A pl.DataFrame of shape (n, p_numeric) giving E[X_j | X_{-j}] for each numeric column. Only relevant when categorical_method='scip'.

from heteroknockoffpy import rbridge

# compute once, reuse across multiple knockoff draws
ce = rbridge.get_forest_conditional_expectations(X)

Xk1 = knockoff.get_knockoffs(X, method="GAN", rng=rng,
                               categorical_method="scip",
                               conditional_expectations=ce)
Xk2 = knockoff.get_knockoffs(X, method="GAN", rng=rng,
                               categorical_method="scip",
                               conditional_expectations=ce)

If conditional_expectations=None (the default) and categorical_method='scip', the package computes them internally using R ranger::ranger. Pass a pre-computed frame to avoid refitting the forest on every call.


Importances

All importance functions return a np.ndarray of length 2p — scores for [x_1, …, x_p, x̃_1, …, x̃_p]. Use wFromImportances to convert these to knockoff W-statistics for variable selection.

Both PRISM functions train a single MLP on [X, Xk] while sweeping a lambda regularization path. At the end of each lambda stage a snapshot of importances is recorded; the returned importances are the mean across all snapshots. The regularization path defaults to logspace(1, -2, 50); pass lambda_path and/or a_path to override. epochs is distributed evenly across stages.

PRISM-W — prismWImportances

Records first-layer column norms ‖W[:,j]‖₂ at each lambda stage. Fast — no extra forward passes per snapshot.

from heteroknockoffpy.importance import prismWImportances

imp = prismWImportances(
    X=X, Xk=Xk, y=y,
    layers=[64, 32],
    outcome_type="continuous",   # "continuous" | "count" | "categorical" | None (inferred)
    model_type="mlp",            # "mlp" | "pairwise" | "additive"
    epochs=500,
)

PRISM-G — prismGImportances

Records per-feature output sensitivity φⱼ = mean|ŷ(x+σeⱼ) − ŷ(x−σeⱼ)| / 2σ at each lambda stage. More directly tied to the model's predictions than PRISM-W, but requires extra forward passes per snapshot.

from heteroknockoffpy.importance import prismGImportances

imp = prismGImportances(
    X=X, Xk=Xk, y=y,
    layers=[64, 32],
    outcome_type="continuous",
    local_grad_method="auto_diff",  # "auto_diff" | "bandwidth"
    bandwidth=None,                 # only used when local_grad_method="bandwidth"
    model_type="mlp",
    epochs=500,
)

model_type

value behavior
'mlp' Standard MLP on [X, Xk] with group regularization on first-layer columns
'pairwise' Adds a learnable filter that creates convex combinations of xⱼ and x̃ⱼ, forcing explicit per-feature competition
'additive' Feature-wise sub-networks with separate group regularization for X and Xk channels

Variable selection

from heteroknockoffpy.importance import wFromImportances, selection_threshold

W = wFromImportances(imp)
threshold = selection_threshold(W, fdr=0.1)
selected = [j for j, w in enumerate(W) if w >= threshold]

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

heteroknockoffpy-0.1.0.tar.gz (918.9 kB view details)

Uploaded Source

Built Distribution

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

heteroknockoffpy-0.1.0-py3-none-any.whl (51.3 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: heteroknockoffpy-0.1.0.tar.gz
  • Upload date:
  • Size: 918.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for heteroknockoffpy-0.1.0.tar.gz
Algorithm Hash digest
SHA256 865e4f3b85631da21be2d2b1035d38fb19f4d9483bc520de03d5054a819ae365
MD5 83634fda497c9c88266847e24bc25e89
BLAKE2b-256 3727bea4a9f3790ab48e2474faa2d89096ac49d54ebe9c564c5ab833a4314db9

See more details on using hashes here.

File details

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

File metadata

  • Download URL: heteroknockoffpy-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 51.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for heteroknockoffpy-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 beaede148f0cf4e73dfb0881c96f36e1097c4f97e66a51c322135ae2f569bbe4
MD5 92a1607e52c51db2abdac4462414afb4
BLAKE2b-256 94219cad1c4b661d662f3bef322f45e928bc4cac2c3c6d3a08dd7458b96e5750

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