guide-rs 0.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.
Files changed (55) hide show
  1. guide_rs-0.2.0/.gitignore +15 -0
  2. guide_rs-0.2.0/CHANGELOG.md +82 -0
  3. guide_rs-0.2.0/Cargo.lock +409 -0
  4. guide_rs-0.2.0/Cargo.toml +26 -0
  5. guide_rs-0.2.0/LICENSE +21 -0
  6. guide_rs-0.2.0/PKG-INFO +91 -0
  7. guide_rs-0.2.0/README.md +87 -0
  8. guide_rs-0.2.0/examples/iris.json +8 -0
  9. guide_rs-0.2.0/examples/linear-limits.json +14 -0
  10. guide_rs-0.2.0/examples/mtcars-quantile.json +18 -0
  11. guide_rs-0.2.0/examples/mtcars.json +9 -0
  12. guide_rs-0.2.0/guide/__init__.py +25 -0
  13. guide_rs-0.2.0/guide/_estimators.py +1196 -0
  14. guide_rs-0.2.0/guide/_plot.py +154 -0
  15. guide_rs-0.2.0/guide/py.typed +0 -0
  16. guide_rs-0.2.0/pyproject.toml +57 -0
  17. guide_rs-0.2.0/python/Cargo.lock +494 -0
  18. guide_rs-0.2.0/python/Cargo.toml +27 -0
  19. guide_rs-0.2.0/python/README.md +73 -0
  20. guide_rs-0.2.0/python/docs/api.rst +28 -0
  21. guide_rs-0.2.0/python/docs/conf.py +37 -0
  22. guide_rs-0.2.0/python/docs/examples.md +13 -0
  23. guide_rs-0.2.0/python/docs/getting-started.md +66 -0
  24. guide_rs-0.2.0/python/docs/index.md +15 -0
  25. guide_rs-0.2.0/python/examples/classification.ipynb +468 -0
  26. guide_rs-0.2.0/python/examples/discriminant.ipynb +342 -0
  27. guide_rs-0.2.0/python/examples/ensembles.ipynb +676 -0
  28. guide_rs-0.2.0/python/examples/execute.py +16 -0
  29. guide_rs-0.2.0/python/examples/regression.ipynb +515 -0
  30. guide_rs-0.2.0/python/examples/selection_bias.ipynb +645 -0
  31. guide_rs-0.2.0/python/src/lib.rs +339 -0
  32. guide_rs-0.2.0/python/tests/test_boosting.py +55 -0
  33. guide_rs-0.2.0/python/tests/test_discriminant.py +89 -0
  34. guide_rs-0.2.0/python/tests/test_estimators.py +264 -0
  35. guide_rs-0.2.0/python/tests/test_options.py +150 -0
  36. guide_rs-0.2.0/python/tests/test_plot.py +57 -0
  37. guide_rs-0.2.0/python/tests/test_roles_forests_importance.py +149 -0
  38. guide_rs-0.2.0/python/tests/test_sklearn_checks.py +34 -0
  39. guide_rs-0.2.0/python/uv.lock +4475 -0
  40. guide_rs-0.2.0/src/boosting.rs +636 -0
  41. guide_rs-0.2.0/src/config.rs +355 -0
  42. guide_rs-0.2.0/src/data.rs +554 -0
  43. guide_rs-0.2.0/src/discriminant.rs +1233 -0
  44. guide_rs-0.2.0/src/ensemble.rs +249 -0
  45. guide_rs-0.2.0/src/export.rs +229 -0
  46. guide_rs-0.2.0/src/importance.rs +333 -0
  47. guide_rs-0.2.0/src/lapack.rs +1287 -0
  48. guide_rs-0.2.0/src/lib.rs +60 -0
  49. guide_rs-0.2.0/src/main.rs +375 -0
  50. guide_rs-0.2.0/src/node.rs +1269 -0
  51. guide_rs-0.2.0/src/pruning.rs +533 -0
  52. guide_rs-0.2.0/src/quantile.rs +267 -0
  53. guide_rs-0.2.0/src/selection.rs +744 -0
  54. guide_rs-0.2.0/src/stats.rs +747 -0
  55. guide_rs-0.2.0/src/tree.rs +2297 -0
@@ -0,0 +1,15 @@
1
+ /target/
2
+ /.reference/
3
+ /assets/
4
+ __pycache__/
5
+ *.py[cod]
6
+ .pytest_cache/
7
+ .DS_Store
8
+ /python/target/
9
+ /python/.venv/
10
+ *.so
11
+ *.pyd
12
+ /.vscode/
13
+ /python/docs/_build/
14
+ /python/docs/generated/
15
+ /python/docs/examples/
@@ -0,0 +1,82 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and the project
5
+ adheres to [Semantic Versioning](https://semver.org/).
6
+
7
+ ## [Unreleased]
8
+
9
+ ## [0.2.0] - 2026-11-02
10
+
11
+ ### Added
12
+
13
+ - `lda` node model for classification: GUIDE's linear discriminant splits and leaves on numeric and categorical features
14
+ - `node_model="lda"` in the Python `GuideClassifier`
15
+ - Importance scores for LDA classification configurations, computed with constant-node trees
16
+ - `lda_splits` node model for classification: GUIDE's linear discriminant splits with constant leaves
17
+ - Missing-value flags with polynomial, linear and stepwise node models
18
+ - `alpha` for polynomial node models: insignificant highest powers are dropped at 0.05 by default, as GUIDE does
19
+
20
+ ### Fixed
21
+
22
+ - Classification leaves with tied class counts predict the class GUIDE predicts
23
+ - Trees without interaction tests stop insignificant nodes at depth 4 and below, as GUIDE does
24
+ - Cuts below the root may leave exactly the minimum node size in the right child, as in GUIDE
25
+ - Interaction and linear-split tests are skipped on data with about 317 or more split variables, as in GUIDE
26
+ - Simple polynomial trees choose cuts and leaves as GUIDE does
27
+ - Regression selection tests group categorical and few-valued numeric variables as GUIDE does, pooling values seen once
28
+ - Numeric variables with a single observed value are not tested for selection, as in GUIDE
29
+ - Tree fitting ranks selection tests on GUIDE's 1-df chi-square scale, whose Wilson-Hilferty tails below 2e-6 can rank a test with a larger p-value first
30
+ - Selection quartile cuts stop at the first repeated cut, and a one-row group joins the largest group, as in GUIDE
31
+ - Importance trees group categorical and few-valued variables, cut interaction pairs and stop small or nearly pure nodes as GUIDE does
32
+ - Classification selection tests bin numeric variables at quantiles and group few-valued ones by value, as GUIDE does
33
+ - Interaction tests cut numeric variables at the node median, as GUIDE does
34
+
35
+ ## [0.1.0] - 2026-10-27
36
+
37
+ ### Added
38
+
39
+ - Experimental GUIDE classification and regression trees targeting GUIDE 46.3, with a CLI and Rust API
40
+ - `--threads` CLI option and `n_jobs` estimator parameter set the threads used for parallel fits
41
+ - Python package (`import guide`) with scikit-learn tree and forest estimators, feature roles and importance scores
42
+ - Python estimators accept periodic features, missing-value flags, logistic and dual-quantile losses, stepwise leaves, prediction truncation and validation pruning
43
+ - `guide.plot_tree` draws fitted trees with matplotlib
44
+ - Example notebooks comparing GUIDE with scikit-learn decision trees on its bundled datasets
45
+ - Example notebook comparing GUIDE bagging, forests and boosting with scikit-learn's ensembles
46
+ - Sphinx documentation for the Python package: user guide, API reference and the example notebooks
47
+ - Python wheels for Linux, macOS and Windows built and tested in CI, published to PyPI on version tags
48
+ - `pruning_loss` prunes classification trees and measures out-of-bag loss by log loss or Brier score instead of misclassification cost
49
+ - Experimental gradient boosting with GUIDE variable selection (`fit_boosting`, a `boosting` CLI section, `GuideBoostingRegressor` and `GuideBoostingClassifier`) for squared-error, Poisson and logistic regression and classification, with early stopping
50
+ - Multiclass trees split categorical predictors with more than 11 levels instead of rejecting them
51
+ - Missing-value flag variables (GUIDE M variables) for constant node models
52
+ - `exposures_from_csv` reads prediction exposures with line-numbered errors
53
+ - Per-subcommand `--help` output
54
+
55
+ ### Changed
56
+
57
+ - Classification trees and forests that look ahead on interactions fit 3 to 7 times faster, with unchanged models
58
+ - Ensemble trees, cross-validation folds and importance permutations are fitted in parallel, with results independent of the thread count
59
+ - Pruning large trees is faster: the pruning sequence no longer copies the tree per stage, and held-out rows are routed once
60
+ - Variable selection and split search are faster and run in parallel at large nodes, with unchanged models
61
+ - Linear, polynomial and quantile-regression leaves fit faster, with unchanged models
62
+ - Squared-error regression trees with constant leaves fit about 2.5 times faster, with unchanged models
63
+ - Categorical splits put the side with fewer categories on the left, matching GUIDE; unseen categories may reach a different leaf than before
64
+ - Classification trees merge sibling leaves that predict the same class, matching GUIDE
65
+ - `min_gain = 0` accepts zero-gain splits on the selected variable, matching GUIDE
66
+ - With `min_gain = 0`, classification keeps splits that raise prior- or cost-adjusted impurity, matching GUIDE
67
+ - Linear quantile leaves need `p + 4` rows for a linear fit, matching GUIDE; smaller leaves are constant
68
+ - Poisson and quantile trees search GUIDE's fixed grid of cutpoints, Poisson children need a positive count, and quantile leaves average at exact ties, matching GUIDE
69
+ - Constant-leaf trees use the two-level lookahead for interaction pairs at every depth, with parent cuts on GUIDE's fixed grid, matching GUIDE more often
70
+ - Multiple-linear least-squares trees with numeric regressors use GUIDE's separate row minimums for split search and leaves, and keep the best split whatever its gain
71
+ - Poisson trees select split variables from Anscombe residual groups and quantile trees place zero residuals as GUIDE does; constant-response Poisson nodes are not split
72
+ - CSV parse errors report the line number and column name
73
+ - File I/O errors name the file that could not be read or written
74
+
75
+ ### Removed
76
+
77
+ - R prediction-function export (`export --format r` and `FittedModel::to_r`)
78
+
79
+ ### Fixed
80
+
81
+ - Blank lines in CSV input no longer cause a field-count error
82
+ - Bagged ensembles reject cross-validation pruning on bootstrap samples instead of under-pruning
@@ -0,0 +1,409 @@
1
+ # This file is automatically @generated by Cargo.
2
+ # It is not intended for manual editing.
3
+ version = 4
4
+
5
+ [[package]]
6
+ name = "anstream"
7
+ version = "1.0.0"
8
+ source = "registry+https://github.com/rust-lang/crates.io-index"
9
+ checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d"
10
+ dependencies = [
11
+ "anstyle",
12
+ "anstyle-parse",
13
+ "anstyle-query",
14
+ "anstyle-wincon",
15
+ "colorchoice",
16
+ "is_terminal_polyfill",
17
+ "utf8parse",
18
+ ]
19
+
20
+ [[package]]
21
+ name = "anstyle"
22
+ version = "1.0.14"
23
+ source = "registry+https://github.com/rust-lang/crates.io-index"
24
+ checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000"
25
+
26
+ [[package]]
27
+ name = "anstyle-parse"
28
+ version = "1.0.0"
29
+ source = "registry+https://github.com/rust-lang/crates.io-index"
30
+ checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e"
31
+ dependencies = [
32
+ "utf8parse",
33
+ ]
34
+
35
+ [[package]]
36
+ name = "anstyle-query"
37
+ version = "1.1.5"
38
+ source = "registry+https://github.com/rust-lang/crates.io-index"
39
+ checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
40
+ dependencies = [
41
+ "windows-sys",
42
+ ]
43
+
44
+ [[package]]
45
+ name = "anstyle-wincon"
46
+ version = "3.0.11"
47
+ source = "registry+https://github.com/rust-lang/crates.io-index"
48
+ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
49
+ dependencies = [
50
+ "anstyle",
51
+ "once_cell_polyfill",
52
+ "windows-sys",
53
+ ]
54
+
55
+ [[package]]
56
+ name = "anyhow"
57
+ version = "1.0.104"
58
+ source = "registry+https://github.com/rust-lang/crates.io-index"
59
+ checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470"
60
+
61
+ [[package]]
62
+ name = "cfg-if"
63
+ version = "1.0.5"
64
+ source = "registry+https://github.com/rust-lang/crates.io-index"
65
+ checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600"
66
+
67
+ [[package]]
68
+ name = "clap"
69
+ version = "4.6.7"
70
+ source = "registry+https://github.com/rust-lang/crates.io-index"
71
+ checksum = "aa8876b300ab35ba921adea3dfd70157a46249b33f95c9084ae5709785478946"
72
+ dependencies = [
73
+ "clap_builder",
74
+ "clap_derive",
75
+ ]
76
+
77
+ [[package]]
78
+ name = "clap_builder"
79
+ version = "4.6.7"
80
+ source = "registry+https://github.com/rust-lang/crates.io-index"
81
+ checksum = "ec0797fb7aeb1406c84efac526901f7ec3ead2124f946b494e72879d4b54704d"
82
+ dependencies = [
83
+ "anstream",
84
+ "anstyle",
85
+ "clap_lex",
86
+ "strsim",
87
+ ]
88
+
89
+ [[package]]
90
+ name = "clap_derive"
91
+ version = "4.6.7"
92
+ source = "registry+https://github.com/rust-lang/crates.io-index"
93
+ checksum = "f9c751b79415d4e559e3d1fcf128e09e720eb673a06d26cf6f392d37d75b66e0"
94
+ dependencies = [
95
+ "heck",
96
+ "proc-macro2",
97
+ "quote",
98
+ "syn 3.0.3",
99
+ ]
100
+
101
+ [[package]]
102
+ name = "clap_lex"
103
+ version = "1.1.1"
104
+ source = "registry+https://github.com/rust-lang/crates.io-index"
105
+ checksum = "1c133bc6a41be0d194c306b5506d15e6feeea7b1d6604bd3f8310dfb2ca96486"
106
+
107
+ [[package]]
108
+ name = "colorchoice"
109
+ version = "1.0.5"
110
+ source = "registry+https://github.com/rust-lang/crates.io-index"
111
+ checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570"
112
+
113
+ [[package]]
114
+ name = "crossbeam-deque"
115
+ version = "0.8.8"
116
+ source = "registry+https://github.com/rust-lang/crates.io-index"
117
+ checksum = "622f3fc73690be383c7214310406f28a90e6edeadc3cea882f9d71e495b9711a"
118
+ dependencies = [
119
+ "crossbeam-epoch",
120
+ "crossbeam-utils",
121
+ ]
122
+
123
+ [[package]]
124
+ name = "crossbeam-epoch"
125
+ version = "0.9.21"
126
+ source = "registry+https://github.com/rust-lang/crates.io-index"
127
+ checksum = "dc74980687109a3b14c72fd458107bf0baa1da1a1a805e178d15501ba9b86d9d"
128
+ dependencies = [
129
+ "crossbeam-utils",
130
+ ]
131
+
132
+ [[package]]
133
+ name = "crossbeam-utils"
134
+ version = "0.8.23"
135
+ source = "registry+https://github.com/rust-lang/crates.io-index"
136
+ checksum = "a31eee39dddec8330830986fcd7625edb5a24ec90ea038215273bbc3adb08ac6"
137
+
138
+ [[package]]
139
+ name = "either"
140
+ version = "1.19.0"
141
+ source = "registry+https://github.com/rust-lang/crates.io-index"
142
+ checksum = "0e9c71c2167ca323c882b99918929403426e2373ea17242ff5653e0d5e1058be"
143
+
144
+ [[package]]
145
+ name = "getrandom"
146
+ version = "0.2.17"
147
+ source = "registry+https://github.com/rust-lang/crates.io-index"
148
+ checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
149
+ dependencies = [
150
+ "cfg-if",
151
+ "libc",
152
+ "wasi",
153
+ ]
154
+
155
+ [[package]]
156
+ name = "guide-rs"
157
+ version = "0.2.0"
158
+ dependencies = [
159
+ "anyhow",
160
+ "clap",
161
+ "rand",
162
+ "rand_chacha",
163
+ "rayon",
164
+ "serde",
165
+ "serde_json",
166
+ ]
167
+
168
+ [[package]]
169
+ name = "heck"
170
+ version = "0.5.0"
171
+ source = "registry+https://github.com/rust-lang/crates.io-index"
172
+ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
173
+
174
+ [[package]]
175
+ name = "is_terminal_polyfill"
176
+ version = "1.70.2"
177
+ source = "registry+https://github.com/rust-lang/crates.io-index"
178
+ checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
179
+
180
+ [[package]]
181
+ name = "itoa"
182
+ version = "1.0.18"
183
+ source = "registry+https://github.com/rust-lang/crates.io-index"
184
+ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
185
+
186
+ [[package]]
187
+ name = "libc"
188
+ version = "0.2.190"
189
+ source = "registry+https://github.com/rust-lang/crates.io-index"
190
+ checksum = "ce5d3ddc6d3fa000eb1536d85e147bfe31aacaba692ed6a876f95cb7c855be78"
191
+
192
+ [[package]]
193
+ name = "memchr"
194
+ version = "2.8.3"
195
+ source = "registry+https://github.com/rust-lang/crates.io-index"
196
+ checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
197
+
198
+ [[package]]
199
+ name = "once_cell_polyfill"
200
+ version = "1.70.2"
201
+ source = "registry+https://github.com/rust-lang/crates.io-index"
202
+ checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
203
+
204
+ [[package]]
205
+ name = "ppv-lite86"
206
+ version = "0.2.21"
207
+ source = "registry+https://github.com/rust-lang/crates.io-index"
208
+ checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
209
+ dependencies = [
210
+ "zerocopy",
211
+ ]
212
+
213
+ [[package]]
214
+ name = "proc-macro2"
215
+ version = "1.0.107"
216
+ source = "registry+https://github.com/rust-lang/crates.io-index"
217
+ checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
218
+ dependencies = [
219
+ "unicode-ident",
220
+ ]
221
+
222
+ [[package]]
223
+ name = "quote"
224
+ version = "1.0.47"
225
+ source = "registry+https://github.com/rust-lang/crates.io-index"
226
+ checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
227
+ dependencies = [
228
+ "proc-macro2",
229
+ ]
230
+
231
+ [[package]]
232
+ name = "rand"
233
+ version = "0.8.7"
234
+ source = "registry+https://github.com/rust-lang/crates.io-index"
235
+ checksum = "22f6172bdec972074665ed81ed53b71da00bfc44b65a753cfde883ec4c702a1a"
236
+ dependencies = [
237
+ "libc",
238
+ "rand_chacha",
239
+ "rand_core",
240
+ ]
241
+
242
+ [[package]]
243
+ name = "rand_chacha"
244
+ version = "0.3.1"
245
+ source = "registry+https://github.com/rust-lang/crates.io-index"
246
+ checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
247
+ dependencies = [
248
+ "ppv-lite86",
249
+ "rand_core",
250
+ ]
251
+
252
+ [[package]]
253
+ name = "rand_core"
254
+ version = "0.6.4"
255
+ source = "registry+https://github.com/rust-lang/crates.io-index"
256
+ checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
257
+ dependencies = [
258
+ "getrandom",
259
+ ]
260
+
261
+ [[package]]
262
+ name = "rayon"
263
+ version = "1.12.0"
264
+ source = "registry+https://github.com/rust-lang/crates.io-index"
265
+ checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d"
266
+ dependencies = [
267
+ "either",
268
+ "rayon-core",
269
+ ]
270
+
271
+ [[package]]
272
+ name = "rayon-core"
273
+ version = "1.13.0"
274
+ source = "registry+https://github.com/rust-lang/crates.io-index"
275
+ checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91"
276
+ dependencies = [
277
+ "crossbeam-deque",
278
+ "crossbeam-utils",
279
+ ]
280
+
281
+ [[package]]
282
+ name = "serde"
283
+ version = "1.0.229"
284
+ source = "registry+https://github.com/rust-lang/crates.io-index"
285
+ checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba"
286
+ dependencies = [
287
+ "serde_core",
288
+ "serde_derive",
289
+ ]
290
+
291
+ [[package]]
292
+ name = "serde_core"
293
+ version = "1.0.229"
294
+ source = "registry+https://github.com/rust-lang/crates.io-index"
295
+ checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48"
296
+ dependencies = [
297
+ "serde_derive",
298
+ ]
299
+
300
+ [[package]]
301
+ name = "serde_derive"
302
+ version = "1.0.229"
303
+ source = "registry+https://github.com/rust-lang/crates.io-index"
304
+ checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348"
305
+ dependencies = [
306
+ "proc-macro2",
307
+ "quote",
308
+ "syn 3.0.3",
309
+ ]
310
+
311
+ [[package]]
312
+ name = "serde_json"
313
+ version = "1.0.151"
314
+ source = "registry+https://github.com/rust-lang/crates.io-index"
315
+ checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14"
316
+ dependencies = [
317
+ "itoa",
318
+ "memchr",
319
+ "serde",
320
+ "serde_core",
321
+ "zmij",
322
+ ]
323
+
324
+ [[package]]
325
+ name = "strsim"
326
+ version = "0.11.1"
327
+ source = "registry+https://github.com/rust-lang/crates.io-index"
328
+ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
329
+
330
+ [[package]]
331
+ name = "syn"
332
+ version = "2.0.119"
333
+ source = "registry+https://github.com/rust-lang/crates.io-index"
334
+ checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297"
335
+ dependencies = [
336
+ "proc-macro2",
337
+ "quote",
338
+ "unicode-ident",
339
+ ]
340
+
341
+ [[package]]
342
+ name = "syn"
343
+ version = "3.0.3"
344
+ source = "registry+https://github.com/rust-lang/crates.io-index"
345
+ checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3"
346
+ dependencies = [
347
+ "proc-macro2",
348
+ "quote",
349
+ "unicode-ident",
350
+ ]
351
+
352
+ [[package]]
353
+ name = "unicode-ident"
354
+ version = "1.0.24"
355
+ source = "registry+https://github.com/rust-lang/crates.io-index"
356
+ checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
357
+
358
+ [[package]]
359
+ name = "utf8parse"
360
+ version = "0.2.2"
361
+ source = "registry+https://github.com/rust-lang/crates.io-index"
362
+ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
363
+
364
+ [[package]]
365
+ name = "wasi"
366
+ version = "0.11.1+wasi-snapshot-preview1"
367
+ source = "registry+https://github.com/rust-lang/crates.io-index"
368
+ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
369
+
370
+ [[package]]
371
+ name = "windows-link"
372
+ version = "0.2.1"
373
+ source = "registry+https://github.com/rust-lang/crates.io-index"
374
+ checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
375
+
376
+ [[package]]
377
+ name = "windows-sys"
378
+ version = "0.61.2"
379
+ source = "registry+https://github.com/rust-lang/crates.io-index"
380
+ checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
381
+ dependencies = [
382
+ "windows-link",
383
+ ]
384
+
385
+ [[package]]
386
+ name = "zerocopy"
387
+ version = "0.8.56"
388
+ source = "registry+https://github.com/rust-lang/crates.io-index"
389
+ checksum = "556764e583adb45a9f8d413c2a147fa7e8d821e48e12b14fd560b607998b75eb"
390
+ dependencies = [
391
+ "zerocopy-derive",
392
+ ]
393
+
394
+ [[package]]
395
+ name = "zerocopy-derive"
396
+ version = "0.8.56"
397
+ source = "registry+https://github.com/rust-lang/crates.io-index"
398
+ checksum = "f2ab42fc20575779bd240faa45f94a74256f755c0fa9e89f0ede20d91d0cdfc1"
399
+ dependencies = [
400
+ "proc-macro2",
401
+ "quote",
402
+ "syn 2.0.119",
403
+ ]
404
+
405
+ [[package]]
406
+ name = "zmij"
407
+ version = "1.0.23"
408
+ source = "registry+https://github.com/rust-lang/crates.io-index"
409
+ checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b"
@@ -0,0 +1,26 @@
1
+ [package]
2
+ name = "guide-rs"
3
+ version = "0.2.0"
4
+ edition = "2024"
5
+ description = "Native Rust research implementation of GUIDE-style statistical trees"
6
+ authors = ["Brandon Greenwell <greenwell.brandon@gmail.com>"]
7
+ license = "MIT"
8
+ repository = "https://github.com/bgreenwell/guide-rs"
9
+ homepage = "https://github.com/bgreenwell/guide-rs"
10
+ readme = "README.md"
11
+ keywords = ["decision-tree", "statistics", "regression", "classification", "guide"]
12
+ categories = ["science", "algorithms", "command-line-utilities"]
13
+ exclude = ["tests/", "tools/", "docs/", "python/", ".github/", "AGENTS.md", "CLAUDE.md"]
14
+
15
+ [dependencies]
16
+ serde = { version = "1", features = ["derive"] }
17
+ serde_json = { version = "1", features = ["float_roundtrip"] }
18
+ rand = "0.8"
19
+ rand_chacha = "0.3"
20
+ clap = { version = "4", features = ["derive"] }
21
+ anyhow = "1"
22
+ rayon = "1"
23
+
24
+ [profile.release]
25
+ lto = true
26
+ codegen-units = 1
guide_rs-0.2.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Brandon Greenwell
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,91 @@
1
+ Metadata-Version: 2.4
2
+ Name: guide-rs
3
+ Version: 0.2.0
4
+ Classifier: Programming Language :: Python :: 3
5
+ Classifier: Programming Language :: Rust
6
+ Classifier: Topic :: Scientific/Engineering
7
+ Requires-Dist: numpy>=1.24
8
+ Requires-Dist: scikit-learn>=1.6
9
+ Requires-Dist: matplotlib>=3.7 ; extra == 'plot'
10
+ Provides-Extra: plot
11
+ Summary: scikit-learn estimators for GUIDE-style classification and regression trees
12
+ Author-email: Brandon Greenwell <greenwell.brandon@gmail.com>
13
+ License-Expression: MIT
14
+ Requires-Python: >=3.10
15
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
16
+ Project-URL: Repository, https://github.com/bgreenwell/guide-rs
17
+
18
+ # guide-rs for Python
19
+
20
+ scikit-learn estimators for GUIDE-style classification and regression trees, backed by the [guide-rs](https://github.com/bgreenwell/guide-rs) Rust core.
21
+
22
+ The bindings are experimental; see the core's [coverage and remaining work](https://github.com/bgreenwell/guide-rs/blob/main/docs/coverage.md) for what is validated against GUIDE 46.3.
23
+
24
+ ## Features
25
+
26
+ - `GuideRegressor`, `GuideClassifier`, `GuideForestRegressor` and `GuideForestClassifier`, compatible with scikit-learn's estimator API, pipelines, cloning and model selection
27
+ - Unbiased split-variable selection with interaction tests, as in GUIDE
28
+ - Native categorical features and missing values (NaN or None); no one-hot encoding or imputation
29
+ - Constant, linear, polynomial, linear discriminant (`node_model="lda"`) and (experimental) stepwise leaves; squared-error, quantile, dual-quantile, Poisson and logistic losses; class priors and costs
30
+ - Per-feature roles (`feature_roles`): split only, fit only, both or excluded; periodic features (`periodic_features`) and missing-value flags (`missing_flags`)
31
+ - Pruning by cross-validation, cost complexity, leaf count or a validation sample (`fit(..., validation_data=...)`)
32
+ - Bagged ensembles and forests with out-of-bag loss, and bias-adjusted GUIDE importance scores (`guide.importance`)
33
+ - Experimental gradient boosting (`GuideBoostingRegressor`, `GuideBoostingClassifier`) whose split variables come from GUIDE-style chi-square tests on the gradients, so split counts and gain are not biased toward variables with many values
34
+ - Tree drawings with matplotlib (`guide.plot_tree`), plus text, Graphviz DOT and JSON output, the JSON matching models saved by the guide-rs CLI
35
+
36
+ ## Installation
37
+
38
+ From a clone (requires a Rust toolchain):
39
+
40
+ ```sh
41
+ cd python
42
+ uv sync
43
+ ```
44
+
45
+ The distribution is named `guide-rs`; the package imports as `guide`. `plot_tree` needs matplotlib (the `plot` extra).
46
+
47
+ ## Quick start
48
+
49
+ ```python
50
+ from sklearn.datasets import load_iris
51
+ from guide import GuideClassifier
52
+
53
+ X, y = load_iris(return_X_y=True, as_frame=True)
54
+ model = GuideClassifier().fit(X, y)
55
+ print(model.predict_proba(X.head()))
56
+
57
+ from guide import plot_tree
58
+ plot_tree(model)
59
+ ```
60
+
61
+ DataFrame columns with object, string, categorical or boolean dtypes are treated as categorical; for arrays, name them with `categorical_features`.
62
+
63
+ Importance scores refit shallow trees with the estimator's configuration:
64
+
65
+ ```python
66
+ from guide import importance
67
+
68
+ report = importance(GuideClassifier(), X, y)
69
+ for score in report["scores"]:
70
+ print(score["feature"], score["adjusted_score"], score["group"])
71
+ ```
72
+
73
+ Cross-validation pruning, forests and importance permutations run in parallel, with the same results for any thread count. `n_jobs` sets the threads; unlike most scikit-learn estimators, its default (None) uses all cores. Lower it when `GridSearchCV` also runs jobs in parallel.
74
+
75
+ ## Documentation
76
+
77
+ - Example notebooks comparing GUIDE with scikit-learn on its bundled datasets: [classification trees](examples/classification.ipynb), [regression trees](examples/regression.ipynb), [ensembles](examples/ensembles.ipynb) (bagging, forests and boosting), and [selection bias and importance](examples/selection_bias.ipynb)
78
+ - [User guide and API reference](https://bgreenwell.github.io/guide-rs/), built from `docs/` and published on each push to `main`
79
+ - [Usage and configuration of the core](https://github.com/bgreenwell/guide-rs/blob/main/docs/usage.md)
80
+
81
+ ## Development
82
+
83
+ ```sh
84
+ uv sync # build the extension in editable mode
85
+ uv run ruff check . && uv run pytest # quality gate
86
+ uv run --group examples python examples/execute.py # re-run the notebooks
87
+ uv run --group docs sphinx-build -W -b html docs docs/_build/html # build the docs
88
+ ```
89
+
90
+ Branch and commit conventions are in the repository's [AGENTS.md](https://github.com/bgreenwell/guide-rs/blob/main/AGENTS.md).
91
+