Skip to main content

ASymCat

CI Docs PyPI version Python versions License: MIT Code style: ruff

Measure association between categorical variables — separately in each direction.

Most association measures are symmetric: they report one number for a pair of variables, as if the relationship between X and Y were the same as between Y and X. Many real relationships are not. ASymCat scores association in both directions across a dozen probabilistic, information-theoretic, and statistical measures, behind one consistent interface.

import asymcat

data = asymcat.read_sequences("data.tsv")
coocs = asymcat.collect_cooccs(data)
scorer = asymcat.CatScorer(coocs)

scorer.mle()[("a", "x")]  # (0.83, 0.20)  — P(x|a) vs P(a|x)

That tuple is the whole point: a symmetric summary would collapse the two numbers into one and hide exactly the structure ASymCat is built to reveal — which variable predicts which, and how strongly, in each direction.

Install

pip install asymcat

The interface

The workflow is always the same: read data into paired sequences (or a presence–absence matrix), collect the co-occurrences, build a CatScorer, then call a measure. Every measure returns a mapping from category pairs to a (x→y, y→x) tuple.

import asymcat

data = asymcat.read_sequences("data.tsv")  # or asymcat.read_pa_matrix(...)
coocs = asymcat.collect_cooccs(data)  # order=2, pad="#" for n-grams
scorer = asymcat.CatScorer(coocs, smoothing_method="laplace", smoothing_alpha=1.0)

scorer.mle()  # P(y|x), P(x|y)
scorer.theil_u()  # uncertainty coefficient in each direction
scorer.pmi()  # pointwise mutual information
scorer.fisher()  # exact odds ratios

# Turn any scored measure into matrices for plotting
xy, yx, x_labels, y_labels = asymcat.scorer.scorer2matrices(scorer.pmi())

Choosing a measure

Measure Use it for Family
mle conditional probabilities P(y|x), P(x|y) probabilistic
pmi / pmi_smoothed co-occurrence strength vs. independence information-theoretic
theil_u directional predictability (uncertainty coefficient) information-theoretic
cond_entropy / mutual_information information remaining / shared information-theoretic
chi2 / cramers_v strength of statistical association statistical
fisher exact odds ratios for small samples statistical
log_likelihood_ratio G² association statistic statistical
goodman_kruskal_lambda proportional reduction in prediction error statistical
jaccard_index directional set overlap set-based
tresoldi smoothed measure tuned for sequence alignment specialized

Significance and uncertainty. The statistical tests expose matching p-value scorers (chi2_pvalue, fisher_pvalue, log_likelihood_ratio_pvalue). For any measure — including the information-theoretic ones with no closed-form null — permutation_pvalue(measure, ...) estimates significance by shuffling the x↔y pairing, and bootstrap_ci(measure, ...) returns percentile confidence intervals by resampling the co-occurrences.

scorer.chi2_pvalue()  # closed-form p-values
scorer.permutation_pvalue("theil_u", n_permutations=1000, seed=0)
scorer.bootstrap_ci("theil_u", n_bootstrap=1000, confidence_level=0.95, seed=0)

Why ASymCat

  • Directional by construction — every measure reports x→y and y→x separately, surfacing asymmetries symmetric measures average away.
  • One consistent API across a dozen measures — swap scorer.mle() for scorer.theil_u() without changing anything else.
  • Robust smoothing via FreqProb for numerically stable probability estimates on sparse data.
  • Typed and tested — full type hints (py.typed), strict linting and type-checking, and a test suite run across Python 3.10–3.12.

Documentation

  • Documentation site — user guide and full API reference.
  • User Guide — concepts, measure selection, data preparation, and worked examples.
  • The Tresoldi Measure — motivation and definition of the specialized tresoldi measure.
  • API Reference — every public class and function, generated from the source.

Applications

Directional association between categories recurs across fields: grapheme–phoneme correspondence and sound-change directionality in linguistics; asymmetric species co-occurrence in ecology; feature screening in machine learning; and dependency analysis in categorical analytics. Sample datasets for several of these live in resources/.

Citation

If you use ASymCat in academic research, please cite:

@software{tresoldi_asymcat,
  author  = {Tresoldi, Tiago},
  title   = {ASymCat: Asymmetric measures of association between categorical variables},
  url     = {https://github.com/tresoldi/asymcat}
}

License

MIT — see LICENSE.

Metadata

Release files for asymcat 0.6.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for asymcat 0.6.0
File Size Uploaded
asymcat-0.6.0.tar.gz 33.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for asymcat 0.6.0
File Interpreter ABI Platform
asymcat-0.6.0-py3-none-any.whl Python 3 none any Details

Total release size: 62.5 kB

Release files / asymcat-0.6.0.tar.gz

Download URL asymcat-0.6.0.tar.gz
Size 33.1 kB
Tags Source
SHA-256 checksum
How to use checksums
505357cba09760854c8329b9a8d740ac59cf54432279b02da9d28c6b274d24a7
BLAKE2b-256 checksum
How to use checksums
a69fdb3bdefaf3015ce25bec31e3740d57549a44d8cd87aff2e3486c3a8de278
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 Aug 5, 2026.

Transparency log

Release files / asymcat-0.6.0-py3-none-any.whl

Download URL asymcat-0.6.0-py3-none-any.whl
Size 29.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5d9d2236965d2f4740bac66ffec727c2d1a6e7e2777c71dc5d67b1bb692f6447
BLAKE2b-256 checksum
How to use checksums
93cd5266a79d5dd4a957f06ff98a38270d4d49435855d8a4ef2aa8a54a3fc21c
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 Aug 5, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.6.0 This release

2 release files

0.4.0

2 release files

0.3.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page