texgisa-survival 2.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- texgisa_survival-2.2.0/.github/workflows/ci.yml +17 -0
- texgisa_survival-2.2.0/.github/workflows/release.yml +91 -0
- texgisa_survival-2.2.0/API_REFERENCE.md +11 -0
- texgisa_survival-2.2.0/BACKENDS.md +25 -0
- texgisa_survival-2.2.0/CHANGELOG.md +30 -0
- texgisa_survival-2.2.0/CITATION.cff +62 -0
- texgisa_survival-2.2.0/CONTRIBUTING.md +327 -0
- texgisa_survival-2.2.0/EXTENSIONS_SINCE_ICDM.md +3 -0
- texgisa_survival-2.2.0/LICENSE +21 -0
- texgisa_survival-2.2.0/MANIFEST.in +8 -0
- texgisa_survival-2.2.0/PKG-INFO +232 -0
- texgisa_survival-2.2.0/README.md +155 -0
- texgisa_survival-2.2.0/SCIENTIFIC_NOTES.md +9 -0
- texgisa_survival-2.2.0/benchmarks/README.md +107 -0
- texgisa_survival-2.2.0/benchmarks/check_refit.py +7 -0
- texgisa_survival-2.2.0/benchmarks/configs.json +3179 -0
- texgisa_survival-2.2.0/benchmarks/expert_feedback.py +87 -0
- texgisa_survival-2.2.0/benchmarks/legacy/check_refit.py +49 -0
- texgisa_survival-2.2.0/benchmarks/legacy/configs.json +3179 -0
- texgisa_survival-2.2.0/benchmarks/legacy/run_benchmark.py +339 -0
- texgisa_survival-2.2.0/benchmarks/legacy/src/texgisa_survival/__init__.py +92 -0
- texgisa_survival-2.2.0/benchmarks/legacy/src/texgisa_survival/api.py +642 -0
- texgisa_survival-2.2.0/benchmarks/legacy/src/texgisa_survival/diagnostics.py +385 -0
- texgisa_survival-2.2.0/benchmarks/legacy/src/texgisa_survival/explainers/__init__.py +451 -0
- texgisa_survival-2.2.0/benchmarks/legacy/src/texgisa_survival/explainers/counterfactual.py +849 -0
- texgisa_survival-2.2.0/benchmarks/legacy/src/texgisa_survival/explainers/texgi.py +281 -0
- texgisa_survival-2.2.0/benchmarks/legacy/src/texgisa_survival/metrics/__init__.py +414 -0
- texgisa_survival-2.2.0/benchmarks/legacy/src/texgisa_survival/models/__init__.py +18 -0
- texgisa_survival-2.2.0/benchmarks/legacy/src/texgisa_survival/models/base.py +280 -0
- texgisa_survival-2.2.0/benchmarks/legacy/src/texgisa_survival/models/multimodal.py +543 -0
- texgisa_survival-2.2.0/benchmarks/legacy/src/texgisa_survival/models/texgisa.py +1279 -0
- texgisa_survival-2.2.0/benchmarks/legacy/src/texgisa_survival/models/texgisa_advanced.py +951 -0
- texgisa_survival-2.2.0/benchmarks/legacy/src/texgisa_survival/preprocessing/__init__.py +65 -0
- texgisa_survival-2.2.0/benchmarks/legacy/src/texgisa_survival/preprocessing/image.py +477 -0
- texgisa_survival-2.2.0/benchmarks/legacy/src/texgisa_survival/preprocessing/sensor.py +430 -0
- texgisa_survival-2.2.0/benchmarks/legacy/src/texgisa_survival/preprocessing/tabular.py +330 -0
- texgisa_survival-2.2.0/benchmarks/legacy/src/texgisa_survival/texgi_utils.py +456 -0
- texgisa_survival-2.2.0/benchmarks/legacy/src/texgisa_survival/visualization/__init__.py +485 -0
- texgisa_survival-2.2.0/benchmarks/results/expert_feedback.json +404 -0
- texgisa_survival-2.2.0/benchmarks/results/flchain.json +2135 -0
- texgisa_survival-2.2.0/benchmarks/results/gbsg.json +2141 -0
- texgisa_survival-2.2.0/benchmarks/results/metabric.json +2161 -0
- texgisa_survival-2.2.0/benchmarks/results/summary.md +37 -0
- texgisa_survival-2.2.0/benchmarks/results/support.json +2182 -0
- texgisa_survival-2.2.0/benchmarks/run_benchmark.py +327 -0
- texgisa_survival-2.2.0/benchmarks/summarize.py +97 -0
- texgisa_survival-2.2.0/examples/advanced_texgisa_example.py +322 -0
- texgisa_survival-2.2.0/examples/basic_texgisa_example.py +175 -0
- texgisa_survival-2.2.0/examples/current_recipe.py +13 -0
- texgisa_survival-2.2.0/examples/expert_prior_texgi.py +19 -0
- texgisa_survival-2.2.0/examples/gbsg2_expert_rules.py +81 -0
- texgisa_survival-2.2.0/pyproject.toml +205 -0
- texgisa_survival-2.2.0/setup.cfg +4 -0
- texgisa_survival-2.2.0/skills/texgisa-prior-finder/SKILL.md +104 -0
- texgisa_survival-2.2.0/src/texgisa_survival/__init__.py +94 -0
- texgisa_survival-2.2.0/src/texgisa_survival/_recipes/__init__.py +1 -0
- texgisa_survival-2.2.0/src/texgisa_survival/_recipes/adapters.py +305 -0
- texgisa_survival-2.2.0/src/texgisa_survival/_recipes/aft.py +62 -0
- texgisa_survival-2.2.0/src/texgisa_survival/_recipes/anchors.py +46 -0
- texgisa_survival-2.2.0/src/texgisa_survival/_recipes/boost_ci.py +244 -0
- texgisa_survival-2.2.0/src/texgisa_survival/_recipes/budget.py +37 -0
- texgisa_survival-2.2.0/src/texgisa_survival/_recipes/cache.py +76 -0
- texgisa_survival-2.2.0/src/texgisa_survival/_recipes/candidate.py +150 -0
- texgisa_survival-2.2.0/src/texgisa_survival/_recipes/censor_representation.py +196 -0
- texgisa_survival-2.2.0/src/texgisa_survival/_recipes/data.py +114 -0
- texgisa_survival-2.2.0/src/texgisa_survival/_recipes/exploratory.py +422 -0
- texgisa_survival-2.2.0/src/texgisa_survival/_recipes/frontier.py +361 -0
- texgisa_survival-2.2.0/src/texgisa_survival/_recipes/full.py +203 -0
- texgisa_survival-2.2.0/src/texgisa_survival/_recipes/ibs_upgrade.py +125 -0
- texgisa_survival-2.2.0/src/texgisa_survival/_recipes/improved.py +520 -0
- texgisa_survival-2.2.0/src/texgisa_survival/_recipes/logistic.py +27 -0
- texgisa_survival-2.2.0/src/texgisa_survival/_recipes/losses.py +58 -0
- texgisa_survival-2.2.0/src/texgisa_survival/_recipes/metrics.py +70 -0
- texgisa_survival-2.2.0/src/texgisa_survival/_recipes/neural_aft.py +90 -0
- texgisa_survival-2.2.0/src/texgisa_survival/_recipes/pch.py +23 -0
- texgisa_survival-2.2.0/src/texgisa_survival/_recipes/pilot.py +124 -0
- texgisa_survival-2.2.0/src/texgisa_survival/_recipes/predecessor.py +94 -0
- texgisa_survival-2.2.0/src/texgisa_survival/_recipes/research_extra.py +94 -0
- texgisa_survival-2.2.0/src/texgisa_survival/_recipes/research_round2.py +106 -0
- texgisa_survival-2.2.0/src/texgisa_survival/_recipes/scaled_predecessor.py +78 -0
- texgisa_survival-2.2.0/src/texgisa_survival/_recipes/single_metric.py +275 -0
- texgisa_survival-2.2.0/src/texgisa_survival/_recipes/single_metric_evidence.py +27 -0
- texgisa_survival-2.2.0/src/texgisa_survival/_recipes/strengthened.py +503 -0
- texgisa_survival-2.2.0/src/texgisa_survival/_recipes/tcga_knowledge.py +43 -0
- texgisa_survival-2.2.0/src/texgisa_survival/_recipes/tree_baselines.py +25 -0
- texgisa_survival-2.2.0/src/texgisa_survival/api.py +658 -0
- texgisa_survival-2.2.0/src/texgisa_survival/backends/__init__.py +1 -0
- texgisa_survival-2.2.0/src/texgisa_survival/backends/native_configs.json +2206 -0
- texgisa_survival-2.2.0/src/texgisa_survival/backends/native_models.py +318 -0
- texgisa_survival-2.2.0/src/texgisa_survival/backends/runner.py +80 -0
- texgisa_survival-2.2.0/src/texgisa_survival/backends/worker.py +21 -0
- texgisa_survival-2.2.0/src/texgisa_survival/data/__init__.py +324 -0
- texgisa_survival-2.2.0/src/texgisa_survival/data/gene_prior.json +485 -0
- texgisa_survival-2.2.0/src/texgisa_survival/data/manager.py +130 -0
- texgisa_survival-2.2.0/src/texgisa_survival/diagnostics.py +385 -0
- texgisa_survival-2.2.0/src/texgisa_survival/explainers/__init__.py +451 -0
- texgisa_survival-2.2.0/src/texgisa_survival/explainers/counterfactual.py +849 -0
- texgisa_survival-2.2.0/src/texgisa_survival/explainers/texgi.py +281 -0
- texgisa_survival-2.2.0/src/texgisa_survival/metrics/__init__.py +414 -0
- texgisa_survival-2.2.0/src/texgisa_survival/models/__init__.py +18 -0
- texgisa_survival-2.2.0/src/texgisa_survival/models/base.py +280 -0
- texgisa_survival-2.2.0/src/texgisa_survival/models/multimodal.py +543 -0
- texgisa_survival-2.2.0/src/texgisa_survival/models/texgisa.py +1231 -0
- texgisa_survival-2.2.0/src/texgisa_survival/models/texgisa_advanced.py +953 -0
- texgisa_survival-2.2.0/src/texgisa_survival/preprocessing/__init__.py +65 -0
- texgisa_survival-2.2.0/src/texgisa_survival/preprocessing/image.py +477 -0
- texgisa_survival-2.2.0/src/texgisa_survival/preprocessing/sensor.py +430 -0
- texgisa_survival-2.2.0/src/texgisa_survival/preprocessing/tabular.py +330 -0
- texgisa_survival-2.2.0/src/texgisa_survival/priors.json +78 -0
- texgisa_survival-2.2.0/src/texgisa_survival/recipe_configs.json +1010 -0
- texgisa_survival-2.2.0/src/texgisa_survival/recipes.py +151 -0
- texgisa_survival-2.2.0/src/texgisa_survival/texgi_utils.py +466 -0
- texgisa_survival-2.2.0/src/texgisa_survival/visualization/__init__.py +485 -0
- texgisa_survival-2.2.0/src/texgisa_survival.egg-info/PKG-INFO +232 -0
- texgisa_survival-2.2.0/src/texgisa_survival.egg-info/SOURCES.txt +130 -0
- texgisa_survival-2.2.0/src/texgisa_survival.egg-info/dependency_links.txt +1 -0
- texgisa_survival-2.2.0/src/texgisa_survival.egg-info/requires.txt +54 -0
- texgisa_survival-2.2.0/src/texgisa_survival.egg-info/top_level.txt +1 -0
- texgisa_survival-2.2.0/tests/__init__.py +6 -0
- texgisa_survival-2.2.0/tests/conftest.py +90 -0
- texgisa_survival-2.2.0/tests/test_benchmark_preprocessing.py +23 -0
- texgisa_survival-2.2.0/tests/test_counterfactual.py +191 -0
- texgisa_survival-2.2.0/tests/test_data_manager.py +74 -0
- texgisa_survival-2.2.0/tests/test_diagnostics.py +243 -0
- texgisa_survival-2.2.0/tests/test_e2e_v2.py +214 -0
- texgisa_survival-2.2.0/tests/test_kaplan_meier.py +71 -0
- texgisa_survival-2.2.0/tests/test_metrics.py +183 -0
- texgisa_survival-2.2.0/tests/test_models.py +394 -0
- texgisa_survival-2.2.0/tests/test_regularizer_gradients.py +495 -0
- texgisa_survival-2.2.0/tests/test_release_interfaces.py +49 -0
- texgisa_survival-2.2.0/tests/test_scientific_semantics.py +138 -0
- texgisa_survival-2.2.0/tests/test_texgi_utils.py +330 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
name: Test source candidate
|
|
2
|
+
on: [push, pull_request]
|
|
3
|
+
jobs:
|
|
4
|
+
tests:
|
|
5
|
+
strategy:
|
|
6
|
+
matrix:
|
|
7
|
+
os: [ubuntu-latest, windows-latest]
|
|
8
|
+
python: ['3.11', '3.12']
|
|
9
|
+
runs-on: ${{ matrix.os }}
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v4
|
|
12
|
+
- uses: actions/setup-python@v5
|
|
13
|
+
with:
|
|
14
|
+
python-version: ${{ matrix.python }}
|
|
15
|
+
- run: python -m pip install ".[dev,recipes,baselines]" build
|
|
16
|
+
- run: python -m pytest tests --override-ini="addopts="
|
|
17
|
+
- run: python -m build
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
# Publishes to PyPI with Trusted Publishing (no API token stored in GitHub).
|
|
4
|
+
# One-time setup on pypi.org and test.pypi.org: add a "pending publisher" for
|
|
5
|
+
# owner: Kunjoe7, repository: texgisa-survival, workflow: release.yml,
|
|
6
|
+
# environment: pypi (PyPI) / testpypi (TestPyPI)
|
|
7
|
+
#
|
|
8
|
+
# - Manual run (Actions tab -> Release -> Run workflow): build, test, upload to TestPyPI
|
|
9
|
+
# - Publishing a GitHub release (tag vX.Y.Z): build, test, upload to PyPI
|
|
10
|
+
|
|
11
|
+
on:
|
|
12
|
+
release:
|
|
13
|
+
types: [published]
|
|
14
|
+
workflow_dispatch:
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
build:
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v4
|
|
21
|
+
- uses: actions/setup-python@v5
|
|
22
|
+
with:
|
|
23
|
+
python-version: "3.11"
|
|
24
|
+
- name: Build sdist and wheel
|
|
25
|
+
run: |
|
|
26
|
+
python -m pip install --upgrade pip build twine
|
|
27
|
+
python -m build
|
|
28
|
+
twine check --strict dist/*
|
|
29
|
+
- name: Check that the tag matches the package version
|
|
30
|
+
if: github.event_name == 'release'
|
|
31
|
+
run: |
|
|
32
|
+
VERSION=$(python -c "import tomllib;print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])")
|
|
33
|
+
test "v${VERSION}" = "${GITHUB_REF_NAME}" || { echo "tag ${GITHUB_REF_NAME} != v${VERSION}"; exit 1; }
|
|
34
|
+
- uses: actions/upload-artifact@v4
|
|
35
|
+
with:
|
|
36
|
+
name: dist
|
|
37
|
+
path: dist/
|
|
38
|
+
|
|
39
|
+
test-wheel:
|
|
40
|
+
needs: build
|
|
41
|
+
runs-on: ${{ matrix.os }}
|
|
42
|
+
strategy:
|
|
43
|
+
matrix:
|
|
44
|
+
os: [ubuntu-latest, windows-latest]
|
|
45
|
+
steps:
|
|
46
|
+
- uses: actions/checkout@v4
|
|
47
|
+
- uses: actions/setup-python@v5
|
|
48
|
+
with:
|
|
49
|
+
python-version: "3.11"
|
|
50
|
+
- uses: actions/download-artifact@v4
|
|
51
|
+
with:
|
|
52
|
+
name: dist
|
|
53
|
+
path: dist/
|
|
54
|
+
- name: Install the built wheel and run the tests against it
|
|
55
|
+
shell: bash
|
|
56
|
+
run: |
|
|
57
|
+
python -m pip install --upgrade pip
|
|
58
|
+
WHEEL=$(ls dist/*.whl)
|
|
59
|
+
python -m pip install "${WHEEL}[recipes,baselines]" pytest
|
|
60
|
+
mv src src_unused # make sure the installed wheel is tested, not the source tree
|
|
61
|
+
python -m pytest tests -q --override-ini="addopts="
|
|
62
|
+
|
|
63
|
+
publish-testpypi:
|
|
64
|
+
if: github.event_name == 'workflow_dispatch'
|
|
65
|
+
needs: test-wheel
|
|
66
|
+
runs-on: ubuntu-latest
|
|
67
|
+
environment: testpypi
|
|
68
|
+
permissions:
|
|
69
|
+
id-token: write
|
|
70
|
+
steps:
|
|
71
|
+
- uses: actions/download-artifact@v4
|
|
72
|
+
with:
|
|
73
|
+
name: dist
|
|
74
|
+
path: dist/
|
|
75
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
76
|
+
with:
|
|
77
|
+
repository-url: https://test.pypi.org/legacy/
|
|
78
|
+
|
|
79
|
+
publish-pypi:
|
|
80
|
+
if: github.event_name == 'release'
|
|
81
|
+
needs: test-wheel
|
|
82
|
+
runs-on: ubuntu-latest
|
|
83
|
+
environment: pypi
|
|
84
|
+
permissions:
|
|
85
|
+
id-token: write
|
|
86
|
+
steps:
|
|
87
|
+
- uses: actions/download-artifact@v4
|
|
88
|
+
with:
|
|
89
|
+
name: dist
|
|
90
|
+
path: dist/
|
|
91
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Current API
|
|
2
|
+
|
|
3
|
+
`SurvivalRecipe(recipe="RefineCDF", dataset="custom", config_id=0, config=None, random_state=271, threads=1)` implements `fit(X,time,event)`, `predict_risk(X)`, `predict_survival(X,times=None)`, `predict_time(X)`, `explain(X,integration_steps=20,time_samples=None)` and `save(path)`.
|
|
4
|
+
|
|
5
|
+
Pandas column names/order must match at prediction. NumPy inputs receive x0,x1,... column names. Features must be finite numeric values; explicit category encoding belongs to the caller. Named domain rules validate their required feature names. No test outcomes are accepted by prediction methods. The reference for TEXGI and all internal transformations are fitted on training subsets.
|
|
6
|
+
|
|
7
|
+
`metadata_` records fitting/stopping/calibration row indices, epoch selection, calibration, prior diagnostics and output semantics. `config_` records the effective configuration. `feature_names_in_`, `n_features_in_` and `time_grid_` expose input/grid metadata. Recipe save files contain model objects and must be treated as trusted-code artifacts.
|
|
8
|
+
|
|
9
|
+
`available_recipes()` lists8 callable own variants. `backends.runner.available_methods()` lists20 public-package/author-array routes plus3 author CLI routes. `fit_predict` returns a dictionary rather than falsely promising every native estimator implements every prediction type. `run_author_cli` accepts an original author checkout, argv and an optional interpreter/log path; exceptions preserve author failures. Source code is never modified by the runner.
|
|
10
|
+
|
|
11
|
+
The inherited `TexGISa` class remains available at package root. Its legacy constructor and rule methods are defined in `api.py`; current benchmark numbers correspond to `SurvivalRecipe`, not a default legacy estimator.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Existing-method backends
|
|
2
|
+
|
|
3
|
+
Native inputs: finite numeric fitting matrix, observed durations, binary event indicator, and query matrix. No user innovation modules are fed into a baseline.
|
|
4
|
+
|
|
5
|
+
| Route | Provider | Outputs | Dependency/runtime |
|
|
6
|
+
|---|---|---|---|
|
|
7
|
+
| Cox, Weibull, Lognormal, Loglogistic | lifelines | native risk, survival and median | baselines extra |
|
|
8
|
+
| Coxnet, RandomSurvivalForest, GradientBoostingCox | scikit-survival | native risk and survival | baselines extra |
|
|
9
|
+
| DeepSurv, CoxTime, CoxCC, DeepHit, LogisticHazard, PCHazard, PMF, MTLR, NMTLR | pycox | estimator-specific risk and/or native curve | baselines extra |
|
|
10
|
+
| HarrellNMSE, HarrellNMAE, UnoNMSE, UnoNMAE | original ICDM2021 source | scalar time and negative-time risk, no curve | separate NumPy1.x interpreter; author_source argument |
|
|
11
|
+
| DRO | author run_dro_cox_split.py | original CLI outputs/files | run_author_cli; original formats/environment |
|
|
12
|
+
| Kernet | author demo_tuna_kernet.py | original CLI outputs/files | run_author_cli; teacher/config files as upstream requires |
|
|
13
|
+
| SODEN | author main.py | original CLI outputs/files | run_author_cli; original formats/environment |
|
|
14
|
+
|
|
15
|
+
`fit_predict(...,python_executable=...,author_source=...)` isolates original scalar-time code. The6 original ICDM2021 source hashes are verified before import. No missing NumPy aliases are injected. Author source: https://github.com/yanlirock/local_global_survival at commit2eee054ccbf8b8ab9750c79d640ce72ef8f836d1.
|
|
16
|
+
|
|
17
|
+
Classical public configurations use `pen` and Cox `l1`; Coxnet uses `alpha,l1_ratio`; RSF uses `n_estimators,max_depth,min_samples_leaf`; boosted Cox uses `n_estimators,learning_rate,max_depth,min_samples_leaf,subsample`. Neural configurations use the frozen `native_configs.json` keys, including hidden/dropout/lr/wd/batch/epochs/patience and model-specific bins/alpha/sigma. Defaults are the first saved configuration, not an automatic test-selected best model.
|
|
18
|
+
|
|
19
|
+
Native arrays are not clipped or repaired. Deriving a common evaluation metric from them is a separate operation. Infinities or unsupported outputs remain visible. Author CLI data adapters in the companion reproduction directory document the exact experimental IO changes; they do not alter author losses, networks or optimizers. A method's upstream data-format requirements remain part of the contract.
|
|
20
|
+
|
|
21
|
+
Optional libraries are installed from their distributions; they are not relicensed as MIT by this wrapper. Keep GPL-licensed dependency terms and any upstream author-source terms when redistributing combined works. This archive does not bundle those author implementations.
|
|
22
|
+
|
|
23
|
+
## Method provenance
|
|
24
|
+
|
|
25
|
+
The original scalar-time objectives are described by Wang, Li and Chignell, "Combining Ranking and Point-wise Losses for Training Deep Survival Analysis Models," ICDM2021,689–698, DOI10.1109/ICDM51629.2021.00080. Survival kernets: Chen, JMLR25(40):1–78,2024, https://jmlr.org/papers/v25/22-0667.html . Sample-split DRO: Hu and Chen, JMLR25(246):1–85,2024, https://jmlr.org/papers/v25/23-0888.html . Package-specific method documentation remains the authority for each native estimator.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Changes
|
|
2
|
+
|
|
3
|
+
## 2.2.0 (2026-11-12)
|
|
4
|
+
|
|
5
|
+
- Add `skills/texgisa-prior-finder`, a step-by-step procedure for finding expert priors
|
|
6
|
+
(important-feature lists and directional rules) in published sources, with provenance and a
|
|
7
|
+
final review by a domain expert.
|
|
8
|
+
- Add `SurvivalRecipe`, the tuned default configuration of TexGISa, with separate
|
|
9
|
+
`predict_risk`, `predict_survival`, `predict_time` and `explain` outputs.
|
|
10
|
+
- Add `backends.runner`: one call (`fit_predict`) to 20 established survival models from
|
|
11
|
+
lifelines, scikit-survival, pycox and the original ICDM 2021 code, each run unchanged in its own
|
|
12
|
+
process; `run_author_cli` runs DRO, survival kernets and SODEN through their authors' programs.
|
|
13
|
+
- Keep fitted preprocessing, training partitions and calibration diagnostics with the model.
|
|
14
|
+
- Benchmark records, configurations and summaries in `benchmarks/`.
|
|
15
|
+
|
|
16
|
+
## 2.1.0
|
|
17
|
+
|
|
18
|
+
- Benchmark scripts and per-fold results in `benchmarks/`; defaults set from nested
|
|
19
|
+
cross-validation.
|
|
20
|
+
|
|
21
|
+
## 2.0.1
|
|
22
|
+
|
|
23
|
+
- Attribution priors now back-propagate to the network (`create_graph=True`).
|
|
24
|
+
- Fix the sign of `concordance_index`, rule thresholds on standardized features,
|
|
25
|
+
save/load, and the Brier-score column alignment.
|
|
26
|
+
- Fix `MySATrainer` on recent PyTorch releases.
|
|
27
|
+
|
|
28
|
+
## 2.0.0
|
|
29
|
+
|
|
30
|
+
- First public release on GitHub.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
cff-version: 1.2.0
|
|
2
|
+
title: "texgisa-survival: Interpretable and Interactive Deep Discrete-Time Survival Analysis"
|
|
3
|
+
message: >-
|
|
4
|
+
If you use this software, please cite it using the
|
|
5
|
+
metadata from this file, and cite the method paper below.
|
|
6
|
+
type: software
|
|
7
|
+
authors:
|
|
8
|
+
- family-names: Qin
|
|
9
|
+
given-names: Xinyu
|
|
10
|
+
affiliation: Baylor University
|
|
11
|
+
email: Xinyu_Qin1@baylor.edu
|
|
12
|
+
- family-names: Yu
|
|
13
|
+
given-names: Ruiheng
|
|
14
|
+
affiliation: Florida State University
|
|
15
|
+
email: ry26@fsu.edu
|
|
16
|
+
- family-names: Li
|
|
17
|
+
given-names: Yan
|
|
18
|
+
affiliation: University of Toronto
|
|
19
|
+
- family-names: Wang
|
|
20
|
+
given-names: Lu
|
|
21
|
+
affiliation: Baylor University
|
|
22
|
+
email: Lu_Wang@baylor.edu
|
|
23
|
+
repository-code: 'https://github.com/Kunjoe7/texgisa-survival'
|
|
24
|
+
url: 'https://github.com/Kunjoe7/texgisa-survival'
|
|
25
|
+
abstract: >-
|
|
26
|
+
A PyTorch library for discrete-time deep survival analysis with
|
|
27
|
+
time-dependent feature attributions computed against extreme baselines
|
|
28
|
+
(TEXGI) and attribution priors that let domain experts shape training.
|
|
29
|
+
keywords:
|
|
30
|
+
- survival analysis
|
|
31
|
+
- deep learning
|
|
32
|
+
- explainable AI
|
|
33
|
+
- interactive machine learning
|
|
34
|
+
license: MIT
|
|
35
|
+
version: 2.2.0
|
|
36
|
+
date-released: 2026-11-12
|
|
37
|
+
preferred-citation:
|
|
38
|
+
type: conference-paper
|
|
39
|
+
authors:
|
|
40
|
+
- family-names: Qin
|
|
41
|
+
given-names: Xinyu
|
|
42
|
+
- family-names: Yu
|
|
43
|
+
given-names: Ruiheng
|
|
44
|
+
- family-names: Khayati
|
|
45
|
+
given-names: Armin
|
|
46
|
+
- family-names: Qiu
|
|
47
|
+
given-names: Zixiao
|
|
48
|
+
- family-names: Zou
|
|
49
|
+
given-names: Gengyi
|
|
50
|
+
- family-names: Li
|
|
51
|
+
given-names: Yan
|
|
52
|
+
- family-names: Wang
|
|
53
|
+
given-names: Lu
|
|
54
|
+
title: >-
|
|
55
|
+
Interpretable and Interactive Deep Survival Analysis with
|
|
56
|
+
Time-dependent EXtreme Gradient Integration
|
|
57
|
+
collection-title: >-
|
|
58
|
+
2025 IEEE International Conference on Data Mining (ICDM)
|
|
59
|
+
year: 2025
|
|
60
|
+
start: 673
|
|
61
|
+
end: 682
|
|
62
|
+
doi: 10.1109/ICDM65498.2025.00075
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
# Contributing to DHAI Survival
|
|
2
|
+
|
|
3
|
+
First off, thank you for considering contributing to DHAI Survival! It's people like you that make DHAI Survival such a great tool for the survival analysis community.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Code of Conduct](#code-of-conduct)
|
|
8
|
+
- [Getting Started](#getting-started)
|
|
9
|
+
- [How Can I Contribute?](#how-can-i-contribute)
|
|
10
|
+
- [Development Setup](#development-setup)
|
|
11
|
+
- [Style Guidelines](#style-guidelines)
|
|
12
|
+
- [Commit Messages](#commit-messages)
|
|
13
|
+
- [Pull Request Process](#pull-request-process)
|
|
14
|
+
- [Community](#community)
|
|
15
|
+
|
|
16
|
+
## Code of Conduct
|
|
17
|
+
|
|
18
|
+
Contributors should communicate respectfully and describe reproducible technical issues. Use the [public issue tracker](https://github.com/Kunjoe7/texgisa-survival/issues) for project discussions.
|
|
19
|
+
|
|
20
|
+
## Getting Started
|
|
21
|
+
|
|
22
|
+
1. Fork the repository on GitHub
|
|
23
|
+
2. Clone your fork locally
|
|
24
|
+
3. Create a new branch for your contribution
|
|
25
|
+
4. Make your changes
|
|
26
|
+
5. Push to your fork and submit a pull request
|
|
27
|
+
|
|
28
|
+
## How Can I Contribute?
|
|
29
|
+
|
|
30
|
+
### Reporting Bugs
|
|
31
|
+
|
|
32
|
+
Before creating bug reports, please check existing issues as you might find that you don't need to create one. When you are creating a bug report, please include as many details as possible:
|
|
33
|
+
|
|
34
|
+
- **Use a clear and descriptive title**
|
|
35
|
+
- **Describe the exact steps to reproduce the problem**
|
|
36
|
+
- **Provide specific examples** to demonstrate the steps
|
|
37
|
+
- **Describe the behavior you observed** and explain why it's a problem
|
|
38
|
+
- **Explain the behavior you expected** to see instead
|
|
39
|
+
- **Include screenshots** if relevant
|
|
40
|
+
- **Include your environment details** (Python version, OS, package versions)
|
|
41
|
+
|
|
42
|
+
### Suggesting Enhancements
|
|
43
|
+
|
|
44
|
+
Enhancement suggestions are tracked as GitHub issues. When creating an enhancement suggestion, please include:
|
|
45
|
+
|
|
46
|
+
- **Use a clear and descriptive title**
|
|
47
|
+
- **Provide a detailed description** of the suggested enhancement
|
|
48
|
+
- **Provide specific examples** to demonstrate the enhancement
|
|
49
|
+
- **Describe the current behavior** and explain why it's insufficient
|
|
50
|
+
- **Explain why this enhancement would be useful** to most users
|
|
51
|
+
- **List any alternatives** you've considered
|
|
52
|
+
|
|
53
|
+
### Code Contributions
|
|
54
|
+
|
|
55
|
+
#### Your First Code Contribution
|
|
56
|
+
|
|
57
|
+
Unsure where to begin? You can start by looking through these issues:
|
|
58
|
+
|
|
59
|
+
- Issues labeled `good first issue` - issues which should be relatively simple to implement
|
|
60
|
+
- Issues labeled `help wanted` - issues which need extra attention
|
|
61
|
+
- Issues labeled `documentation` - improvements or additions to documentation
|
|
62
|
+
|
|
63
|
+
#### Development Setup
|
|
64
|
+
|
|
65
|
+
1. **Fork and clone the repository**
|
|
66
|
+
```bash
|
|
67
|
+
git clone https://github.com/Kunjoe7/texgisa-survival.git
|
|
68
|
+
cd texgisa_survival
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
2. **Create a virtual environment**
|
|
72
|
+
```bash
|
|
73
|
+
python -m venv venv
|
|
74
|
+
source venv/bin/activate # On Windows: venv\Scripts\activate
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
3. **Install in development mode**
|
|
78
|
+
```bash
|
|
79
|
+
pip install -e ".[dev]"
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
4. **Install pre-commit hooks**
|
|
83
|
+
```bash
|
|
84
|
+
pre-commit install
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
5. **Create a branch for your feature**
|
|
88
|
+
```bash
|
|
89
|
+
git checkout -b feature/your-feature-name
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Adding New Models
|
|
93
|
+
|
|
94
|
+
If you're adding a new survival model:
|
|
95
|
+
|
|
96
|
+
1. Create a new module in `src/texgisa_survival/models/`
|
|
97
|
+
2. Inherit from the `BaseModel` class
|
|
98
|
+
3. Implement required methods: `fit()`, `predict_risk()`, etc.
|
|
99
|
+
4. Add comprehensive tests in `tests/test_models.py`
|
|
100
|
+
5. Add documentation with examples
|
|
101
|
+
6. Update the README with model description
|
|
102
|
+
|
|
103
|
+
Example structure:
|
|
104
|
+
```python
|
|
105
|
+
from texgisa_survival.models.base import BaseModel
|
|
106
|
+
|
|
107
|
+
class YourModel(BaseModel):
|
|
108
|
+
"""
|
|
109
|
+
Your model description.
|
|
110
|
+
|
|
111
|
+
Parameters
|
|
112
|
+
----------
|
|
113
|
+
input_dim : int
|
|
114
|
+
Number of input features
|
|
115
|
+
**kwargs
|
|
116
|
+
Additional parameters
|
|
117
|
+
|
|
118
|
+
Examples
|
|
119
|
+
--------
|
|
120
|
+
>>> model = YourModel(input_dim=10)
|
|
121
|
+
>>> model.fit(X_train, y_train, e_train)
|
|
122
|
+
>>> risk_scores = model.predict_risk(X_test)
|
|
123
|
+
"""
|
|
124
|
+
|
|
125
|
+
def __init__(self, input_dim, **kwargs):
|
|
126
|
+
super().__init__(input_dim, **kwargs)
|
|
127
|
+
# Your initialization code
|
|
128
|
+
|
|
129
|
+
def fit(self, X, y, e, **kwargs):
|
|
130
|
+
"""Fit the model"""
|
|
131
|
+
# Your training code
|
|
132
|
+
|
|
133
|
+
def predict_risk(self, X):
|
|
134
|
+
"""Predict risk scores"""
|
|
135
|
+
# Your prediction code
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Style Guidelines
|
|
139
|
+
|
|
140
|
+
### Python Style Guide
|
|
141
|
+
|
|
142
|
+
We use [PEP 8](https://www.python.org/dev/peps/pep-0008/) with the following specifications:
|
|
143
|
+
|
|
144
|
+
- Line length: 100 characters
|
|
145
|
+
- Use type hints where possible
|
|
146
|
+
- Document all public functions with NumPy-style docstrings
|
|
147
|
+
|
|
148
|
+
We enforce style using:
|
|
149
|
+
- `black` for code formatting
|
|
150
|
+
- `flake8` for linting
|
|
151
|
+
- `mypy` for type checking
|
|
152
|
+
- `isort` for import sorting
|
|
153
|
+
|
|
154
|
+
Run these tools before committing:
|
|
155
|
+
```bash
|
|
156
|
+
black src/
|
|
157
|
+
flake8 src/
|
|
158
|
+
mypy src/texgisa_survival
|
|
159
|
+
isort src/
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Or use pre-commit:
|
|
163
|
+
```bash
|
|
164
|
+
pre-commit run --all-files
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Documentation Style
|
|
168
|
+
|
|
169
|
+
- Use NumPy style for docstrings
|
|
170
|
+
- Include type hints in function signatures
|
|
171
|
+
- Provide examples in docstrings where helpful
|
|
172
|
+
- Keep documentation up-to-date with code changes
|
|
173
|
+
|
|
174
|
+
Example docstring:
|
|
175
|
+
```python
|
|
176
|
+
def concordance_index(y_true, y_pred, e):
|
|
177
|
+
"""
|
|
178
|
+
Calculate the concordance index for survival analysis.
|
|
179
|
+
|
|
180
|
+
Parameters
|
|
181
|
+
----------
|
|
182
|
+
y_true : array-like, shape = [n_samples]
|
|
183
|
+
True survival times
|
|
184
|
+
y_pred : array-like, shape = [n_samples]
|
|
185
|
+
Predicted risk scores
|
|
186
|
+
e : array-like, shape = [n_samples]
|
|
187
|
+
Event indicators (1 if event occurred, 0 if censored)
|
|
188
|
+
|
|
189
|
+
Returns
|
|
190
|
+
-------
|
|
191
|
+
float
|
|
192
|
+
Concordance index between 0 and 1
|
|
193
|
+
|
|
194
|
+
Examples
|
|
195
|
+
--------
|
|
196
|
+
>>> c_index = concordance_index([1, 2, 3], [0.5, 0.3, 0.1], [1, 1, 0])
|
|
197
|
+
>>> print(f"C-index: {c_index:.3f}")
|
|
198
|
+
C-index: 1.000
|
|
199
|
+
"""
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## Testing
|
|
203
|
+
|
|
204
|
+
### Writing Tests
|
|
205
|
+
|
|
206
|
+
- Write tests for any new functionality
|
|
207
|
+
- Ensure all tests pass before submitting PR
|
|
208
|
+
- Aim for high test coverage (>90%)
|
|
209
|
+
- Use pytest for testing
|
|
210
|
+
|
|
211
|
+
Run tests:
|
|
212
|
+
```bash
|
|
213
|
+
pytest tests/
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
Run tests with coverage:
|
|
217
|
+
```bash
|
|
218
|
+
pytest tests/ --cov=texgisa_survival --cov-report=html
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Test Structure
|
|
222
|
+
|
|
223
|
+
```python
|
|
224
|
+
import pytest
|
|
225
|
+
from texgisa_survival.your_module import your_function
|
|
226
|
+
|
|
227
|
+
class TestYourFunction:
|
|
228
|
+
def test_normal_case(self):
|
|
229
|
+
"""Test normal operation"""
|
|
230
|
+
result = your_function(input_data)
|
|
231
|
+
assert result == expected_output
|
|
232
|
+
|
|
233
|
+
def test_edge_case(self):
|
|
234
|
+
"""Test edge cases"""
|
|
235
|
+
with pytest.raises(ValueError):
|
|
236
|
+
your_function(invalid_input)
|
|
237
|
+
|
|
238
|
+
@pytest.mark.parametrize("input,expected", [
|
|
239
|
+
(1, 2),
|
|
240
|
+
(2, 4),
|
|
241
|
+
(3, 6),
|
|
242
|
+
])
|
|
243
|
+
def test_multiple_cases(self, input, expected):
|
|
244
|
+
"""Test multiple cases"""
|
|
245
|
+
assert your_function(input) == expected
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
## Commit Messages
|
|
249
|
+
|
|
250
|
+
We follow the [Conventional Commits](https://www.conventionalcommits.org/) specification:
|
|
251
|
+
|
|
252
|
+
- `feat:` A new feature
|
|
253
|
+
- `fix:` A bug fix
|
|
254
|
+
- `docs:` Documentation only changes
|
|
255
|
+
- `style:` Changes that don't affect code meaning
|
|
256
|
+
- `refactor:` Code change that neither fixes a bug nor adds a feature
|
|
257
|
+
- `perf:` Code change that improves performance
|
|
258
|
+
- `test:` Adding missing tests or correcting existing tests
|
|
259
|
+
- `build:` Changes that affect the build system or dependencies
|
|
260
|
+
- `ci:` Changes to CI configuration files and scripts
|
|
261
|
+
- `chore:` Other changes that don't modify src or test files
|
|
262
|
+
|
|
263
|
+
Examples:
|
|
264
|
+
```
|
|
265
|
+
feat: add TexGISa model for interpretable survival analysis
|
|
266
|
+
fix: correct concordance index calculation for tied events
|
|
267
|
+
docs: update installation instructions for Windows users
|
|
268
|
+
test: add integration tests for model comparison
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## Pull Request Process
|
|
272
|
+
|
|
273
|
+
1. **Ensure your code follows the style guidelines**
|
|
274
|
+
2. **Update documentation** for any changed functionality
|
|
275
|
+
3. **Add tests** for new functionality
|
|
276
|
+
4. **Ensure all tests pass** locally
|
|
277
|
+
5. **Update the CHANGELOG.md** with your changes
|
|
278
|
+
6. **Create a pull request** with a clear title and description
|
|
279
|
+
|
|
280
|
+
### PR Checklist
|
|
281
|
+
|
|
282
|
+
- [ ] Code follows project style guidelines
|
|
283
|
+
- [ ] Tests added/updated and passing
|
|
284
|
+
- [ ] Documentation updated
|
|
285
|
+
- [ ] CHANGELOG.md updated
|
|
286
|
+
- [ ] Commit messages follow conventions
|
|
287
|
+
- [ ] PR has descriptive title and description
|
|
288
|
+
- [ ] All CI checks passing
|
|
289
|
+
|
|
290
|
+
### PR Review Process
|
|
291
|
+
|
|
292
|
+
1. At least one maintainer review required
|
|
293
|
+
2. All CI checks must pass
|
|
294
|
+
3. No merge conflicts
|
|
295
|
+
4. Discussions resolved
|
|
296
|
+
|
|
297
|
+
## Release Process
|
|
298
|
+
|
|
299
|
+
Releases are managed by maintainers following semantic versioning:
|
|
300
|
+
|
|
301
|
+
1. Update version in `pyproject.toml`
|
|
302
|
+
2. Update CHANGELOG.md
|
|
303
|
+
3. Create git tag
|
|
304
|
+
4. GitHub Actions automatically publishes to PyPI
|
|
305
|
+
|
|
306
|
+
## Community
|
|
307
|
+
|
|
308
|
+
### Getting Help
|
|
309
|
+
|
|
310
|
+
- GitHub Issues for bug reports and feature requests
|
|
311
|
+
- GitHub Discussions for general questions
|
|
312
|
+
- Email: the public issue tracker at https://github.com/Kunjoe7/texgisa-survival/issues
|
|
313
|
+
|
|
314
|
+
### Acknowledgments
|
|
315
|
+
|
|
316
|
+
Contributors will be acknowledged in:
|
|
317
|
+
- The AUTHORS file
|
|
318
|
+
- Release notes
|
|
319
|
+
- Project documentation
|
|
320
|
+
|
|
321
|
+
## Questions?
|
|
322
|
+
|
|
323
|
+
Feel free to contact the maintainers if you have any questions about contributing. We're here to help and look forward to your contributions!
|
|
324
|
+
|
|
325
|
+
## License
|
|
326
|
+
|
|
327
|
+
By contributing, you agree that your contributions will be licensed under the MIT License.
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
# Software changes since the method publication
|
|
2
|
+
|
|
3
|
+
Relative to the method described by Qin et al. (ICDM2025), the review candidate adds a fitted multi-output recipe interface, explicit risk/curve/point semantics, eight experiment-backed own-model recipes, two calibration choices, train-only split/epoch/config provenance, and isolated optional baseline/author-CLI invocation. The legacy estimator and TEXGI functions remain available. Benchmark replay and table reconstruction are supplied separately. These are source-verified software capabilities, not a claim that all changes were independently isolated in accuracy ablations.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 DHAI Lab
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
include README.md LICENSE CHANGELOG.md CITATION.cff
|
|
2
|
+
include SCIENTIFIC_NOTES.md API_REFERENCE.md BACKENDS.md CONTRIBUTING.md EXTENSIONS_SINCE_ICDM.md
|
|
3
|
+
recursive-include .github/workflows *.yml
|
|
4
|
+
recursive-include tests *.py
|
|
5
|
+
recursive-include examples *.py
|
|
6
|
+
recursive-include benchmarks *.py *.json *.md
|
|
7
|
+
recursive-include skills *.md
|
|
8
|
+
global-exclude *.py[cod] __pycache__ *.pt *.pkl
|