ndscape 0.1.1__tar.gz → 0.1.2__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.
- ndscape-0.1.2/MANIFEST.in +1 -0
- {ndscape-0.1.1 → ndscape-0.1.2}/PKG-INFO +136 -132
- {ndscape-0.1.1 → ndscape-0.1.2}/README.md +76 -69
- {ndscape-0.1.1 → ndscape-0.1.2}/ndscape/api.py +1 -1
- {ndscape-0.1.1 → ndscape-0.1.2}/ndscape.egg-info/PKG-INFO +136 -132
- ndscape-0.1.2/ndscape.egg-info/SOURCES.txt +13 -0
- {ndscape-0.1.1 → ndscape-0.1.2}/pyproject.toml +6 -2
- {ndscape-0.1.1 → ndscape-0.1.2}/setup.cfg +4 -4
- ndscape-0.1.1/ndscape.egg-info/SOURCES.txt +0 -23
- ndscape-0.1.1/tests/test_artifact.py +0 -160
- ndscape-0.1.1/tests/test_dt_simulation.py +0 -236
- ndscape-0.1.1/tests/test_embed_tree.py +0 -2
- ndscape-0.1.1/tests/test_nd_generators.py +0 -135
- ndscape-0.1.1/tests/test_nd_predict.py +0 -128
- ndscape-0.1.1/tests/test_order_tree.py +0 -100
- ndscape-0.1.1/tests/test_real_datasets.py +0 -195
- ndscape-0.1.1/tests/test_sample_trees.py +0 -114
- ndscape-0.1.1/tests/test_split_analyzer.py +0 -93
- ndscape-0.1.1/tests/test_tree_enumeration.py +0 -101
- ndscape-0.1.1/tests/test_tree_utilities.py +0 -2
- {ndscape-0.1.1 → ndscape-0.1.2}/LICENSE +0 -0
- {ndscape-0.1.1 → ndscape-0.1.2}/ndscape/README.md +0 -0
- {ndscape-0.1.1 → ndscape-0.1.2}/ndscape/__init__.py +0 -0
- {ndscape-0.1.1 → ndscape-0.1.2}/ndscape/plot.py +0 -0
- {ndscape-0.1.1 → ndscape-0.1.2}/ndscape.egg-info/dependency_links.txt +0 -0
- {ndscape-0.1.1 → ndscape-0.1.2}/ndscape.egg-info/requires.txt +0 -0
- {ndscape-0.1.1 → ndscape-0.1.2}/ndscape.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
prune tests
|
|
@@ -1,132 +1,136 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: ndscape
|
|
3
|
-
Version: 0.1.
|
|
4
|
-
Summary: Fit, score, and embed nested-dichotomy (ND) trees for multi-class classification.
|
|
5
|
-
Author: Maxwell Dix-Matthews
|
|
6
|
-
License-Expression: MIT
|
|
7
|
-
Project-URL:
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
Requires-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
Requires-Dist:
|
|
20
|
-
Requires-Dist:
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
Requires-Dist:
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
score
|
|
33
|
-
|
|
34
|
-
tree
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
`
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
`
|
|
132
|
-
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ndscape
|
|
3
|
+
Version: 0.1.2
|
|
4
|
+
Summary: Fit, score, and embed nested-dichotomy (ND) trees for multi-class classification.
|
|
5
|
+
Author: Maxwell Dix-Matthews
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/res-lucid/ndscape
|
|
8
|
+
Project-URL: Repository, https://github.com/res-lucid/ndscape
|
|
9
|
+
Project-URL: Issues, https://github.com/res-lucid/ndscape/issues
|
|
10
|
+
Project-URL: Interactive maps, https://res-lucid.github.io/ndscape-plots/
|
|
11
|
+
Project-URL: Data archive, https://doi.org/10.5281/zenodo.20456943
|
|
12
|
+
Keywords: nested-dichotomy,multi-class,classification,scikit-learn
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: Topic :: Scientific/Engineering
|
|
16
|
+
Requires-Python: >=3.9
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
License-File: LICENSE
|
|
19
|
+
Requires-Dist: numpy>=1.24
|
|
20
|
+
Requires-Dist: scikit-learn>=1.3
|
|
21
|
+
Requires-Dist: joblib>=1.2
|
|
22
|
+
Provides-Extra: spatial
|
|
23
|
+
Requires-Dist: esda>=2.6; extra == "spatial"
|
|
24
|
+
Requires-Dist: libpysal>=4.10; extra == "spatial"
|
|
25
|
+
Provides-Extra: plot
|
|
26
|
+
Requires-Dist: matplotlib>=3.5; extra == "plot"
|
|
27
|
+
Requires-Dist: bokeh>=3.0; extra == "plot"
|
|
28
|
+
Dynamic: license-file
|
|
29
|
+
|
|
30
|
+
# ndscape
|
|
31
|
+
|
|
32
|
+
Fit, score, and embed nested-dichotomy (ND) trees for multi-class classification.
|
|
33
|
+
|
|
34
|
+
A nested dichotomy reduces a C-class problem to a tree of binary splits
|
|
35
|
+
(e.g. {0,1,2} vs {3,4}, then {0} vs {1,2}, ...). ndscape lets you fit one,
|
|
36
|
+
score it, or place a whole population of candidate trees in a 2-D
|
|
37
|
+
"tree-space" to see how a property (accuracy, variance, ...) varies across
|
|
38
|
+
tree structures.
|
|
39
|
+
|
|
40
|
+
## Install
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
pip install ndscape
|
|
44
|
+
pip install ndscape[spatial] # adds Moran's I support (esda, libpysal)
|
|
45
|
+
pip install ndscape[plot] # adds plotting (matplotlib, bokeh)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Quickstart
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
from sklearn.datasets import load_iris
|
|
52
|
+
from sklearn.model_selection import train_test_split
|
|
53
|
+
import ndscape as nds
|
|
54
|
+
|
|
55
|
+
X, y = load_iris(return_X_y=True)
|
|
56
|
+
classes = sorted(set(y))
|
|
57
|
+
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)
|
|
58
|
+
|
|
59
|
+
nd = nds.fit(X_train, y_train, classes=classes, base="lr")
|
|
60
|
+
nd.predict(X_test)
|
|
61
|
+
nd.score(X_test, y_test) # {"accuracy": ..., "logloss": ...}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
`classes` is the list of class labels in your `y` (`sorted(set(y))` works for
|
|
65
|
+
integer or string labels). `nds.fit` samples one ND tree automatically; pass
|
|
66
|
+
`tree=...` to use a specific one (see "A `tree` is..." below).
|
|
67
|
+
|
|
68
|
+
## Use cases
|
|
69
|
+
|
|
70
|
+
**You have a dataset and a binary classifier.**
|
|
71
|
+
|
|
72
|
+
`base` can be the string `"lr"` or `"decisiontree"`, or your own unfitted
|
|
73
|
+
scikit-learn estimator — a fresh clone of it is fit at every split.
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
from sklearn.svm import SVC
|
|
77
|
+
|
|
78
|
+
nd = nds.fit(X_train, y_train, classes=classes, base=SVC(probability=True, kernel="linear"))
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**You have a train/test split and want a score.**
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
nd = nds.ND(tree, classes).fit(X_train, y_train, base="lr")
|
|
85
|
+
nd.score(X_test, y_test) # {"accuracy": ..., "logloss": ...}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**You already trained the per-split models yourself.**
|
|
89
|
+
|
|
90
|
+
```python
|
|
91
|
+
# models in the same order as tree, or a {(left, right): model} dict — either works
|
|
92
|
+
nd = nds.ND.from_trained(tree, classes, models=[fitted_model_1, fitted_model_2, ...])
|
|
93
|
+
nd.predict_proba(X_test)
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**You already scored a set of trees and want to see where they sit in tree-space.**
|
|
97
|
+
|
|
98
|
+
```python
|
|
99
|
+
trees, coords = nds.embed_trees(classes)
|
|
100
|
+
nds.spatial_autocorrelation(my_scores, coords) # {"I": ..., "p_sim": ...}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**You just want the whole picture: fit, score, and embed every candidate tree.**
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
rows = nds.analyze(X_train, y_train, classes, X_test=X_test, y_test=y_test, base="lr")
|
|
107
|
+
# [{"tree": ..., "accuracy": ..., "logloss": ..., "coord": array([...])}, ...]
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
**You want a picture of that tree-space.**
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
nds.plot(rows, metric="accuracy", path="tree_space.png") # static PNG/PDF
|
|
114
|
+
nds.plot_interactive(rows, metric="accuracy", path="tree_space.html") # pan/zoom/hover
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Both color points by `metric` and mark the best tree with a black x. Needs
|
|
118
|
+
`ndscape[plot]`.
|
|
119
|
+
|
|
120
|
+
**The embedding is slow to recompute and you want to reuse it.**
|
|
121
|
+
|
|
122
|
+
```python
|
|
123
|
+
rows = nds.analyze(X_train, y_train, classes, cache="embedding.joblib")
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
The MDS step in `embed_trees`/`analyze` is the slow part. Pass `cache=` a
|
|
127
|
+
`.joblib` path: the first call computes the embedding and saves it there,
|
|
128
|
+
later calls with the same path just load it.
|
|
129
|
+
|
|
130
|
+
A `tree` is a list of `(left, right)` tuples of class labels, e.g.
|
|
131
|
+
`[((0, 1), (2, 3)), ((0,), (1,)), ((2,), (3,))]`. Use `nds.all_trees(classes)`
|
|
132
|
+
(exhaustive, for small C) or `nds.sample_trees(classes, N)` (for larger C)
|
|
133
|
+
to generate candidates.
|
|
134
|
+
|
|
135
|
+
`base` accepts `"lr"`, `"decisiontree"`, or any unfitted scikit-learn
|
|
136
|
+
estimator with `fit`/`predict_proba`.
|
|
@@ -1,46 +1,74 @@
|
|
|
1
|
-
# Nested
|
|
1
|
+
# ndscape: Nested Dichotomy Tree-Space Embedding
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://pypi.org/project/ndscape/)
|
|
4
|
+
[](https://doi.org/10.5281/zenodo.20456943)
|
|
5
|
+
[](LICENSE)
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
A classification model assigns an observation to one of several classes, and when there are more than two, the task becomes a multiclass problem. A nested dichotomy (ND) gives that multiclass problem a visible structure: it arranges the classes in a binary tree and fits a classifier at each split, so the final prediction is built from a sequence of simpler binary decisions.
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
Any binary classifier can be used at the nodes. With probabilistic classifiers, the probability of each class is the product of the branch probabilities along its path from root to leaf. And because the tree records which classes are grouped together, where they separate, and in what order, you can inspect the fitted model and compare its structure with what you already know about the problem.
|
|
10
|
+
|
|
11
|
+
That structure also matters for prediction. There are (2M−3)!! possible NDs for M classes, each defining a different decomposition of the same classification task, and changing the tree can produce very different fitted models even when the data and binary classifier stay the same. This gives NDs a large, interpretable model space where changes in predictive behaviour can be related directly to changes in structure.
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
`ndscape` embeds ND tree structures using depth-weighted structural tokens and metric MDS, so structurally similar trees sit close together. It can be used as a Python package, and this repository also contains the code needed to reproduce the paper outputs.
|
|
12
14
|
|
|
13
|
-
|
|
15
|
+
Interactive maps from the paper: [res-lucid.github.io/ndscape-plots](https://res-lucid.github.io/ndscape-plots/)
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
For package use:
|
|
14
20
|
|
|
15
21
|
```bash
|
|
16
|
-
|
|
22
|
+
pip install ndscape
|
|
17
23
|
```
|
|
18
24
|
|
|
19
|
-
To
|
|
20
|
-
|
|
25
|
+
To reproduce the paper outputs, clone the repository and install the pinned requirements:
|
|
21
26
|
```bash
|
|
22
|
-
|
|
27
|
+
python -m venv venv
|
|
28
|
+
source venv/bin/activate # Windows: venv\Scripts\activate
|
|
29
|
+
pip install -r requirements.txt
|
|
23
30
|
```
|
|
24
31
|
|
|
25
|
-
|
|
32
|
+
Versions of `numpy`, `scipy`, and `scikit-learn` are pinned in `requirements.txt`. The MDS coordinates in `cache_nd/` were built with those exact versions, so changing numpy, scipy, or scikit-learn can produce slightly different coordinates.
|
|
33
|
+
|
|
34
|
+
## How to use this repository
|
|
35
|
+
|
|
36
|
+
| Goal | Command |
|
|
37
|
+
|------|---------|
|
|
38
|
+
| Use `ndscape` as a package | `pip install ndscape` |
|
|
39
|
+
| Test the repository install | `pytest tests/` |
|
|
40
|
+
| Recreate paper figures and tables from archived outputs | `python scripts/download_zenodo.py` then `python reproduce.py --paper` |
|
|
41
|
+
| Run the full reproduction pipeline | `python reproduce.py` |
|
|
42
|
+
| Run only selected steps | `python reproduce.py --steps artifacts` |
|
|
43
|
+
| Score a new dataset | `python run_datasets.py --datasets my_dataset` |
|
|
44
|
+
|
|
45
|
+
## Reproduce paper outputs from archived results
|
|
26
46
|
|
|
27
|
-
Download the Zenodo deposit
|
|
47
|
+
Download the Zenodo deposit, then regenerate the paper figures and tables without re-running the simulations:
|
|
28
48
|
|
|
29
49
|
```bash
|
|
30
50
|
python scripts/download_zenodo.py
|
|
31
51
|
python reproduce.py --paper
|
|
32
52
|
```
|
|
33
53
|
|
|
34
|
-
|
|
54
|
+
<details>
|
|
55
|
+
<summary>Scripts run by <code>python reproduce.py --paper</code></summary>
|
|
35
56
|
|
|
36
|
-
1. `scripts/make_dataset_plots.py --cache zenodo --out paper_outputs/figures`
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
57
|
+
1. `scripts/make_dataset_plots.py --cache zenodo --out paper_outputs/figures`
|
|
58
|
+
- PDF and interactive HTML embedding maps for all six real datasets.
|
|
59
|
+
2. `scripts/make_simulation_plots.py --out paper_outputs/figures`
|
|
60
|
+
- Simulation bias, variance, and depth maps.
|
|
61
|
+
3. `scripts/make_ablation_summaries.py`
|
|
62
|
+
- Moran spatial analysis for the tokeniser, BoW, and RF ablations.
|
|
63
|
+
4. `scripts/make_paper_tables.py --all --out paper_outputs/tables`
|
|
64
|
+
- LaTeX tables.
|
|
40
65
|
|
|
41
|
-
Output
|
|
66
|
+
Output is saved to `paper_outputs/figures/` and `paper_outputs/tables/`.
|
|
67
|
+
</details>
|
|
42
68
|
|
|
43
|
-
## Full reproduction
|
|
69
|
+
## Full reproduction pipeline
|
|
70
|
+
|
|
71
|
+
This rebuilds the derived outputs locally, using the archived data and configuration files downloaded into `zenodo/`.
|
|
44
72
|
|
|
45
73
|
```bash
|
|
46
74
|
python reproduce.py
|
|
@@ -67,18 +95,24 @@ python reproduce.py --steps plots
|
|
|
67
95
|
|
|
68
96
|
**Note on step 2:** `run_datasets.py` scores every ND tree on each real dataset and writes xlsx results. These are also available pre-built in `zenodo/tree_metrics/` and are used automatically by `make_dataset_plots.py` and `make_dataset_tables.py` when the xlsx files are absent.
|
|
69
97
|
|
|
70
|
-
##
|
|
98
|
+
## Using your own data
|
|
71
99
|
|
|
72
|
-
`
|
|
100
|
+
Drop a CSV in `zenodo/data/` with a `y` column (integer or string class labels) and any number of numeric feature columns. A `split` column (`"train"` / `"test"`) is used if present, otherwise a stratified 70/30 split is applied.
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
python run_datasets.py --datasets my_dataset
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Output goes to `real-data-bias-analysis/my_dataset/v_my_dataset_lr_cluster_tables.xlsx`.
|
|
73
107
|
|
|
74
108
|
## Tests
|
|
75
109
|
|
|
76
110
|
```bash
|
|
77
111
|
pytest tests/ # unit + snapshot tests (fast)
|
|
78
|
-
pytest tests/ -m integration # integration tests (slow
|
|
112
|
+
pytest tests/ -m integration # integration tests (slow and requires pre-built C=6,7 artifacts)
|
|
79
113
|
```
|
|
80
114
|
|
|
81
|
-
The `tests/fixtures/` directory holds MD5 hashes
|
|
115
|
+
The `tests/fixtures/` directory holds golden-master fixtures: MD5 hashes for the larger artifacts, and full tree lists and generator outputs for the smaller ones.
|
|
82
116
|
|
|
83
117
|
## Datasets
|
|
84
118
|
|
|
@@ -112,38 +146,18 @@ Or place CSV files (with a `y` column for the class label) in `zenodo/data/`:
|
|
|
112
146
|
|
|
113
147
|
## Key files
|
|
114
148
|
|
|
115
|
-
```
|
|
149
|
+
```text
|
|
150
|
+
reproduce.py Main reproduction entry point
|
|
116
151
|
core.py Tree enumeration, embedding, models, artifact building
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
BestOfK.py Best-of-K wrapper (K=10)
|
|
127
|
-
ACND.py, NDC.py, RPND.py, CBND.py Four further construction heuristics
|
|
128
|
-
|
|
129
|
-
scripts/make_artifacts.py Build MDS embeddings from configs/artifacts.yml
|
|
130
|
-
scripts/verify_artifacts.py Check built artifacts against configs/artifacts.yml
|
|
131
|
-
scripts/make_dataset_plots.py Embedding PDF + HTML maps per real dataset
|
|
132
|
-
scripts/make_simulation_plots.py Simulation bias/variance/depth PDF maps
|
|
133
|
-
scripts/moran_simulation_analysis.py Spatial statistics on simulation results
|
|
134
|
-
scripts/make_dataset_tables.py LaTeX real-data tables (spatial stats + heuristic placement)
|
|
135
|
-
scripts/make_simulation_tables.py LaTeX simulation tables
|
|
136
|
-
scripts/make_ablation_summaries.py Moran analysis for tokeniser/BoW/RF ablations
|
|
137
|
-
scripts/make_ablation_tables.py LaTeX ablation tables
|
|
138
|
-
scripts/make_paper_tables.py Orchestrates all tables → paper_outputs/tables/
|
|
139
|
-
scripts/download_zenodo.py Download pre-built data from Zenodo
|
|
140
|
-
scripts/csv_to_configs.py Convert zenodo/simulation_configs.csv to JSON
|
|
141
|
-
|
|
142
|
-
configs/artifacts.yml Manifest of all artifacts to build
|
|
143
|
-
cache_nd/ Cached .joblib artifacts (auto-created by step 1)
|
|
144
|
-
zenodo/ Pre-built deposit data (see Zenodo section below)
|
|
145
|
-
real-data-bias-analysis/ Scoring results (auto-created by step 2)
|
|
146
|
-
bias-analysis/raw_simulation_results/ Simulation bootstrap CSVs (auto-created by step 3)
|
|
152
|
+
run_datasets.py Score all trees on real datasets
|
|
153
|
+
run_simulations.py Bias-variance simulation
|
|
154
|
+
nd/ Nested dichotomy implementations
|
|
155
|
+
scripts/ Figure, table, artifact, download, and analysis scripts
|
|
156
|
+
configs/artifacts.yml Artifact specifications
|
|
157
|
+
cache_nd/ Cached embedding artifacts
|
|
158
|
+
zenodo/ Downloaded Zenodo archive
|
|
159
|
+
real-data-bias-analysis/ Real-data scoring outputs
|
|
160
|
+
bias-analysis/raw_simulation_results/ Simulation bootstrap outputs
|
|
147
161
|
```
|
|
148
162
|
|
|
149
163
|
## Zenodo
|
|
@@ -202,22 +216,11 @@ To convert the LR CSV to JSON:
|
|
|
202
216
|
python scripts/csv_to_configs.py --output simulation_configs.json
|
|
203
217
|
```
|
|
204
218
|
|
|
205
|
-
`zenodo/simulation_configs_dt.csv` is committed as a static artifact
|
|
206
|
-
the original Postgres simulation DB and is not regenerated as part of this pipeline.
|
|
207
|
-
|
|
208
|
-
## Using your own data
|
|
209
|
-
|
|
210
|
-
Drop a CSV in `zenodo/data/` with a `y` column (integer or string class labels) and any number of numeric feature columns. A `split` column (`"train"` / `"test"`) is used if present; otherwise a stratified 70/30 split is applied.
|
|
211
|
-
|
|
212
|
-
```bash
|
|
213
|
-
python run_datasets.py --datasets my_dataset
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
Output goes to `real-data-bias-analysis/my_dataset/v_my_dataset_lr_cluster_tables.xlsx`.
|
|
219
|
+
`zenodo/simulation_configs_dt.csv` is committed as a static artifact and is not regenerated as part of this pipeline.
|
|
217
220
|
|
|
218
221
|
## Artifacts (cache_nd/)
|
|
219
222
|
|
|
220
|
-
The `cache_nd/` directory holds `.joblib` artifacts for C=4 through C=19.
|
|
223
|
+
The `cache_nd/` directory holds `.joblib` artifacts for C=4 through C=19. It is not tracked in git — the artifacts are downloaded from Zenodo into `zenodo/` (tracked with Git LFS, see `.gitattributes`) or rebuilt locally:
|
|
221
224
|
|
|
222
225
|
```bash
|
|
223
226
|
python scripts/download_zenodo.py --what artifacts
|
|
@@ -231,3 +234,7 @@ python scripts/make_artifacts.py --all
|
|
|
231
234
|
|
|
232
235
|
Artifact specs (class count, tree count, seed) are declared in `configs/artifacts.yml`.
|
|
233
236
|
Use `scripts/verify_artifacts.py` to check a built artifact against its spec.
|
|
237
|
+
|
|
238
|
+
## Citation
|
|
239
|
+
|
|
240
|
+
Metadata is in [`CITATION.cff`](CITATION.cff); GitHub renders it under "Cite this repository". The archived data and artifacts have their own DOI, [10.5281/zenodo.20456943](https://doi.org/10.5281/zenodo.20456943).
|
|
@@ -35,7 +35,7 @@ def _get_model(base):
|
|
|
35
35
|
if isinstance(base, str):
|
|
36
36
|
if base == "lr":
|
|
37
37
|
return LogisticRegression(
|
|
38
|
-
|
|
38
|
+
solver="newton-cholesky", C=0.1, max_iter=2000
|
|
39
39
|
)
|
|
40
40
|
if base in ("decisiontree", "dt"):
|
|
41
41
|
return DecisionTreeClassifier(
|