SemAxis
Interpretable NLI-based text features for scikit-learn.
SemAxis turns raw text into a feature matrix by asking an LLM to generate natural-language hypotheses and scoring each text against them with an NLI model. Every feature is a human-readable sentence — no black-box embeddings.
texts ──► LLM (hypothesis generation) ──► NLI scoring ──► X: (n_texts, n_features)
Both transformers are sklearn-compatible: they work inside Pipeline and are safe to use with cross_val_score.
Installation
pip install semaxis
Unsupervised
UnsupervisedTransformer generates hypotheses that characterize the text collection without labels.
from sklearn.pipeline import Pipeline
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score
from semaxis import UnsupervisedTransformer
pipe = Pipeline([
("vect", UnsupervisedTransformer(
llm="gpt-4o",
nli_model="cross-encoder/nli-deberta-v3-large",
n_features=20,
)),
("clf", LogisticRegression()),
])
cross_val_score(pipe, texts, labels, cv=5)
Supervised
SupervisedTransformer generates hypotheses that discriminate between classes.
Binary
from semaxis import SupervisedTransformer
pipe = Pipeline([
("vect", SupervisedTransformer(
llm="gpt-4o",
nli_model="cross-encoder/nli-deberta-v3-large",
n_features=20,
)),
("clf", LogisticRegression()),
])
cross_val_score(pipe, texts, labels, cv=5)
Labels can be numeric (0/1) or strings ("positive"/"negative").
Multi-class
Use strategy="ovr" (one-vs-rest, default) or strategy="ovo" (one-vs-one):
# OvR: generates n_features hypotheses per class (k × n_features total)
vect = SupervisedTransformer(llm="gpt-4o", nli_model="...", n_features=10, strategy="ovr")
# OvO: generates n_features hypotheses per class pair (C(k,2) × n_features total)
vect = SupervisedTransformer(llm="gpt-4o", nli_model="...", n_features=10, strategy="ovo")
Interpreting features
After fitting, both transformers expose features_ (flat list of hypothesis strings).
SupervisedTransformer also exposes feature_meta_, parallel to features_, which records which class pair each hypothesis came from.
vect = SupervisedTransformer(llm="gpt-4o", nli_model="...", n_features=5, strategy="ovr")
vect.fit(texts, labels)
for hypothesis, meta in zip(vect.features_, vect.feature_meta_):
print(f"[{meta.positive} vs {meta.negative}] {hypothesis}")
[cat vs rest] This text describes feline behavior.
[cat vs rest] This text mentions a cat or kitten.
[dog vs rest] This text describes canine behavior.
[dog vs rest] This text mentions a dog or puppy.
...
Combine with a linear model to get per-hypothesis coefficients:
from sklearn.linear_model import LogisticRegression
import numpy as np
X = vect.transform(texts)
clf = LogisticRegression().fit(X, labels)
for coef, hyp in sorted(zip(clf.coef_[0], vect.features_), key=lambda x: abs(x[0]), reverse=True):
print(f" {coef:+.3f} {hyp}")
Custom LLM
For in-process inference, use LlamaCppClient backed by llama-cpp-python:
from llama_cpp import Llama
from semaxis import UnsupervisedTransformer
from semaxis import LlamaCppClient
llm = LlamaCppClient(Llama(model_path="path/to/model.gguf", n_ctx=4096))
vect = UnsupervisedTransformer(llm=llm, nli_model="cross-encoder/nli-deberta-v3-large")
Install the optional dependency with:
pip install "semaxis[llamacpp]"
Related Work
- Balek et al. (2025) — LLM-based feature generation for interpretable ML
- Yin et al. (2019) — NLI as zero-shot text classifier
- LogiPart (2025) — LLM hypothesis generation + NLI propagation
Citation
@software{semaxis2026,
title = {SemAxis: Interpretable NLI-based text features for scikit-learn},
year = {2026},
}
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file semaxis-0.25.0.tar.gz.
File metadata
- Download URL: semaxis-0.25.0.tar.gz
- Upload date:
- Size: 16.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
99c7df077f55dca7eb8bef14803b48d4fd3bcf4a44afb5163765c2db99a5dac7
|
|
| MD5 |
58152521fe07979847fe64d762c937dd
|
|
| BLAKE2b-256 |
183260af80bdb628413eec1f680cbc04b4b6334f7144e2d2d3f37d461b5807a8
|
Provenance
The following attestation bundles were made for semaxis-0.25.0.tar.gz:
Publisher:
release.yml on pillyshi/semaxis
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
semaxis-0.25.0.tar.gz -
Subject digest:
99c7df077f55dca7eb8bef14803b48d4fd3bcf4a44afb5163765c2db99a5dac7 - Sigstore transparency entry: 2529392953
- Sigstore integration time:
-
Permalink:
pillyshi/semaxis@8261a43988ef5e86fb7caa2d3b1df10c72739b70 -
Branch / Tag:
refs/tags/v0.25.0 - Owner: https://github.com/pillyshi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@8261a43988ef5e86fb7caa2d3b1df10c72739b70 -
Trigger Event:
push
-
Statement type:
File details
Details for the file semaxis-0.25.0-py3-none-any.whl.
File metadata
- Download URL: semaxis-0.25.0-py3-none-any.whl
- Upload date:
- Size: 17.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e565db017b619c8437c458f77c4fcb67c137ea86629a5723376c81b027672bf2
|
|
| MD5 |
6f8dc8ee9134e618ded6cafeca2cad04
|
|
| BLAKE2b-256 |
94831aee80e7b04ca88052bbb7b0c88c99140a2abf7e7fa602983db430ff329d
|
Provenance
The following attestation bundles were made for semaxis-0.25.0-py3-none-any.whl:
Publisher:
release.yml on pillyshi/semaxis
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
semaxis-0.25.0-py3-none-any.whl -
Subject digest:
e565db017b619c8437c458f77c4fcb67c137ea86629a5723376c81b027672bf2 - Sigstore transparency entry: 2529393275
- Sigstore integration time:
-
Permalink:
pillyshi/semaxis@8261a43988ef5e86fb7caa2d3b1df10c72739b70 -
Branch / Tag:
refs/tags/v0.25.0 - Owner: https://github.com/pillyshi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@8261a43988ef5e86fb7caa2d3b1df10c72739b70 -
Trigger Event:
push
-
Statement type: