This release is a pre-release and may not be stable for production use.
SignaPy
SignaPy is an exploratory feature-discovery library for labeled datasets.
Long-term mission: find, quantify, localize, and validate predictive signal.
Status: alpha (
0.1.0a2).signapy.discover()works against binary targets with categorical, continuous, and ordinal features today. Everything under Planned next — other feature/target types, interactions, stability, and more — is not implemented yet.
The problem
Before modeling, data scientists want to know which features carry signal about the target, and where within those features that signal lives. Today this means picking the right test for each feature/target combination (Cramér's V? Phi? Spearman? point-biserial?), running it by hand, and stitching the output together.
SignaPy aims to make that a single, task-aware workflow. It uses the feature types you declare (or the categorical-only default), chooses an appropriate method, and returns structured evidence. You shouldn't need to know ahead of time which statistical test applies.
SignaPy discovers evidence of predictive signal. It does not decide what your model should use.
It is not an AutoML framework, a feature-selection oracle, or a modeling library, and it does not drop features based on p-values.
Discovery hierarchy
| Level | Question |
|---|---|
| Profiling | What data am I working with? |
| Feature-level discovery | Does this feature contain signal about the target? |
| Value-level discovery | Where within this feature does the signal live? |
| Interaction discovery (future) | Does signal emerge from combinations of features or values? |
| Stability analysis (future) | Does the signal hold across samples, folds, time, or subgroups? |
For example, feature-level discovery might find that acquisition_channel is
associated with conversion. Value-level discovery then shows where:
referral -> lift 1.91
organic -> lift 1.28
paid -> lift 0.73
Installation
SignaPy is available from PyPI and supports Python 3.10 through 3.14.
pip install signapy
The current release is an alpha (0.1.0a2). To install the exact current
version, which is useful when reproducibility is important:
pip install signapy==0.1.0a2
See the SignaPy PyPI project page for available releases and package metadata.
Development installation
These instructions are for contributors, or for anyone working from the source repository rather than the PyPI release:
git clone https://github.com/Carmeisel101/signapy.git
cd signapy
python -m venv .venv
source .venv/bin/activate
python -m pip install -e ".[dev]"
pytest
Runtime dependencies are numpy, pandas, and scipy. SignaPy doesn't
depend on any ML framework. Polars is optional (pip install "signapy[polars]",
or just install polars yourself) and PyArrow is never required.
Usage
Categorical-only (every non-target column analyzed automatically):
import signapy
report = signapy.discover(df, target="converted", positive_class=True)
report.features # feature-level results
report.feature("acquisition_channel") # one feature's evidence
report.feature("acquisition_channel").values # value-level results
Mixed categorical and continuous — pass feature_types to select exactly
which columns to analyze and declare each one's semantic type:
from signapy.profiling import FeatureType
report = signapy.discover(
df,
target="outcome",
positive_class=True,
feature_types={
"category_context": FeatureType.CATEGORICAL,
"continuous_measurement": FeatureType.CONTINUOUS,
},
)
report.feature("continuous_measurement").effect_size # point-biserial coefficient
report.feature("continuous_measurement").p_value # its p-value
report.feature("continuous_measurement").values # always None (see below)
An ordinal feature needs an explicit order — SignaPy never infers one,
not from the values and never alphabetically — declared via an ordered
pandas Categorical:
df["severity"] = pd.Categorical(
df["severity"],
categories=["low", "medium", "high"],
ordered=True,
)
report = signapy.discover(
df,
target="converted",
positive_class=True,
feature_types={"severity": FeatureType.ORDINAL},
)
report.feature("severity").effect_size # Spearman's rho
report.feature(
"severity"
).values # support/rate/baseline/lift, in low->medium->high order
Pandas converts any value omitted from categories=[...] to a missing value;
under SignaPy's missing-data policy, that row is then excluded from this
feature's analysis. Make sure the declaration includes every intended level.
Polars input
discover() accepts a Polars DataFrame directly — no .to_pandas() (and so
no PyArrow) needed. target, positive_class, and feature_types behave
exactly as for pandas, and results match the equivalent pandas input. The
frame is never mutated.
import polars as pl
attempts = attempts.with_columns(
pl.col("roof").cast(pl.Categorical),
pl.col("severity").cast(pl.Enum(["low", "medium", "high"])),
)
report = signapy.discover(
attempts,
target="is_made",
positive_class=1,
feature_types={
"kick_distance": "continuous",
"roof": "categorical",
"severity": "ordinal",
},
)
Dtype mapping to know about:
| Polars dtype | Treated as |
|---|---|
| integer, float | numeric (continuous when declared); null and NaN are both missing |
String, Categorical |
categorical |
Enum |
categorical, or ordinal in the Enum's declared order |
Boolean |
not supported as a categorical or continuous feature (same as pandas bool); usable as a target |
Date, Datetime, Duration |
rejected as continuous/categorical (same as pandas) |
An ordinal feature must be an Enum (an ordered declaration); a plain
Categorical has no declared order and is rejected as ordinal.
discover() supports categorical, continuous, and ordinal features
against a binary target (see v0.1 scope below):
- Without
feature_types(the default), every non-target column ofdfwith anobject, pandasstring, or pandascategorydtype is analyzed as categorical; other dtypes raise a clear error. - With
feature_types, only the named columns are analyzed, each as its declared type (FeatureType.CATEGORICAL,FeatureType.CONTINUOUS, orFeatureType.ORDINAL— the only three supported so far). Numeric columns are never silently treated as continuous, and categorical columns are never silently treated as ordinal — an integer column might be a measured quantity, an ordinal level, or a category identifier, and SignaPy doesn't guess which; declaring it viafeature_typesis required, and an ordinal declaration additionally requires the column to already be an orderedCategorical. - Categorical features get Cramér's V, a chi-square test, and per-category
values(support, target rate, baseline rate, lift), in order of first appearance. Continuous features get a point-biserial correlation, its p-value, and group counts/means indetails— butvaluesis alwaysNonefor continuous features: localizing where within a continuous range the signal lives needs binning, which SignaPy doesn't do automatically (seedocs/architecture.md). Ordinal features get a Spearman rank correlation, its p-value, and the same per-levelvaluesas categorical — but in the feature's declared category order, not order of first appearance.
See docs/metrics.md for how to choose between and
interpret effect_size/p_value across all three feature types
(including why Spearman, not a naive Pearson correlation on level codes, is
the right tool for ordinal data), and
examples/binary_categorical_discovery.py /
examples/mixed_categorical_continuous_discovery.py /
examples/ordinal_binary_discovery.py
for runnable, printed examples.
Also available: the low-level, pure statistical building blocks in
signapy.metrics (association.cramers_v, association.point_biserial,
association.spearman_rho, significance.chi_square,
lift.categorical_lift) that discover() is built on, the result models
(signapy.results.FeatureResult, ValueResult, DiscoveryReport), and the
semantic type enums (signapy.profiling.FeatureType, TargetType).
signapy.discover() characterizes univariate statistical relationships. It
does not train a classifier, select features automatically, or evaluate how
features perform in combination — that judgment, and any modeling built on
this evidence, stays yours.
v0.1 scope
Implemented so far:
- Target: binary classification
- Categorical features: Cramér's V (effect size), chi-square test (p-value), and per-category support/target rate/baseline rate/lift
- Continuous features: point-biserial correlation (effect size and p-value) and group counts/means; no value-level localization yet
- Ordinal features: Spearman rank correlation (effect size and
p-value), and per-level support/target rate/baseline rate/lift in
declared category order; requires an explicit ordered
Categorical - Feature selection: explicit, via the
feature_typesargument; numeric/boolean columns are never inferred as a semantic type, and an order is never inferred for ordinal columns
See docs/architecture.md for the full design,
including the missing-data and dtype policies this slice follows.
Planned next
Not yet implemented: boolean features, semantic type overrides (e.g.
integer-coded categories), multiclass or continuous targets,
continuous-feature value-level localization (binning — unlike ordinal,
which got this via its declared levels), additional value-level metrics
(risk difference, odds ratio, confidence intervals), interaction discovery,
and stability analysis. See the
discovery hierarchy above and
docs/architecture.md for how these fit the overall
design.
Versioning
SignaPy uses PEP 440 versions and will
follow semantic versioning for releases. Pre-release
development builds use .devN suffixes. The current alpha release is
0.1.0a2. The version is defined once, in src/signapy/__init__.py.
License
MIT. See LICENSE.
Metadata
Release files for signapy 0.1.0a2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| signapy-0.1.0a2.tar.gz | 69.1 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| signapy-0.1.0a2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 103.2 kB
Release files / signapy-0.1.0a2.tar.gz
| Download URL | signapy-0.1.0a2.tar.gz |
|---|---|
| Size | 69.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f5306a4a1edc8887daec28ba73c52248ef5cff1c12b1ebc2314b5c6ce083e006
|
|
BLAKE2b-256 checksum How to use checksums |
74db52f70971b84c7b87db29d19d88f0499294f6de3bd148eae16ab4030028ce
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 6, 2026.
Transparency logRelease files / signapy-0.1.0a2-py3-none-any.whl
| Download URL | signapy-0.1.0a2-py3-none-any.whl |
|---|---|
| Size | 34.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
575143bdd6e562acf16af463f4dc89c3b2f8329bae83d3e98fe27269a19026d3
|
|
BLAKE2b-256 checksum How to use checksums |
3d9e8af34e6101d3320520bb2869d9f0e97f7a9cbb304b3e313a5cd4c9a7be0c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 6, 2026.
Transparency logSecurity for signapy 0.1.0a2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for signapy-0.1.0a2.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 6, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.