binboost 0.2.5__tar.gz → 0.2.6__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.
- binboost-0.2.6/PKG-INFO +429 -0
- binboost-0.2.6/README.md +408 -0
- {binboost-0.2.5 → binboost-0.2.6}/binboost/__init__.py +1 -1
- {binboost-0.2.5 → binboost-0.2.6}/binboost/binboost.py +243 -0
- binboost-0.2.6/binboost/multiclass.py +156 -0
- {binboost-0.2.5 → binboost-0.2.6}/binboost/rule.py +62 -1
- binboost-0.2.6/binboost.egg-info/PKG-INFO +429 -0
- {binboost-0.2.5 → binboost-0.2.6}/pyproject.toml +1 -1
- {binboost-0.2.5 → binboost-0.2.6}/setup.py +1 -1
- binboost-0.2.5/PKG-INFO +0 -129
- binboost-0.2.5/README.md +0 -108
- binboost-0.2.5/binboost/multiclass.py +0 -70
- binboost-0.2.5/binboost.egg-info/PKG-INFO +0 -129
- {binboost-0.2.5 → binboost-0.2.6}/LICENSE +0 -0
- {binboost-0.2.5 → binboost-0.2.6}/binboost/binarizer.py +0 -0
- {binboost-0.2.5 → binboost-0.2.6}/binboost/loss.py +0 -0
- {binboost-0.2.5 → binboost-0.2.6}/binboost.egg-info/SOURCES.txt +0 -0
- {binboost-0.2.5 → binboost-0.2.6}/binboost.egg-info/dependency_links.txt +0 -0
- {binboost-0.2.5 → binboost-0.2.6}/binboost.egg-info/requires.txt +0 -0
- {binboost-0.2.5 → binboost-0.2.6}/binboost.egg-info/top_level.txt +0 -0
- {binboost-0.2.5 → binboost-0.2.6}/setup.cfg +0 -0
binboost-0.2.6/PKG-INFO
ADDED
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: binboost
|
|
3
|
+
Version: 0.2.6
|
|
4
|
+
Summary: Gradient Boosting Berbasis Aturan Logika Adaptif untuk Fitur Biner
|
|
5
|
+
Author: Rangga Wahyu Pratama
|
|
6
|
+
License: MIT
|
|
7
|
+
Keywords: gradient boosting,logical rules,binary features,interpretable machine learning
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Classifier: Intended Audience :: Science/Research
|
|
12
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
13
|
+
Requires-Python: >=3.8
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
License-File: LICENSE
|
|
16
|
+
Requires-Dist: numpy>=1.21.0
|
|
17
|
+
Requires-Dist: pandas>=1.3.0
|
|
18
|
+
Dynamic: author
|
|
19
|
+
Dynamic: license-file
|
|
20
|
+
Dynamic: requires-python
|
|
21
|
+
|
|
22
|
+
# BinBoost
|
|
23
|
+
|
|
24
|
+
**Gradient boosting with adaptive logic rules for binary and multi-class classification.**
|
|
25
|
+
|
|
26
|
+
BinBoost builds an additive ensemble in which every weak learner is a small logical rule over the input features, for example `(A AND NOT B) OR C`. Numeric features are binarized again at every boosting iteration with thresholds chosen from the current gradient. Each rule contributes one of two learned weights to the score of a sample, depending on whether the sample satisfies the rule. Because every weak learner is a readable rule, the fitted model can be inspected directly, without a post-hoc explanation tool.
|
|
27
|
+
|
|
28
|
+
The package depends only on NumPy. Pandas DataFrames are accepted as input and their column names are used in rule descriptions.
|
|
29
|
+
|
|
30
|
+
## Contents
|
|
31
|
+
|
|
32
|
+
- [Installation](#installation)
|
|
33
|
+
- [Quick start](#quick-start)
|
|
34
|
+
- [Multi-class classification](#multi-class-classification)
|
|
35
|
+
- [Reading the model](#reading-the-model)
|
|
36
|
+
- [How it works](#how-it-works)
|
|
37
|
+
- [Input requirements](#input-requirements)
|
|
38
|
+
- [API reference](#api-reference)
|
|
39
|
+
- [Package layout](#package-layout)
|
|
40
|
+
- [License](#license)
|
|
41
|
+
|
|
42
|
+
## Installation
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pip install binboost
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Quick start
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
from sklearn.datasets import load_breast_cancer
|
|
52
|
+
from sklearn.model_selection import train_test_split
|
|
53
|
+
from binboost import BinBoost
|
|
54
|
+
|
|
55
|
+
data = load_breast_cancer(as_frame=True)
|
|
56
|
+
X_train, X_test, y_train, y_test = train_test_split(
|
|
57
|
+
data.data, data.target, test_size=0.25, random_state=0, stratify=data.target
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
model = BinBoost(n_estimators=50, random_state=0)
|
|
61
|
+
model.fit(X_train, y_train)
|
|
62
|
+
|
|
63
|
+
print(model.predict(X_test))
|
|
64
|
+
print(model.predict_proba(X_test)) # shape (n_samples, 2)
|
|
65
|
+
print(model.score(X_test, y_test)) # accuracy
|
|
66
|
+
print(model.rules_[:2])
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
```text
|
|
70
|
+
['(worst concave points AND mean concave points)', '((worst radius AND worst concavity) AND worst concave points)']
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
`rule_summary_` lists every rule together with its two weights:
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
import pandas as pd
|
|
77
|
+
print(pd.DataFrame(model.rule_summary_).head(2))
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
```text
|
|
81
|
+
iterasi aturan bobot_memenuhi bobot_tidak_memenuhi panjang_aturan threshold_prediksi
|
|
82
|
+
0 1 (worst concave points AND mean concave points) -2.514364 1.204648 2 0.570929
|
|
83
|
+
1 2 ((worst radius AND worst concavity) AND worst concave points) -1.920358 1.219571 3 0.570929
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Labels for `BinBoost` must be `0` or `1`. For more than two classes use `OneVsRestBinBoost`.
|
|
87
|
+
|
|
88
|
+
## Multi-class classification
|
|
89
|
+
|
|
90
|
+
`OneVsRestBinBoost` trains one `BinBoost` model per class (one-vs-rest). Every keyword argument is forwarded to `BinBoost`, so the hyperparameters are identical.
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
from sklearn.datasets import load_iris
|
|
94
|
+
from sklearn.model_selection import train_test_split
|
|
95
|
+
from binboost.multiclass import OneVsRestBinBoost
|
|
96
|
+
|
|
97
|
+
iris = load_iris(as_frame=True)
|
|
98
|
+
X_train, X_test, y_train, y_test = train_test_split(
|
|
99
|
+
iris.data, iris.target, test_size=0.3, random_state=0, stratify=iris.target
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
model = OneVsRestBinBoost(mode='multiclass', n_estimators=50, random_state=0)
|
|
103
|
+
model.fit(X_train, y_train) # labels may be integers or strings
|
|
104
|
+
|
|
105
|
+
print(model.predict(X_test))
|
|
106
|
+
print(model.predict_proba(X_test)) # rows are normalized to sum to 1
|
|
107
|
+
print(model.n_rules_) # rules summed over all classes
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Two modes are available:
|
|
111
|
+
|
|
112
|
+
| `mode` | `predict_proba` | `predict` |
|
|
113
|
+
|---|---|---|
|
|
114
|
+
| `'multiclass'` (default) | Per-class probabilities normalized so that each row sums to 1. A row whose raw scores are all zero gets a uniform distribution. | The class with the largest normalized probability. |
|
|
115
|
+
| `'multilabel'` | Raw per-class probabilities, not normalized. | One binary column per class, each using its own sub-model and prediction threshold. |
|
|
116
|
+
|
|
117
|
+
## Reading the model
|
|
118
|
+
|
|
119
|
+
### Rule structure
|
|
120
|
+
|
|
121
|
+
A rule combines features from left to right with the operators `AND`, `OR` and optionally `XOR`. There is no operator precedence: `((A AND B) OR C)` is evaluated exactly as the parentheses indicate. Each feature in a rule can be negated, and `rules_` shows negation as `NOT`.
|
|
122
|
+
|
|
123
|
+
The score of a sample is
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
F(x) = F0 + learning_rate * sum over rules of ( w1 if x satisfies the rule else w0 )
|
|
127
|
+
P(y = 1 | x) = sigmoid(F(x))
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
`F0_` is the initial score, `rule_weights_[i] = [w0, w1]` holds the two weights of rule `i`, and the class decision compares `P(y = 1 | x)` with the prediction threshold.
|
|
131
|
+
|
|
132
|
+
### Global view
|
|
133
|
+
|
|
134
|
+
```python
|
|
135
|
+
model.rules_ # text of every rule, negations written as NOT
|
|
136
|
+
model.rule_summary_ # list of dicts, one per rule, with both weights
|
|
137
|
+
model.feature_importances_ # normalized importance per feature
|
|
138
|
+
model.feature_usage_ # how often each feature appears in a rule
|
|
139
|
+
model.thresholds_ # binarization thresholds per numeric feature and iteration
|
|
140
|
+
model.apply(X) # (n_samples, n_rules) matrix of rule activations
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
`jelaskan()` prints every rule in an IF / THEN / ELSE layout:
|
|
144
|
+
|
|
145
|
+
```python
|
|
146
|
+
model.jelaskan(maks=2, urut='pengaruh')
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
```text
|
|
150
|
+
Skor awal +0.518
|
|
151
|
+
Skor semua aturan dijumlahkan lalu diubah jadi probabilitas lewat sigmoid
|
|
152
|
+
Kelas positif adalah 1
|
|
153
|
+
Kelas positif dipilih jika probabilitas minimal 0.571
|
|
154
|
+
Skor positif mendorong ke kelas positif dan skor negatif mendorong ke arah sebaliknya
|
|
155
|
+
|
|
156
|
+
Aturan 1 dengan pengaruh 0.744
|
|
157
|
+
JIKA worst concave points > 0.14235
|
|
158
|
+
DAN mean concave points > 0.051455
|
|
159
|
+
MAKA skor -0.503
|
|
160
|
+
SELAIN ITU skor +0.241
|
|
161
|
+
|
|
162
|
+
Aturan 2 dengan pengaruh 0.628
|
|
163
|
+
JIKA worst radius > 15.455
|
|
164
|
+
DAN worst concavity > 0.2108
|
|
165
|
+
DAN worst concave points > 0.1151
|
|
166
|
+
MAKA skor -0.384
|
|
167
|
+
SELAIN ITU skor +0.244
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
How to read it:
|
|
171
|
+
|
|
172
|
+
- **Numeric features** are written against the binarization threshold used in that rule's iteration, for example `worst radius > 15.455`. A negated numeric feature becomes `<=`.
|
|
173
|
+
- **Binary features** are written as `feature = 1`, and a negated binary feature as `feature = 0`. No `NOT` appears in this output.
|
|
174
|
+
- **Layout.** When all operators in a rule are the same, the rule is a vertical list with the operator at the start of each line. When the operators are mixed, the rule stays on one line with parentheses so that the left-to-right evaluation order is unambiguous.
|
|
175
|
+
- **Scores** are the contribution of the rule to the final score, already multiplied by the learning rate. They therefore differ from the raw values in `rule_weights_`.
|
|
176
|
+
- **Influence** (`pengaruh`) is the absolute difference between the two scores of the rule. `urut='pengaruh'` sorts rules by it.
|
|
177
|
+
|
|
178
|
+
The text of these reports is in Indonesian. A short glossary:
|
|
179
|
+
|
|
180
|
+
| Output term | Meaning |
|
|
181
|
+
|---|---|
|
|
182
|
+
| `JIKA` | IF |
|
|
183
|
+
| `MAKA` | THEN |
|
|
184
|
+
| `SELAIN ITU` | ELSE |
|
|
185
|
+
| `DAN` / `ATAU` | AND / OR (`XOR` is unchanged) |
|
|
186
|
+
| `Aturan` | Rule |
|
|
187
|
+
| `pengaruh` | influence |
|
|
188
|
+
| `Skor awal` | initial score |
|
|
189
|
+
| `terpenuhi` / `tidak terpenuhi` | satisfied / not satisfied |
|
|
190
|
+
| `Nilai sampel` | sample values |
|
|
191
|
+
|
|
192
|
+
`rule_summary_` uses Indonesian keys as well: `iterasi` (iteration), `aturan` (rule), `bobot_memenuhi` (weight when satisfied), `bobot_tidak_memenuhi` (weight when not satisfied), `panjang_aturan` (rule length) and `threshold_prediksi` (prediction threshold).
|
|
193
|
+
|
|
194
|
+
`ringkas_ambang()` summarizes the thresholds that rules actually use for each numeric feature:
|
|
195
|
+
|
|
196
|
+
```python
|
|
197
|
+
print(pd.DataFrame(model.ringkas_ambang()).head(3))
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
```text
|
|
201
|
+
fitur jumlah_dipakai ambang_terkecil ambang_tengah ambang_terbesar
|
|
202
|
+
0 worst radius 17 12.8350 16.80500 17.67500
|
|
203
|
+
1 worst texture 17 20.2250 23.26500 25.83000
|
|
204
|
+
2 worst concave points 16 0.1151 0.12865 0.14655
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
The columns give the feature name, the number of rules that use it, and the smallest, median and largest threshold among those rules.
|
|
208
|
+
|
|
209
|
+
### Local view
|
|
210
|
+
|
|
211
|
+
`pilih_sampel` picks representative samples automatically, and `jelaskan_sampel` explains them rule by rule.
|
|
212
|
+
|
|
213
|
+
```python
|
|
214
|
+
X_eval = X_test.reset_index(drop=True)
|
|
215
|
+
|
|
216
|
+
model.pilih_sampel(X_eval, y_test.values)
|
|
217
|
+
model.jelaskan_sampel(X_eval, y_test.values, maks=8)
|
|
218
|
+
|
|
219
|
+
# Explain specific rows instead (positional row indices, labels optional)
|
|
220
|
+
model.jelaskan_sampel(X_eval, indeks=[5, 12])
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
For every class, `pilih_sampel` returns up to three samples (`indeks` is `None` when a class has no sample of that kind):
|
|
224
|
+
|
|
225
|
+
| `jenis` | Meaning |
|
|
226
|
+
|---|---|
|
|
227
|
+
| `'mudah'` | Correctly classified, farthest from the decision boundary. |
|
|
228
|
+
| `'sulit'` | Correctly classified, closest to the decision boundary. |
|
|
229
|
+
| `'salah'` | Misclassified, farthest from the decision boundary. |
|
|
230
|
+
|
|
231
|
+
Distance to the boundary is measured as the difference between the final score and the logit of the prediction threshold, so it stays meaningful when the threshold is not 0.5. For `OneVsRestBinBoost` it is the gap between the two largest normalized probabilities.
|
|
232
|
+
|
|
233
|
+
A report lists the initial score, the `maks` rules with the largest absolute contribution (including the sample's own values for the features involved), one line that aggregates the remaining rules, and the final score and probability:
|
|
234
|
+
|
|
235
|
+
```text
|
|
236
|
+
Jenis sampel : Salah dan yakin untuk kelas 1
|
|
237
|
+
Indeks baris : 13
|
|
238
|
+
Label asli : 1
|
|
239
|
+
Prediksi : 0
|
|
240
|
+
|
|
241
|
+
Skor awal +0.518
|
|
242
|
+
Aturan 1 terpenuhi skor -0.503
|
|
243
|
+
worst concave points > 0.14235 DAN mean concave points > 0.051455
|
|
244
|
+
Nilai sampel worst concave points 0.1505 dan mean concave points 0.07798
|
|
245
|
+
Aturan 3 terpenuhi skor -0.335
|
|
246
|
+
worst perimeter > 103.25 DAN worst concavity > 0.2162 DAN mean concave points > 0.049885
|
|
247
|
+
Nilai sampel worst perimeter 107 dan worst concavity 0.6783 dan mean concave points 0.07798
|
|
248
|
+
Sisa 48 aturan lainnya skor -0.852
|
|
249
|
+
Skor akhir -1.171
|
|
250
|
+
Probabilitas kelas positif 0.237
|
|
251
|
+
Keputusan kelas 0 karena probabilitas 0.237 kurang dari 0.571
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
Every rule adds a score, either `w1` when it is satisfied or `w0` when it is not, so a sample has one contribution per rule. The report therefore shows the largest ones and folds the rest into a single line, which keeps the sum complete. In multi-class mode a misclassified sample is explained with two sub-models: the predicted class (why it won) and the true class (why it lost).
|
|
255
|
+
|
|
256
|
+
## How it works
|
|
257
|
+
|
|
258
|
+
**Training loop.** Training starts from the log-odds of the (weighted) positive rate as the initial score `F0`. Each iteration then does the following:
|
|
259
|
+
|
|
260
|
+
1. Compute the gradient and Hessian of the selected loss at the current scores.
|
|
261
|
+
2. Draw a random subsample without replacement (`subsample`).
|
|
262
|
+
3. Binarize every numeric feature on the subsample with the selected strategy. This yields one threshold per numeric feature for this iteration.
|
|
263
|
+
4. Optionally keep only the candidate features whose gain is above a percentile (`feature_selection_threshold`).
|
|
264
|
+
5. Find a rule with beam search (below).
|
|
265
|
+
6. Apply the iteration's thresholds to the full training set and evaluate the rule there.
|
|
266
|
+
7. Compute two Newton-style weights, one for the samples that satisfy the rule and one for the others, using `w = sum(g) / (sum(H) + lambda)`, with `lambda = lambda0 * L / sqrt(n + 1)`. Here `L` is the rule length and `n` is the number of samples on that side.
|
|
267
|
+
8. Update the scores with `learning_rate * (w1 * h + w0 * (1 - h))`, where `h` is 1 for samples that satisfy the rule and 0 otherwise.
|
|
268
|
+
|
|
269
|
+
Training stops after `n_estimators` iterations, when no candidate rule passes the acceptance tests, or earlier when `n_iter_no_change` is set and the training loss stops improving by more than `tol`.
|
|
270
|
+
|
|
271
|
+
**Rule search.** Candidates are scored by how much they reduce the (weighted) squared error when fitting the current gradient with a single-weight rule, and all candidates are scored with matrix products rather than loops. The search starts from single features. Each feature is tried in both polarities, original and negated. A beam of the `beam_width` best rules is then extended one feature at a time with the allowed operators up to `max_rule_length`, and extension stops as soon as it no longer improves the best score. A rule is only accepted when:
|
|
272
|
+
|
|
273
|
+
- at least `min_samples_rule` samples satisfy it, and
|
|
274
|
+
- its error reduction is at least `gamma` times the current gradient energy. Because this threshold is relative, one value can be used across datasets and losses. A value of `0.0` disables the pruning.
|
|
275
|
+
|
|
276
|
+
`rule_complexity_penalty` makes the score of a candidate worse in proportion to its length.
|
|
277
|
+
|
|
278
|
+
**Binarization strategies** (`binarize_strategy`):
|
|
279
|
+
|
|
280
|
+
| Strategy | Threshold |
|
|
281
|
+
|---|---|
|
|
282
|
+
| `'gradient'` | Recomputed every iteration: the candidate cut that maximizes the absolute sum of the current gradient over the samples above it. |
|
|
283
|
+
| `'quantile'` | Fixed per feature: the median of the candidate cut points. |
|
|
284
|
+
| `'uniform'` | Fixed per feature: the midpoint between the minimum and maximum value. |
|
|
285
|
+
| `'kmeans'` | Fixed per feature: the midpoint between the two centroids of a one-dimensional 2-means clustering. |
|
|
286
|
+
|
|
287
|
+
Candidate cut points are midpoints between consecutive unique values. `n_thresholds='auto'` caps them at 256 per feature, taking an evenly spaced subset when there are more. Binarized values are `1` when the feature is strictly greater than the threshold.
|
|
288
|
+
|
|
289
|
+
**One-hot groups.** Binary columns that are mutually exclusive and add up to exactly one in every row are detected as a one-hot group (`ohe_groups_`). With `ohe_policy='block'` a single rule can never contain two categories of the same group, which rules out nonsensical rules such as `(Color_Red AND Color_Blue)`.
|
|
290
|
+
|
|
291
|
+
**Prediction threshold.** With `threshold='auto'` the cut-off on `P(y = 1)` is chosen after training by maximizing Youden's J (sensitivity + specificity - 1) on the training data, taking the smallest threshold that reaches the maximum. This means the cut-off is not fixed at 0.5. Pass a float to use a fixed value.
|
|
292
|
+
|
|
293
|
+
**Feature importance.** For each rule, the absolute difference `|w1 - w0|` is added to every feature the rule contains, and the totals are normalized to sum to 1.
|
|
294
|
+
|
|
295
|
+
**Losses.** `'logistic'` is the standard log-loss. `'focal'` is the focal loss with `focal_gamma` and `focal_alpha`. `'poly'` is the PolyLoss variant controlled by `poly_epsilon`. Each loss provides its own gradient and Hessian for the Newton weights.
|
|
296
|
+
|
|
297
|
+
**Sample weights.** `fit` accepts non-negative `sample_weight`. The weights are normalized to a mean of 1, so only their ratios matter. They enter the initial score, the gradients and Hessians, the rule search, the Newton weights, the training loss and the Youden threshold. `min_samples_rule` counts samples whose weight is positive. Subsampling stays uniform. Weights that are all equal give the same result as no weights.
|
|
298
|
+
|
|
299
|
+
## Input requirements
|
|
300
|
+
|
|
301
|
+
- `X` is converted to a float64 matrix. Numeric columns are detected automatically as every column that is not purely `0`/`1`. Missing values are not handled, so impute them before fitting.
|
|
302
|
+
- `y` for `BinBoost` must contain only `0` and `1`. `OneVsRestBinBoost` accepts any labels, with at least two distinct classes.
|
|
303
|
+
- Categorical features with three or more categories must be one-hot encoded. Keep every category column (do not drop one) so that each group adds up to exactly one per row and is recognized as a group:
|
|
304
|
+
|
|
305
|
+
```python
|
|
306
|
+
from sklearn.preprocessing import OneHotEncoder
|
|
307
|
+
|
|
308
|
+
encoder = OneHotEncoder(sparse_output=False) # no drop=...
|
|
309
|
+
X_encoded = encoder.fit_transform(X[['categorical_column']])
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
If one column per group is dropped (for example `drop='first'`), the columns no longer add up to one in every row. The group is then not detected, and `ohe_policy` has no effect for it.
|
|
313
|
+
|
|
314
|
+
- `pilih_sampel` and `jelaskan_sampel` expect `y` values of `0`/`1` for `BinBoost` and use positional row indices. `OneVsRestBinBoost.pilih_sampel` supports `mode='multiclass'` only.
|
|
315
|
+
|
|
316
|
+
## API reference
|
|
317
|
+
|
|
318
|
+
### `BinBoost`
|
|
319
|
+
|
|
320
|
+
```python
|
|
321
|
+
BinBoost(
|
|
322
|
+
n_estimators=100, learning_rate=0.2, loss='logistic',
|
|
323
|
+
poly_epsilon=1.0, focal_gamma=2.0, focal_alpha=0.25,
|
|
324
|
+
max_rule_length=4, operators=None, use_xor=False,
|
|
325
|
+
rule_complexity_penalty=0.0, feature_selection_threshold=0.0,
|
|
326
|
+
beam_width=5, subsample=0.8, min_samples_rule=5,
|
|
327
|
+
lambda0=3.0, gamma=0.001, binarize_strategy='gradient',
|
|
328
|
+
n_thresholds='auto', n_iter_no_change=None, tol=1e-4,
|
|
329
|
+
random_state=None, warm_start=False, threshold='auto',
|
|
330
|
+
ohe_policy='block',
|
|
331
|
+
)
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
| Parameter | Default | Description |
|
|
335
|
+
|---|---|---|
|
|
336
|
+
| `n_estimators` | `100` | Maximum number of boosting iterations (rules). |
|
|
337
|
+
| `learning_rate` | `0.2` | Shrinkage applied to the contribution of every rule. |
|
|
338
|
+
| `loss` | `'logistic'` | `'logistic'`, `'focal'` or `'poly'`. |
|
|
339
|
+
| `poly_epsilon` | `1.0` | Epsilon of the PolyLoss. Used only when `loss='poly'`. |
|
|
340
|
+
| `focal_gamma` | `2.0` | Gamma of the focal loss. Used only when `loss='focal'`. |
|
|
341
|
+
| `focal_alpha` | `0.25` | Alpha of the focal loss. Used only when `loss='focal'`. |
|
|
342
|
+
| `max_rule_length` | `4` | Maximum number of features in one rule. |
|
|
343
|
+
| `operators` | `None` | Logical operators allowed in a rule. `None` means `['AND', 'OR']`. |
|
|
344
|
+
| `use_xor` | `False` | Adds `'XOR'` to the operators. |
|
|
345
|
+
| `rule_complexity_penalty` | `0.0` | Makes longer candidate rules score worse in proportion to their length. |
|
|
346
|
+
| `feature_selection_threshold` | `0.0` | Percentile of per-feature gain below which features are not considered as candidates in an iteration. `0.0` keeps all features and `0.5` keeps those above the median gain. |
|
|
347
|
+
| `beam_width` | `5` | Number of best partial rules kept at each step of the beam search. |
|
|
348
|
+
| `subsample` | `0.8` | Fraction of the training data drawn without replacement in each iteration. |
|
|
349
|
+
| `min_samples_rule` | `5` | Minimum number of samples that must satisfy a rule. A float below `1.0` is read as a fraction of the sample count. |
|
|
350
|
+
| `lambda0` | `3.0` | Base regularization of the Newton weights, `lambda = lambda0 * L / sqrt(n + 1)`. |
|
|
351
|
+
| `gamma` | `0.001` | Relative minimum error reduction (as a multiple of the gradient energy) needed to accept a rule. `0.0` disables it. |
|
|
352
|
+
| `binarize_strategy` | `'gradient'` | `'gradient'`, `'quantile'`, `'uniform'` or `'kmeans'`. |
|
|
353
|
+
| `n_thresholds` | `'auto'` | Number of candidate thresholds per numeric feature. `'auto'` means at most 256. |
|
|
354
|
+
| `n_iter_no_change` | `None` | Stop when the training loss has not improved for this many iterations. `None` disables early stopping. |
|
|
355
|
+
| `tol` | `1e-4` | Minimum loss improvement that counts as progress for early stopping. |
|
|
356
|
+
| `random_state` | `None` | Seed for the subsampling. |
|
|
357
|
+
| `warm_start` | `False` | Continue training from the existing ensemble and add more rules. |
|
|
358
|
+
| `threshold` | `'auto'` | Prediction threshold on `P(y = 1)`. `'auto'` uses Youden's J on the training data. A float fixes it. |
|
|
359
|
+
| `ohe_policy` | `'block'` | `'block'` forbids two categories of one one-hot group in the same rule and `'allow'` permits it. |
|
|
360
|
+
|
|
361
|
+
### Methods
|
|
362
|
+
|
|
363
|
+
| Method | Description |
|
|
364
|
+
|---|---|
|
|
365
|
+
| `fit(X, y, sample_weight=None)` | Train the model. Returns `self`. |
|
|
366
|
+
| `predict(X)` | Class labels `0` or `1` using the prediction threshold. |
|
|
367
|
+
| `predict_proba(X)` | Array of shape `(n_samples, 2)`. |
|
|
368
|
+
| `predict_log_proba(X)` | Logarithm of `predict_proba`. |
|
|
369
|
+
| `score(X, y)` | Accuracy. |
|
|
370
|
+
| `staged_predict(X)` / `staged_predict_proba(X)` | Generators that yield the prediction after each boosting iteration. |
|
|
371
|
+
| `apply(X)` | Rule activations of shape `(n_samples, n_rules)`. |
|
|
372
|
+
| `get_params()` / `set_params(**params)` | Read and change hyperparameters. |
|
|
373
|
+
| `jelaskan(urut='iterasi', maks=None, cetak=True, nama_positif=1)` | IF / THEN / ELSE description of the rules. `urut` is `'iterasi'` or `'pengaruh'`, `maks` limits the number of rules, and the text is returned as a string. |
|
|
374
|
+
| `ringkas_ambang()` | Per-feature summary of the thresholds that rules use. |
|
|
375
|
+
| `pilih_sampel(X, y, jenis=('mudah', 'sulit', 'salah'))` | Select representative samples per class. |
|
|
376
|
+
| `jelaskan_sampel(X, y=None, indeks=None, jenis=('mudah', 'sulit', 'salah'), maks=8, cetak=True)` | Rule-by-rule explanation of selected or given samples. `y` is required unless `indeks` is given. |
|
|
377
|
+
|
|
378
|
+
### Attributes and properties
|
|
379
|
+
|
|
380
|
+
| Name | Description |
|
|
381
|
+
|---|---|
|
|
382
|
+
| `estimators_` | List of the learned `Rule` objects. |
|
|
383
|
+
| `F0_` | Initial score (log-odds of the positive rate). |
|
|
384
|
+
| `rule_weights_` | Array of shape `(n_rules, 2)` with columns `[w0, w1]`: the weight when the rule is not satisfied and when it is satisfied. |
|
|
385
|
+
| `rules_` | Text of every rule, with `NOT` for negated features. |
|
|
386
|
+
| `rule_summary_` | List of dicts with the keys `iterasi`, `aturan`, `bobot_memenuhi`, `bobot_tidak_memenuhi`, `panjang_aturan`, `threshold_prediksi`. |
|
|
387
|
+
| `feature_importances_` | Normalized importance per feature. |
|
|
388
|
+
| `feature_usage_` | Dict of how often each feature appears in rules. |
|
|
389
|
+
| `thresholds_` | Dict mapping each numeric feature index to its list of thresholds, one per iteration. |
|
|
390
|
+
| `train_score_` | Training loss after each iteration. |
|
|
391
|
+
| `n_rules_` / `n_estimators_` | Number of rules actually learned. |
|
|
392
|
+
| `n_features_in_` | Number of features seen during `fit`. |
|
|
393
|
+
| `feature_names_in_` | Column names when `fit` received a DataFrame, otherwise `None`. |
|
|
394
|
+
| `numeric_cols_` | Indices of the columns treated as numeric. |
|
|
395
|
+
| `ohe_groups_` | Detected one-hot groups as a dict, or `None`. |
|
|
396
|
+
|
|
397
|
+
### `OneVsRestBinBoost`
|
|
398
|
+
|
|
399
|
+
```python
|
|
400
|
+
OneVsRestBinBoost(mode='multiclass', **binboost_params)
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
`fit(X, y, sample_weight=None)`, `predict`, `predict_proba` and `score` work as described above. Other members:
|
|
404
|
+
|
|
405
|
+
| Name | Description |
|
|
406
|
+
|---|---|
|
|
407
|
+
| `classes_`, `n_classes_` | The class labels and their count. |
|
|
408
|
+
| `estimators_ovr_` | The per-class `BinBoost` models, in the order of `classes_`. |
|
|
409
|
+
| `rule_summary_` | Combined rule summaries with an extra `kelas` column that names the class of each sub-model. |
|
|
410
|
+
| `feature_usage_` | Feature usage summed over all classes. |
|
|
411
|
+
| `n_rules_` | Total number of rules across classes. |
|
|
412
|
+
| `jelaskan(urut='iterasi', maks=None, cetak=True)` | The `BinBoost.jelaskan` description for every class model. The class is the positive class of its own section. |
|
|
413
|
+
| `ringkas_ambang()` | Threshold summaries of all models with a `kelas` column. |
|
|
414
|
+
| `pilih_sampel(X, y, jenis=...)` | Representative samples per class (`mode='multiclass'` only). |
|
|
415
|
+
| `jelaskan_sampel(X, y, jenis=..., maks=8, cetak=True)` | Explanation of the selected samples, including the combined class probabilities. |
|
|
416
|
+
|
|
417
|
+
## Package layout
|
|
418
|
+
|
|
419
|
+
| Module | Contents |
|
|
420
|
+
|---|---|
|
|
421
|
+
| `binboost/binboost.py` | `BinBoost`: the boosting loop, prediction, thresholding and the explanation methods. |
|
|
422
|
+
| `binboost/rule.py` | `Rule` (evaluation and text rendering) and `BeamSearchRuleFinder` (vectorized beam search). |
|
|
423
|
+
| `binboost/binarizer.py` | `GradientBinarizer`: the four binarization strategies. |
|
|
424
|
+
| `binboost/loss.py` | `LogisticLoss`, `FocalLoss`, `PolyLoss`, `get_loss` and a numerically stable `sigmoid`. |
|
|
425
|
+
| `binboost/multiclass.py` | `OneVsRestBinBoost`: the one-vs-rest wrapper. |
|
|
426
|
+
|
|
427
|
+
## License
|
|
428
|
+
|
|
429
|
+
MIT
|