Induced CSH classifier with pluggable relation-induction backends.
Project description
csh-model
Reusable Python package for the induced CSH classifier extracted from the original sepsis benchmark script and repackaged as a clean GitHub repo.
This is not a castrated toy version. The repo keeps the CSH model layer complete: rigorous PyTorch CSH classifier, singleton/diad/triad relation induction, Platt calibration, sensitivity-threshold helpers, named presets, relation explainability including heatmap data/plots, and optional automatic selection across multiple induced variants. What it removes is the benchmark clutter: GEO downloaders, plotting pipelines, global output folders, auto-pip install, hardcoded Windows cache paths, and paper-specific exports.
What is inside
CSHClassifier trains a PyTorch CSH tabular model after inducing relations from feature scores. You can select the induction backend directly:
| backend | extra dependency | meaning |
|---|---|---|
logreg |
none beyond base install | absolute logistic-regression coefficients |
rf |
none beyond base install | random-forest feature importances |
et |
none beyond base install | extra-trees feature importances |
xgb |
xgboost |
XGBoost feature importances |
rf_logreg |
none beyond base install | weighted RF + logistic scores |
ensemble |
xgboost |
weighted RF + ET + XGB + logistic scores |
Named presets match the original benchmark naming style:
rigorous_csh_classifier_rf_induced
rigorous_csh_classifier_et_induced
rigorous_csh_classifier_xgb_induced
rigorous_csh_classifier_logreg_induced
rigorous_csh_classifier_rf_logreg_induced
rigorous_csh_classifier_ensemble_induced
Install
For normal CSH use:
python -m pip install -e .[torch]
For the XGBoost-induced variant and full preset coverage:
python -m pip install -e .[all]
For explainability heatmaps only, add the visualization extra:
python -m pip install -e .[torch,viz]
For development:
python -m pip install -e .[all,dev]
pytest
Quick start
from csh_model import CSHClassifier, CSHConfig, RelationConfig
clf = CSHClassifier(
induction="xgb",
relation_config=RelationConfig(top_features=12, max_diads=20, max_triads=6),
csh_config=CSHConfig(max_epochs=56, batch_size=512),
random_state=42,
)
clf.fit(X_train, y_train, feature_names=gene_names)
prob = clf.predict_proba(X_test)[:, 1]
labels = clf.predict(X_test)
clf.save("artifacts/csh.joblib")
Load the model later:
from csh_model import load_csh_classifier
clf = load_csh_classifier("artifacts/csh.joblib")
prob = clf.predict_proba(X_new)[:, 1]
Use an original-style preset
from csh_model import make_csh_classifier
clf = make_csh_classifier("rigorous_csh_classifier_xgb_induced", random_state=42)
clf.fit(X_fit, y_fit, X_cal=X_cal, y_cal=y_cal, feature_names=feature_names)
Try multiple CSH variants and select the best
from csh_model import CSHModelSelector, CSHConfig, RelationConfig
selector = CSHModelSelector(
candidates=(
"rigorous_csh_classifier_logreg_induced",
"rigorous_csh_classifier_rf_induced",
"rigorous_csh_classifier_xgb_induced",
"rigorous_csh_classifier_ensemble_induced",
),
relation_config=RelationConfig(top_features=12, max_diads=20, max_triads=6),
csh_config=CSHConfig(max_epochs=56),
metric="auc",
random_state=42,
)
selector.fit(X_train, y_train, X_val=X_val, y_val=y_val, feature_names=feature_names)
print(selector.best_name_, selector.best_score_)
prob = selector.predict_proba(X_test)[:, 1]
If xgboost is not installed and skip_unavailable=True, XGB-based candidates are skipped rather than crashing the whole selector.
Explicit source calibration split
If you already have the source-fit and source-calibration split, pass it directly. This mirrors the benchmark workflow more closely than an internal split.
clf.fit(
X_fit,
y_fit,
X_cal=X_cal,
y_cal=y_cal,
feature_names=feature_names,
)
Inspect induced structure and heatmaps
relations = clf.explain_relations()
scores = clf.induction_scores()
# Pure NumPy, no plotting dependency.
heatmap, relation_labels, feature_labels = clf.relation_heatmap_data()
# Optional matplotlib plot.
clf.plot_relation_heatmap(path="artifacts/csh_relation_heatmap.png")
Each relation includes original feature indices, feature names, arity, and induction score. The heatmap rows are induced relations and the columns are features. By default the matrix shows only the compact feature support used by the CSH relations; pass include_all_features=True to project back to the original input feature space.
Minimal dependency strategy
The base package depends only on:
numpy
scikit-learn
joblib
Optional dependencies are lazy-loaded only when needed:
torch required to fit or predict with CSHClassifier
xgboost required only for induction="xgb" or induction="ensemble"
pandas not required, but DataFrame inputs work if pandas is installed
matplotlib optional, required only for plot_relation_heatmap
No module in this repo auto-installs packages at import time.
Repo layout
src/csh_model/
__init__.py public API
config.py CSH and relation configs
induction.py RF, ET, XGB, LogReg and ensemble feature scoring
relations.py singleton, diad and triad relation construction
torch_model.py PyTorch CSH implementation
calibration.py Platt calibration helpers
estimator.py sklearn-style CSHClassifier
presets.py original-style named presets
selection.py CSHModelSelector for candidate search
explainability.py relation matrices and optional heatmap plotting
thresholds.py sensitivity and rule-out threshold helpers
examples/
quickstart.py
tests/
test_smoke.py
Generalizing beyond gene-expression data
The package is intentionally a numeric tabular CSH implementation rather than a sepsis-specific pipeline. It does not know about GEO, genes, platforms, or clinical cohorts. Any modality can be used after you convert it into a two-dimensional feature matrix:
rows = samples, patients, images, documents, windows, molecules, devices, ...
columns = numeric features, embeddings, biomarkers, handcrafted descriptors, ...
y = binary labels encoded as 0/1 or any two label values
Useful patterns:
# pandas tables preserve column names automatically.
clf.fit(df_train, y_train)
# image/text/time-series workflows should pass extracted features or embeddings.
clf.fit(embedding_matrix, y, feature_names=[f"embed_{i}" for i in range(embedding_matrix.shape[1])])
# domain IDs let the CSH domain context represent cohorts, hospitals, batches, studies, sites, devices, or acquisition protocols.
clf.fit(X, y, domain_ids=site_ids)
prob = clf.predict_proba(X_external, domain_ids=external_site_ids)[:, 1]
The current classifier is binary because the original benchmark was binary. Multi-class can be added later in the PyTorch head and label handling without changing relation induction.
Updating without pain
Most future changes should land in one small place:
| change | edit |
|---|---|
| default architecture | CSHConfig in src/csh_model/config.py |
| relation counts or arity penalty | RelationConfig or src/csh_model/presets.py |
| new induction backend | one function plus one branch in src/csh_model/induction.py |
| new named model | mapping in src/csh_model/presets.py |
| threshold policy | src/csh_model/thresholds.py |
Then run:
make test
Project details
Release history Release notifications | RSS feed
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 csh_model-0.1.2.tar.gz.
File metadata
- Download URL: csh_model-0.1.2.tar.gz
- Upload date:
- Size: 26.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fece8f972c8cdb01eef70051b7b8fb9fdd8463870bb75ad12fb651a5d63408fc
|
|
| MD5 |
83b84b66bfc2bf0847f0ca338c47e244
|
|
| BLAKE2b-256 |
de22d42c3df98d0fadba047a368a02d7c6cb8eb1c647376f6cea93e8b041ac18
|
File details
Details for the file csh_model-0.1.2-py3-none-any.whl.
File metadata
- Download URL: csh_model-0.1.2-py3-none-any.whl
- Upload date:
- Size: 26.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fbff3840b44abe9bd83493238c283ec24a6c0f6062ff1c8bb1a8cd432e75f9d3
|
|
| MD5 |
82886ec8a99d97eedc7c18c934729fe8
|
|
| BLAKE2b-256 |
b783a477adacf2aa809849577263f93287c9cf7182f767806af6aab408f621bc
|