neural-trees 0.1.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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Cagri Temel
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,350 @@
1
+ Metadata-Version: 2.4
2
+ Name: neural-trees
3
+ Version: 0.1.0
4
+ Summary: Implementations of algorithms from Prof. Dr. Ethem Alpaydın's research papers and ML textbook (MIT Press).
5
+ Home-page: https://github.com/cgrtml/neural-trees
6
+ Author: Cagri Temel
7
+ Author-email: cagritemel34@gmail.com
8
+ Keywords: machine learning,soft decision trees,mixture of experts,statistical tests,alpaydin,sklearn
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Science/Research
11
+ Classifier: Intended Audience :: Education
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.8
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
19
+ Requires-Python: >=3.8
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: numpy>=1.21
23
+ Requires-Dist: scipy>=1.7
24
+ Requires-Dist: scikit-learn>=1.0
25
+ Requires-Dist: torch>=1.10
26
+ Provides-Extra: dev
27
+ Requires-Dist: pytest>=7.0; extra == "dev"
28
+ Requires-Dist: pytest-cov; extra == "dev"
29
+ Requires-Dist: matplotlib>=3.4; extra == "dev"
30
+ Requires-Dist: jupyter; extra == "dev"
31
+ Requires-Dist: plotly; extra == "dev"
32
+ Dynamic: author
33
+ Dynamic: author-email
34
+ Dynamic: classifier
35
+ Dynamic: description
36
+ Dynamic: description-content-type
37
+ Dynamic: home-page
38
+ Dynamic: keywords
39
+ Dynamic: license-file
40
+ Dynamic: provides-extra
41
+ Dynamic: requires-dist
42
+ Dynamic: requires-python
43
+ Dynamic: summary
44
+
45
+ # neural-trees
46
+
47
+ > PyTorch + sklearn implementations of the tree and mixture-of-experts algorithms
48
+ > from Alpaydın's research papers — the ones that never got a proper open-source home.
49
+
50
+ [![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
51
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
52
+ [![Tests](https://github.com/cgrtml/neural-trees/actions/workflows/tests.yml/badge.svg)](https://github.com/cgrtml/neural-trees/actions)
53
+ [![sklearn compatible](https://img.shields.io/badge/sklearn-compatible-orange)](https://scikit-learn.org)
54
+
55
+ ---
56
+
57
+ ## Why?
58
+
59
+ I was reading through Alpaydın's *Introduction to Machine Learning* and his papers
60
+ and kept hitting the same wall: interesting algorithms, no usable Python code anywhere.
61
+ The Soft Decision Tree paper (ICPR 2012) alone has hundreds of citations but the implementations
62
+ floating around are incomplete, undocumented, or years out of date.
63
+
64
+ So I wrote them myself — clean, tested, and fully compatible with the sklearn API.
65
+
66
+ Covered so far:
67
+
68
+ | Algorithm | Paper | Status |
69
+ |-----------|-------|--------|
70
+ | **Soft Decision Trees** | İrsoy, Yıldız, Alpaydın (ICPR 2012) | ✅ PyTorch + sklearn API |
71
+ | **Omnivariate Decision Trees** | Yıldız & Alpaydın (IEEE TNN 2001) | ✅ |
72
+ | **Hierarchical Mixture of Experts + Dropout** | İrsoy & Alpaydın (Neurocomputing 2021) | ✅ PyTorch |
73
+ | **GAL: Grow and Learn Networks** | Alpaydın (IJPRAI 1994) | ✅ |
74
+ | **Combined 5×2cv F Test** | Alpaydın (Neural Computation 1999) | ✅ Gold-standard classifier comparison |
75
+ | **McNemar's Test** | — | ✅ |
76
+ | **Naive Bayes (Gaussian/Bernoulli/Multinomial)** | Textbook Ch. 3 | ✅ |
77
+ | **Distance-Weighted KNN + CNN** | Alpaydın (AIR 1997) | ✅ |
78
+
79
+ ---
80
+
81
+ ## Installation
82
+
83
+ ```bash
84
+ pip install neural-trees
85
+ ```
86
+
87
+ Or install from source:
88
+
89
+ ```bash
90
+ git clone https://github.com/cgrtml/neural-trees.git
91
+ cd neural-trees
92
+ pip install -e ".[dev]"
93
+ ```
94
+
95
+ ---
96
+
97
+ ## Quick Start
98
+
99
+ ### Soft Decision Trees
100
+
101
+ The flagship algorithm. Unlike hard decision trees, every sample reaches every leaf with some probability — making the tree **fully differentiable** and trainable end-to-end with backpropagation.
102
+
103
+ ```python
104
+ from neural_trees import SoftDecisionTree
105
+ from sklearn.datasets import load_iris
106
+ from sklearn.model_selection import train_test_split
107
+
108
+ X, y = load_iris(return_X_y=True)
109
+ X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)
110
+
111
+ sdt = SoftDecisionTree(depth=4, max_epochs=40, penalty_coef=1e-3)
112
+ sdt.fit(X_train, y_train)
113
+
114
+ print(f"Accuracy: {sdt.score(X_test, y_test):.4f}")
115
+
116
+ # Inspect what each leaf learned
117
+ leaf_distributions = sdt.get_leaf_distributions() # shape: (n_leaves, n_classes)
118
+
119
+ # Inspect the split direction at each internal node
120
+ split_weights = sdt.get_split_weights() # list of weight vectors
121
+ ```
122
+
123
+ **Key idea** (Irsoy, Yıldız, Alpaydın, 2012):
124
+
125
+ At each internal node *i*:
126
+
127
+ $$p_i(\mathbf{x}) = \sigma(\mathbf{w}_i^\top \mathbf{x} + b_i)$$
128
+
129
+ The probability of reaching leaf $\ell$ is the product of gate values along the path. Final prediction:
130
+
131
+ $$P(y \mid \mathbf{x}) = \sum_\ell \mu_\ell(\mathbf{x}) \cdot Q_\ell(y)$$
132
+
133
+ ---
134
+
135
+ ### Comparing Two Classifiers — The Gold Standard Test
136
+
137
+ Alpaydın's **Combined 5×2cv F Test** (Neural Computation, 1999) is the statistically correct way to compare two classifiers. It overcomes the inflated Type I error of the paired t-test.
138
+
139
+ ```python
140
+ from neural_trees.statistical_tests import combined_5x2cv_f_test
141
+ from sklearn.svm import SVC
142
+ from sklearn.tree import DecisionTreeClassifier
143
+ from sklearn.datasets import load_breast_cancer
144
+
145
+ X, y = load_breast_cancer(return_X_y=True)
146
+
147
+ result = combined_5x2cv_f_test(
148
+ clf_A=DecisionTreeClassifier(),
149
+ clf_B=SVC(kernel="rbf"),
150
+ X=X, y=y,
151
+ alpha=0.05
152
+ )
153
+ print(result)
154
+ ```
155
+
156
+ ```
157
+ StatisticalTestResult(
158
+ test = Alpaydın's Combined 5×2cv F Test
159
+ statistic = 12.4731
160
+ p-value = 0.0083
161
+ alpha = 0.05
162
+ decision = ✓ REJECT H0
163
+ note = Classifiers significantly differ
164
+ )
165
+ ```
166
+
167
+ **Why not just use a t-test?**
168
+ The paired t-test reuses training data across folds — the differences are correlated, inflating the false positive rate. Alpaydın's F test accounts for this by estimating variance within each 2-fold split, giving a much better calibrated test.
169
+
170
+ ---
171
+
172
+ ### Hierarchical Mixture of Experts with Dropout
173
+
174
+ ```python
175
+ from neural_trees import HierarchicalMixtureOfExperts
176
+ from sklearn.datasets import load_digits
177
+
178
+ X, y = load_digits(return_X_y=True)
179
+
180
+ moe = HierarchicalMixtureOfExperts(
181
+ depth=2,
182
+ branching_factor=4, # 4^2 = 16 expert leaves
183
+ dropout_rate=0.3, # Dropout on gating networks (Irsoy & Alpaydın, 2021)
184
+ max_epochs=50,
185
+ verbose=True,
186
+ )
187
+ moe.fit(X, y)
188
+ print(f"Accuracy: {moe.score(X, y):.4f}")
189
+ ```
190
+
191
+ ---
192
+
193
+ ### GAL — Grow and Learn Networks
194
+
195
+ No need to specify architecture. The network grows when it can't learn and prunes itself when neurons become redundant.
196
+
197
+ ```python
198
+ from neural_trees.classical import GALNetwork
199
+ from sklearn.datasets import load_wine
200
+
201
+ X, y = load_wine(return_X_y=True)
202
+
203
+ gal = GALNetwork(
204
+ initial_hidden=2,
205
+ max_hidden=40,
206
+ grow_threshold=0.15,
207
+ prune_threshold=1e-4,
208
+ max_epochs=100,
209
+ verbose=True,
210
+ )
211
+ gal.fit(X, y)
212
+ print(f"Final hidden units: {gal.n_hidden_final_}")
213
+ print(f"Accuracy: {gal.score(X, y):.4f}")
214
+ ```
215
+
216
+ ---
217
+
218
+ ### Omnivariate Decision Trees
219
+
220
+ At each node, automatically selects the best split type (univariate, linear LDA, or nonlinear MLP) using cross-validation.
221
+
222
+ ```python
223
+ from neural_trees import OmnivariateDecisionTree
224
+ from sklearn.datasets import load_wine
225
+
226
+ X, y = load_wine(return_X_y=True)
227
+
228
+ odt = OmnivariateDecisionTree(max_depth=4, cv_folds=3)
229
+ odt.fit(X, y)
230
+
231
+ # See how many nodes used each split type
232
+ print(odt.get_split_type_distribution())
233
+ # {'univariate': 3, 'linear': 4, 'nonlinear': 1}
234
+ ```
235
+
236
+ ---
237
+
238
+ ## All sklearn-compatible
239
+
240
+ Every model follows the `fit` / `predict` / `predict_proba` / `score` interface:
241
+
242
+ ```python
243
+ from sklearn.pipeline import Pipeline
244
+ from sklearn.preprocessing import StandardScaler
245
+
246
+ pipe = Pipeline([
247
+ ("scaler", StandardScaler()),
248
+ ("sdt", SoftDecisionTree(depth=4, max_epochs=30)),
249
+ ])
250
+ pipe.fit(X_train, y_train)
251
+ pipe.score(X_test, y_test)
252
+ ```
253
+
254
+ ```python
255
+ from sklearn.model_selection import GridSearchCV
256
+
257
+ param_grid = {"sdt__depth": [3, 4, 5], "sdt__penalty_coef": [1e-4, 1e-3, 1e-2]}
258
+ gs = GridSearchCV(pipe, param_grid, cv=5)
259
+ gs.fit(X_train, y_train)
260
+ print(gs.best_params_)
261
+ ```
262
+
263
+ ---
264
+
265
+ ## Notebooks
266
+
267
+ | Notebook | Description |
268
+ |----------|-------------|
269
+ | [`01_soft_decision_trees.ipynb`](notebooks/01_soft_decision_trees.ipynb) | Training, visualization, comparison with CART |
270
+ | [`02_classifier_comparison_tests.ipynb`](notebooks/02_classifier_comparison_tests.ipynb) | When to use which statistical test |
271
+ | [`03_hierarchical_moe.ipynb`](notebooks/03_hierarchical_moe.ipynb) | HMoE training and expert specialization |
272
+ | [`04_gal_network.ipynb`](notebooks/04_gal_network.ipynb) | Dynamic architecture growth/pruning |
273
+ | [`05_omnivariate_trees.ipynb`](notebooks/05_omnivariate_trees.ipynb) | Node-level split type analysis |
274
+
275
+ ---
276
+
277
+ ## About the Author
278
+
279
+ **Prof. Dr. Ethem Alpaydın** is one of the world's leading machine learning researchers.
280
+
281
+ - Professor Emeritus at Boğaziçi University (Istanbul), now at Özyeğin University
282
+ - Author of *Introduction to Machine Learning* (MIT Press, 4 editions, 2004–2020) — used in hundreds of universities globally
283
+ - Author of *Machine Learning: The New AI* (MIT Press, 2016)
284
+ - PhD from EPFL (1990); research stays at UC Berkeley, MIT, and IDIAP
285
+ - **34,000+ citations** on Google Scholar
286
+ - IEEE Senior Member; Pattern Recognition journal editorial board
287
+
288
+ His 1999 paper on the Combined 5×2cv F Test is the standard reference for classifier comparison. His Soft Decision Trees paper (2012) remains one of the most elegant proposals for differentiable tree models — predating the modern neural tree literature.
289
+
290
+ ---
291
+
292
+ ## Citation
293
+
294
+ If you use this library in academic work, please cite the original papers:
295
+
296
+ ```bibtex
297
+ @book{alpaydin2020introduction,
298
+ title = {Introduction to Machine Learning},
299
+ author = {Alpayd{\i}n, Ethem},
300
+ year = {2020},
301
+ edition = {4th},
302
+ publisher = {MIT Press}
303
+ }
304
+
305
+ @article{irsoy2021dropout,
306
+ title = {Dropout Regularization in Hierarchical Mixture of Experts},
307
+ author = {\.{I}rsoy, O{\u{g}}uzhan and Alpayd{\i}n, Ethem},
308
+ journal = {Neurocomputing},
309
+ volume = {419},
310
+ pages = {148--156},
311
+ year = {2021}
312
+ }
313
+
314
+ @inproceedings{irsoy2012soft,
315
+ title = {Soft Decision Trees},
316
+ author = {\.{I}rsoy, O{\u{g}}uzhan and Y{\i}ld{\i}z, Olcay Taner and Alpayd{\i}n, Ethem},
317
+ booktitle = {Proceedings of the 21st International Conference on Pattern Recognition (ICPR)},
318
+ year = {2012}
319
+ }
320
+
321
+ @article{alpaydin1999combined,
322
+ title = {Combined 5x2cv {F} Test for Comparing Supervised Classification Learning Algorithms},
323
+ author = {Alpayd{\i}n, Ethem},
324
+ journal = {Neural Computation},
325
+ volume = {11},
326
+ number = {8},
327
+ pages = {1885--1892},
328
+ year = {1999}
329
+ }
330
+ ```
331
+
332
+ ---
333
+
334
+ ## Roadmap
335
+
336
+ Things I'm planning to add:
337
+
338
+ - [ ] Multiple Kernel Learning (Gönen & Alpaydın, JMLR 2011)
339
+ - [ ] Localized Multiple Kernel Learning (ICML 2008)
340
+ - [ ] Convolutional Soft Decision Trees (ICANN 2018)
341
+ - [ ] Decision boundary visualization utilities
342
+ - [ ] Benchmark comparison on UCI datasets
343
+
344
+ If you find a bug or want to implement one of these, open an issue.
345
+
346
+ ---
347
+
348
+ ## License
349
+
350
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,306 @@
1
+ # neural-trees
2
+
3
+ > PyTorch + sklearn implementations of the tree and mixture-of-experts algorithms
4
+ > from Alpaydın's research papers — the ones that never got a proper open-source home.
5
+
6
+ [![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
8
+ [![Tests](https://github.com/cgrtml/neural-trees/actions/workflows/tests.yml/badge.svg)](https://github.com/cgrtml/neural-trees/actions)
9
+ [![sklearn compatible](https://img.shields.io/badge/sklearn-compatible-orange)](https://scikit-learn.org)
10
+
11
+ ---
12
+
13
+ ## Why?
14
+
15
+ I was reading through Alpaydın's *Introduction to Machine Learning* and his papers
16
+ and kept hitting the same wall: interesting algorithms, no usable Python code anywhere.
17
+ The Soft Decision Tree paper (ICPR 2012) alone has hundreds of citations but the implementations
18
+ floating around are incomplete, undocumented, or years out of date.
19
+
20
+ So I wrote them myself — clean, tested, and fully compatible with the sklearn API.
21
+
22
+ Covered so far:
23
+
24
+ | Algorithm | Paper | Status |
25
+ |-----------|-------|--------|
26
+ | **Soft Decision Trees** | İrsoy, Yıldız, Alpaydın (ICPR 2012) | ✅ PyTorch + sklearn API |
27
+ | **Omnivariate Decision Trees** | Yıldız & Alpaydın (IEEE TNN 2001) | ✅ |
28
+ | **Hierarchical Mixture of Experts + Dropout** | İrsoy & Alpaydın (Neurocomputing 2021) | ✅ PyTorch |
29
+ | **GAL: Grow and Learn Networks** | Alpaydın (IJPRAI 1994) | ✅ |
30
+ | **Combined 5×2cv F Test** | Alpaydın (Neural Computation 1999) | ✅ Gold-standard classifier comparison |
31
+ | **McNemar's Test** | — | ✅ |
32
+ | **Naive Bayes (Gaussian/Bernoulli/Multinomial)** | Textbook Ch. 3 | ✅ |
33
+ | **Distance-Weighted KNN + CNN** | Alpaydın (AIR 1997) | ✅ |
34
+
35
+ ---
36
+
37
+ ## Installation
38
+
39
+ ```bash
40
+ pip install neural-trees
41
+ ```
42
+
43
+ Or install from source:
44
+
45
+ ```bash
46
+ git clone https://github.com/cgrtml/neural-trees.git
47
+ cd neural-trees
48
+ pip install -e ".[dev]"
49
+ ```
50
+
51
+ ---
52
+
53
+ ## Quick Start
54
+
55
+ ### Soft Decision Trees
56
+
57
+ The flagship algorithm. Unlike hard decision trees, every sample reaches every leaf with some probability — making the tree **fully differentiable** and trainable end-to-end with backpropagation.
58
+
59
+ ```python
60
+ from neural_trees import SoftDecisionTree
61
+ from sklearn.datasets import load_iris
62
+ from sklearn.model_selection import train_test_split
63
+
64
+ X, y = load_iris(return_X_y=True)
65
+ X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)
66
+
67
+ sdt = SoftDecisionTree(depth=4, max_epochs=40, penalty_coef=1e-3)
68
+ sdt.fit(X_train, y_train)
69
+
70
+ print(f"Accuracy: {sdt.score(X_test, y_test):.4f}")
71
+
72
+ # Inspect what each leaf learned
73
+ leaf_distributions = sdt.get_leaf_distributions() # shape: (n_leaves, n_classes)
74
+
75
+ # Inspect the split direction at each internal node
76
+ split_weights = sdt.get_split_weights() # list of weight vectors
77
+ ```
78
+
79
+ **Key idea** (Irsoy, Yıldız, Alpaydın, 2012):
80
+
81
+ At each internal node *i*:
82
+
83
+ $$p_i(\mathbf{x}) = \sigma(\mathbf{w}_i^\top \mathbf{x} + b_i)$$
84
+
85
+ The probability of reaching leaf $\ell$ is the product of gate values along the path. Final prediction:
86
+
87
+ $$P(y \mid \mathbf{x}) = \sum_\ell \mu_\ell(\mathbf{x}) \cdot Q_\ell(y)$$
88
+
89
+ ---
90
+
91
+ ### Comparing Two Classifiers — The Gold Standard Test
92
+
93
+ Alpaydın's **Combined 5×2cv F Test** (Neural Computation, 1999) is the statistically correct way to compare two classifiers. It overcomes the inflated Type I error of the paired t-test.
94
+
95
+ ```python
96
+ from neural_trees.statistical_tests import combined_5x2cv_f_test
97
+ from sklearn.svm import SVC
98
+ from sklearn.tree import DecisionTreeClassifier
99
+ from sklearn.datasets import load_breast_cancer
100
+
101
+ X, y = load_breast_cancer(return_X_y=True)
102
+
103
+ result = combined_5x2cv_f_test(
104
+ clf_A=DecisionTreeClassifier(),
105
+ clf_B=SVC(kernel="rbf"),
106
+ X=X, y=y,
107
+ alpha=0.05
108
+ )
109
+ print(result)
110
+ ```
111
+
112
+ ```
113
+ StatisticalTestResult(
114
+ test = Alpaydın's Combined 5×2cv F Test
115
+ statistic = 12.4731
116
+ p-value = 0.0083
117
+ alpha = 0.05
118
+ decision = ✓ REJECT H0
119
+ note = Classifiers significantly differ
120
+ )
121
+ ```
122
+
123
+ **Why not just use a t-test?**
124
+ The paired t-test reuses training data across folds — the differences are correlated, inflating the false positive rate. Alpaydın's F test accounts for this by estimating variance within each 2-fold split, giving a much better calibrated test.
125
+
126
+ ---
127
+
128
+ ### Hierarchical Mixture of Experts with Dropout
129
+
130
+ ```python
131
+ from neural_trees import HierarchicalMixtureOfExperts
132
+ from sklearn.datasets import load_digits
133
+
134
+ X, y = load_digits(return_X_y=True)
135
+
136
+ moe = HierarchicalMixtureOfExperts(
137
+ depth=2,
138
+ branching_factor=4, # 4^2 = 16 expert leaves
139
+ dropout_rate=0.3, # Dropout on gating networks (Irsoy & Alpaydın, 2021)
140
+ max_epochs=50,
141
+ verbose=True,
142
+ )
143
+ moe.fit(X, y)
144
+ print(f"Accuracy: {moe.score(X, y):.4f}")
145
+ ```
146
+
147
+ ---
148
+
149
+ ### GAL — Grow and Learn Networks
150
+
151
+ No need to specify architecture. The network grows when it can't learn and prunes itself when neurons become redundant.
152
+
153
+ ```python
154
+ from neural_trees.classical import GALNetwork
155
+ from sklearn.datasets import load_wine
156
+
157
+ X, y = load_wine(return_X_y=True)
158
+
159
+ gal = GALNetwork(
160
+ initial_hidden=2,
161
+ max_hidden=40,
162
+ grow_threshold=0.15,
163
+ prune_threshold=1e-4,
164
+ max_epochs=100,
165
+ verbose=True,
166
+ )
167
+ gal.fit(X, y)
168
+ print(f"Final hidden units: {gal.n_hidden_final_}")
169
+ print(f"Accuracy: {gal.score(X, y):.4f}")
170
+ ```
171
+
172
+ ---
173
+
174
+ ### Omnivariate Decision Trees
175
+
176
+ At each node, automatically selects the best split type (univariate, linear LDA, or nonlinear MLP) using cross-validation.
177
+
178
+ ```python
179
+ from neural_trees import OmnivariateDecisionTree
180
+ from sklearn.datasets import load_wine
181
+
182
+ X, y = load_wine(return_X_y=True)
183
+
184
+ odt = OmnivariateDecisionTree(max_depth=4, cv_folds=3)
185
+ odt.fit(X, y)
186
+
187
+ # See how many nodes used each split type
188
+ print(odt.get_split_type_distribution())
189
+ # {'univariate': 3, 'linear': 4, 'nonlinear': 1}
190
+ ```
191
+
192
+ ---
193
+
194
+ ## All sklearn-compatible
195
+
196
+ Every model follows the `fit` / `predict` / `predict_proba` / `score` interface:
197
+
198
+ ```python
199
+ from sklearn.pipeline import Pipeline
200
+ from sklearn.preprocessing import StandardScaler
201
+
202
+ pipe = Pipeline([
203
+ ("scaler", StandardScaler()),
204
+ ("sdt", SoftDecisionTree(depth=4, max_epochs=30)),
205
+ ])
206
+ pipe.fit(X_train, y_train)
207
+ pipe.score(X_test, y_test)
208
+ ```
209
+
210
+ ```python
211
+ from sklearn.model_selection import GridSearchCV
212
+
213
+ param_grid = {"sdt__depth": [3, 4, 5], "sdt__penalty_coef": [1e-4, 1e-3, 1e-2]}
214
+ gs = GridSearchCV(pipe, param_grid, cv=5)
215
+ gs.fit(X_train, y_train)
216
+ print(gs.best_params_)
217
+ ```
218
+
219
+ ---
220
+
221
+ ## Notebooks
222
+
223
+ | Notebook | Description |
224
+ |----------|-------------|
225
+ | [`01_soft_decision_trees.ipynb`](notebooks/01_soft_decision_trees.ipynb) | Training, visualization, comparison with CART |
226
+ | [`02_classifier_comparison_tests.ipynb`](notebooks/02_classifier_comparison_tests.ipynb) | When to use which statistical test |
227
+ | [`03_hierarchical_moe.ipynb`](notebooks/03_hierarchical_moe.ipynb) | HMoE training and expert specialization |
228
+ | [`04_gal_network.ipynb`](notebooks/04_gal_network.ipynb) | Dynamic architecture growth/pruning |
229
+ | [`05_omnivariate_trees.ipynb`](notebooks/05_omnivariate_trees.ipynb) | Node-level split type analysis |
230
+
231
+ ---
232
+
233
+ ## About the Author
234
+
235
+ **Prof. Dr. Ethem Alpaydın** is one of the world's leading machine learning researchers.
236
+
237
+ - Professor Emeritus at Boğaziçi University (Istanbul), now at Özyeğin University
238
+ - Author of *Introduction to Machine Learning* (MIT Press, 4 editions, 2004–2020) — used in hundreds of universities globally
239
+ - Author of *Machine Learning: The New AI* (MIT Press, 2016)
240
+ - PhD from EPFL (1990); research stays at UC Berkeley, MIT, and IDIAP
241
+ - **34,000+ citations** on Google Scholar
242
+ - IEEE Senior Member; Pattern Recognition journal editorial board
243
+
244
+ His 1999 paper on the Combined 5×2cv F Test is the standard reference for classifier comparison. His Soft Decision Trees paper (2012) remains one of the most elegant proposals for differentiable tree models — predating the modern neural tree literature.
245
+
246
+ ---
247
+
248
+ ## Citation
249
+
250
+ If you use this library in academic work, please cite the original papers:
251
+
252
+ ```bibtex
253
+ @book{alpaydin2020introduction,
254
+ title = {Introduction to Machine Learning},
255
+ author = {Alpayd{\i}n, Ethem},
256
+ year = {2020},
257
+ edition = {4th},
258
+ publisher = {MIT Press}
259
+ }
260
+
261
+ @article{irsoy2021dropout,
262
+ title = {Dropout Regularization in Hierarchical Mixture of Experts},
263
+ author = {\.{I}rsoy, O{\u{g}}uzhan and Alpayd{\i}n, Ethem},
264
+ journal = {Neurocomputing},
265
+ volume = {419},
266
+ pages = {148--156},
267
+ year = {2021}
268
+ }
269
+
270
+ @inproceedings{irsoy2012soft,
271
+ title = {Soft Decision Trees},
272
+ author = {\.{I}rsoy, O{\u{g}}uzhan and Y{\i}ld{\i}z, Olcay Taner and Alpayd{\i}n, Ethem},
273
+ booktitle = {Proceedings of the 21st International Conference on Pattern Recognition (ICPR)},
274
+ year = {2012}
275
+ }
276
+
277
+ @article{alpaydin1999combined,
278
+ title = {Combined 5x2cv {F} Test for Comparing Supervised Classification Learning Algorithms},
279
+ author = {Alpayd{\i}n, Ethem},
280
+ journal = {Neural Computation},
281
+ volume = {11},
282
+ number = {8},
283
+ pages = {1885--1892},
284
+ year = {1999}
285
+ }
286
+ ```
287
+
288
+ ---
289
+
290
+ ## Roadmap
291
+
292
+ Things I'm planning to add:
293
+
294
+ - [ ] Multiple Kernel Learning (Gönen & Alpaydın, JMLR 2011)
295
+ - [ ] Localized Multiple Kernel Learning (ICML 2008)
296
+ - [ ] Convolutional Soft Decision Trees (ICANN 2018)
297
+ - [ ] Decision boundary visualization utilities
298
+ - [ ] Benchmark comparison on UCI datasets
299
+
300
+ If you find a bug or want to implement one of these, open an issue.
301
+
302
+ ---
303
+
304
+ ## License
305
+
306
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,28 @@
1
+ """
2
+ neural-trees: Implementations of algorithms from Prof. Dr. Ethem Alpaydın's
3
+ research papers and textbook "Introduction to Machine Learning" (MIT Press).
4
+
5
+ Reference:
6
+ Alpaydın, E. (2020). Introduction to Machine Learning (4th ed.). MIT Press.
7
+ """
8
+
9
+ __version__ = "0.1.0"
10
+ __author__ = "Cagri Temel"
11
+
12
+ from neural_trees.decision_trees.soft_decision_tree import SoftDecisionTree
13
+ from neural_trees.decision_trees.omnivariate_tree import OmnivariateDecisionTree
14
+ from neural_trees.statistical_tests.classifier_comparison import (
15
+ combined_5x2cv_f_test,
16
+ mcnemar_test,
17
+ paired_t_test,
18
+ )
19
+ from neural_trees.mixture_of_experts.hierarchical_moe import HierarchicalMixtureOfExperts
20
+
21
+ __all__ = [
22
+ "SoftDecisionTree",
23
+ "OmnivariateDecisionTree",
24
+ "HierarchicalMixtureOfExperts",
25
+ "combined_5x2cv_f_test",
26
+ "mcnemar_test",
27
+ "paired_t_test",
28
+ ]