ngboost 0.5.10.dev0__tar.gz → 0.5.11__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.
- {ngboost-0.5.10.dev0 → ngboost-0.5.11}/PKG-INFO +1 -1
- {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/api.py +49 -7
- {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/learners.py +1 -1
- {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/ngboost.py +100 -9
- {ngboost-0.5.10.dev0 → ngboost-0.5.11}/pyproject.toml +1 -1
- {ngboost-0.5.10.dev0 → ngboost-0.5.11}/LICENSE +0 -0
- {ngboost-0.5.10.dev0 → ngboost-0.5.11}/README.md +0 -0
- {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/__init__.py +0 -0
- {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/__init__.py +0 -0
- {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/beta.py +0 -0
- {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/beta_bernoulli.py +0 -0
- {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/betabinomial.py +0 -0
- {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/categorical.py +0 -0
- {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/cauchy.py +0 -0
- {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/distn.py +0 -0
- {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/exponential.py +0 -0
- {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/gamma.py +0 -0
- {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/halfnormal.py +0 -0
- {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/laplace.py +0 -0
- {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/logitnormal.py +0 -0
- {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/lognormal.py +0 -0
- {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/multivariate_normal.py +0 -0
- {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/normal.py +0 -0
- {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/poisson.py +0 -0
- {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/sympy_utils.py +0 -0
- {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/t.py +0 -0
- {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/utils.py +0 -0
- {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/weibull.py +0 -0
- {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/evaluation.py +0 -0
- {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/helpers.py +0 -0
- {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/manifold.py +0 -0
- {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/scores.py +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"The NGBoost library API"
|
|
2
|
+
|
|
2
3
|
# pylint: disable=too-many-arguments
|
|
3
4
|
from sklearn.base import BaseEstimator
|
|
4
5
|
from sklearn.utils import check_array
|
|
@@ -31,8 +32,15 @@ class NGBRegressor(NGBoost, BaseEstimator):
|
|
|
31
32
|
A distribution from ngboost.distns, e.g. Normal
|
|
32
33
|
Score : rule to compare probabilistic predictions P̂ to the observed data y.
|
|
33
34
|
A score from ngboost.scores, e.g. LogScore
|
|
34
|
-
Base : base learner to use in the boosting algorithm.
|
|
35
|
-
|
|
35
|
+
Base : base learner(s) to use in the boosting algorithm.
|
|
36
|
+
Pass a single instantiated sklearn regressor, e.g.
|
|
37
|
+
DecisionTreeRegressor(), to use the same learner for
|
|
38
|
+
every distribution parameter. To use different learners
|
|
39
|
+
per distribution parameter, pass a list/tuple of
|
|
40
|
+
instantiated sklearn regressors with length equal to
|
|
41
|
+
Dist.n_params. The sequence order matches the distribution
|
|
42
|
+
parameter order; for example, Normal uses
|
|
43
|
+
[loc_learner, scale_learner].
|
|
36
44
|
natural_gradient : logical flag indicating whether the natural gradient should be used
|
|
37
45
|
n_estimators : the number of boosting iterations to fit
|
|
38
46
|
learning_rate : the learning rate
|
|
@@ -127,8 +135,15 @@ class NGBClassifier(NGBoost, BaseEstimator):
|
|
|
127
135
|
A distribution from ngboost.distns, e.g. Bernoulli
|
|
128
136
|
Score : rule to compare probabilistic predictions P̂ to the observed data y.
|
|
129
137
|
A score from ngboost.scores, e.g. LogScore
|
|
130
|
-
Base : base learner to use in the boosting algorithm.
|
|
131
|
-
|
|
138
|
+
Base : base learner(s) to use in the boosting algorithm.
|
|
139
|
+
Pass a single instantiated sklearn regressor, e.g.
|
|
140
|
+
DecisionTreeRegressor(), to use the same learner for
|
|
141
|
+
every distribution parameter. To use different learners
|
|
142
|
+
per distribution parameter, pass a list/tuple of
|
|
143
|
+
instantiated sklearn regressors with length equal to
|
|
144
|
+
Dist.n_params. The sequence order matches the distribution
|
|
145
|
+
parameter order; for example, Normal uses
|
|
146
|
+
[loc_learner, scale_learner].
|
|
132
147
|
natural_gradient : logical flag indicating whether the natural gradient should be used
|
|
133
148
|
n_estimators : the number of boosting iterations to fit
|
|
134
149
|
learning_rate : the learning rate
|
|
@@ -139,6 +154,12 @@ class NGBClassifier(NGBoost, BaseEstimator):
|
|
|
139
154
|
tol : numerical tolerance to be used in optimization
|
|
140
155
|
random_state : seed for reproducibility. See
|
|
141
156
|
https://stackoverflow.com/questions/28064634/random-state-pseudo-random-number-in-scikit-learn
|
|
157
|
+
validation_fraction: Proportion of training data to set
|
|
158
|
+
aside as validation data for early stopping.
|
|
159
|
+
early_stopping_rounds: The number of consecutive boosting iterations during which the
|
|
160
|
+
loss has to increase before the algorithm stops early.
|
|
161
|
+
Set to None to disable early stopping and validation.
|
|
162
|
+
None enables running over the full data set.
|
|
142
163
|
Output:
|
|
143
164
|
An NGBClassifier object that can be fit.
|
|
144
165
|
"""
|
|
@@ -158,6 +179,8 @@ class NGBClassifier(NGBoost, BaseEstimator):
|
|
|
158
179
|
verbose_eval=100,
|
|
159
180
|
tol=1e-4,
|
|
160
181
|
random_state=None,
|
|
182
|
+
validation_fraction=0.1,
|
|
183
|
+
early_stopping_rounds=None,
|
|
161
184
|
):
|
|
162
185
|
assert issubclass(
|
|
163
186
|
Dist, ClassificationDistn
|
|
@@ -175,6 +198,8 @@ class NGBClassifier(NGBoost, BaseEstimator):
|
|
|
175
198
|
verbose_eval,
|
|
176
199
|
tol,
|
|
177
200
|
random_state,
|
|
201
|
+
validation_fraction,
|
|
202
|
+
early_stopping_rounds,
|
|
178
203
|
)
|
|
179
204
|
self._estimator_type = "classifier"
|
|
180
205
|
|
|
@@ -221,8 +246,15 @@ class NGBSurvival(NGBoost, BaseEstimator):
|
|
|
221
246
|
A distribution from ngboost.distns, e.g. LogNormal
|
|
222
247
|
Score : rule to compare probabilistic predictions P̂ to the observed data y.
|
|
223
248
|
A score from ngboost.scores, e.g. LogScore
|
|
224
|
-
Base : base learner to use in the boosting algorithm.
|
|
225
|
-
|
|
249
|
+
Base : base learner(s) to use in the boosting algorithm.
|
|
250
|
+
Pass a single instantiated sklearn regressor, e.g.
|
|
251
|
+
DecisionTreeRegressor(), to use the same learner for
|
|
252
|
+
every distribution parameter. To use different learners
|
|
253
|
+
per distribution parameter, pass a list/tuple of
|
|
254
|
+
instantiated sklearn regressors with length equal to
|
|
255
|
+
Dist.n_params. The sequence order matches the distribution
|
|
256
|
+
parameter order; for example, Normal uses
|
|
257
|
+
[loc_learner, scale_learner].
|
|
226
258
|
natural_gradient : logical flag indicating whether the natural gradient should be used
|
|
227
259
|
n_estimators : the number of boosting iterations to fit
|
|
228
260
|
learning_rate : the learning rate
|
|
@@ -233,11 +265,17 @@ class NGBSurvival(NGBoost, BaseEstimator):
|
|
|
233
265
|
tol : numerical tolerance to be used in optimization
|
|
234
266
|
random_state : seed for reproducibility. See
|
|
235
267
|
https://stackoverflow.com/questions/28064634/random-state-pseudo-random-number-in-scikit-learn
|
|
268
|
+
validation_fraction: Proportion of training data to set
|
|
269
|
+
aside as validation data for early stopping.
|
|
270
|
+
early_stopping_rounds: The number of consecutive boosting iterations during which the
|
|
271
|
+
loss has to increase before the algorithm stops early.
|
|
272
|
+
Set to None to disable early stopping and validation.
|
|
273
|
+
None enables running over the full data set.
|
|
236
274
|
Output:
|
|
237
275
|
An NGBSurvival object that can be fit.
|
|
238
276
|
"""
|
|
239
277
|
|
|
240
|
-
# pylint: disable=too-many-positional-arguments
|
|
278
|
+
# pylint: disable=too-many-positional-arguments,too-many-locals
|
|
241
279
|
def __init__(
|
|
242
280
|
self,
|
|
243
281
|
Dist=LogNormal,
|
|
@@ -252,6 +290,8 @@ class NGBSurvival(NGBoost, BaseEstimator):
|
|
|
252
290
|
verbose_eval=100,
|
|
253
291
|
tol=1e-4,
|
|
254
292
|
random_state=None,
|
|
293
|
+
validation_fraction=0.1,
|
|
294
|
+
early_stopping_rounds=None,
|
|
255
295
|
):
|
|
256
296
|
|
|
257
297
|
assert issubclass(
|
|
@@ -278,6 +318,8 @@ class NGBSurvival(NGBoost, BaseEstimator):
|
|
|
278
318
|
verbose_eval,
|
|
279
319
|
tol,
|
|
280
320
|
random_state,
|
|
321
|
+
validation_fraction,
|
|
322
|
+
early_stopping_rounds,
|
|
281
323
|
)
|
|
282
324
|
|
|
283
325
|
def __getstate__(self):
|
|
@@ -2,7 +2,7 @@ from sklearn.linear_model import Ridge
|
|
|
2
2
|
from sklearn.tree import DecisionTreeRegressor
|
|
3
3
|
|
|
4
4
|
default_tree_learner = DecisionTreeRegressor(
|
|
5
|
-
criterion="
|
|
5
|
+
criterion="squared_error",
|
|
6
6
|
min_samples_split=2,
|
|
7
7
|
min_samples_leaf=1,
|
|
8
8
|
min_weight_fraction_leaf=0.0,
|
|
@@ -29,8 +29,15 @@ class NGBoost:
|
|
|
29
29
|
A distribution from ngboost.distns, e.g. Normal
|
|
30
30
|
Score : rule to compare probabilistic predictions P̂ to the observed data y.
|
|
31
31
|
A score from ngboost.scores, e.g. LogScore
|
|
32
|
-
Base : base learner to use in the boosting algorithm.
|
|
33
|
-
|
|
32
|
+
Base : base learner(s) to use in the boosting algorithm.
|
|
33
|
+
Pass a single instantiated sklearn regressor, e.g.
|
|
34
|
+
DecisionTreeRegressor(), to use the same learner for
|
|
35
|
+
every distribution parameter. To use different learners
|
|
36
|
+
per distribution parameter, pass a list/tuple of
|
|
37
|
+
instantiated sklearn regressors with length equal to
|
|
38
|
+
Dist.n_params. The sequence order matches the distribution
|
|
39
|
+
parameter order; for example, Normal uses
|
|
40
|
+
[loc_learner, scale_learner].
|
|
34
41
|
natural_gradient : logical flag indicating whether the natural gradient should be used
|
|
35
42
|
n_estimators : the number of boosting iterations to fit
|
|
36
43
|
learning_rate : the learning rate
|
|
@@ -167,12 +174,27 @@ class NGBoost:
|
|
|
167
174
|
params[idxs, :],
|
|
168
175
|
)
|
|
169
176
|
|
|
177
|
+
def _base_learners(self):
|
|
178
|
+
if not isinstance(self.Base, (list, tuple)):
|
|
179
|
+
return [self.Base] * self.Manifold.n_params
|
|
180
|
+
|
|
181
|
+
if len(self.Base) != self.Manifold.n_params:
|
|
182
|
+
raise ValueError(
|
|
183
|
+
"Base must be a single estimator or a sequence with one estimator "
|
|
184
|
+
"per distribution parameter "
|
|
185
|
+
f"({self.Manifold.n_params} for {self.Dist.__name__}); "
|
|
186
|
+
f"got {len(self.Base)}."
|
|
187
|
+
)
|
|
188
|
+
return self.Base
|
|
189
|
+
|
|
170
190
|
def fit_base(self, X, grads, sample_weight=None):
|
|
191
|
+
base_learners = self._base_learners()
|
|
171
192
|
if sample_weight is None:
|
|
172
|
-
models = [clone(
|
|
193
|
+
models = [clone(base).fit(X, g) for base, g in zip(base_learners, grads.T)]
|
|
173
194
|
else:
|
|
174
195
|
models = [
|
|
175
|
-
clone(
|
|
196
|
+
clone(base).fit(X, g, sample_weight=sample_weight)
|
|
197
|
+
for base, g in zip(base_learners, grads.T)
|
|
176
198
|
]
|
|
177
199
|
fitted = np.array([m.predict(X) for m in models]).T
|
|
178
200
|
self.base_models.append(models)
|
|
@@ -320,6 +342,7 @@ class NGBoost:
|
|
|
320
342
|
raise RuntimeError(
|
|
321
343
|
"Base models, scalings, and col_idxs are not the same length"
|
|
322
344
|
)
|
|
345
|
+
self._base_learners()
|
|
323
346
|
|
|
324
347
|
# if early stopping is specified, split X,Y and sample weights (if given) into training and validation sets
|
|
325
348
|
# This will overwrite any X_val and Y_val values passed by the user directly.
|
|
@@ -491,16 +514,65 @@ class NGBoost:
|
|
|
491
514
|
|
|
492
515
|
return self
|
|
493
516
|
|
|
517
|
+
def _set_base_params(self, parameters):
|
|
518
|
+
if not isinstance(self.Base, (list, tuple)):
|
|
519
|
+
self.Base.set_params(**parameters)
|
|
520
|
+
return
|
|
521
|
+
|
|
522
|
+
base_learners = list(self.Base)
|
|
523
|
+
for key, value in parameters.items():
|
|
524
|
+
index, delim, sub_key = key.partition("__")
|
|
525
|
+
try:
|
|
526
|
+
index = int(index)
|
|
527
|
+
except ValueError as exc:
|
|
528
|
+
raise ValueError(
|
|
529
|
+
"Base sequence parameters must use integer positions, "
|
|
530
|
+
f"for example Base__0__max_depth. Got Base__{key}."
|
|
531
|
+
) from exc
|
|
532
|
+
if index < 0 or index >= len(base_learners):
|
|
533
|
+
raise ValueError(
|
|
534
|
+
f"Base sequence index {index} is out of range for "
|
|
535
|
+
f"{len(base_learners)} estimators."
|
|
536
|
+
)
|
|
537
|
+
if delim:
|
|
538
|
+
base_learners[index].set_params(**{sub_key: value})
|
|
539
|
+
else:
|
|
540
|
+
base_learners[index] = value
|
|
541
|
+
self.Base = type(self.Base)(base_learners)
|
|
542
|
+
|
|
494
543
|
def set_params(self, **parameters):
|
|
495
|
-
|
|
496
|
-
|
|
544
|
+
if not parameters:
|
|
545
|
+
return self
|
|
546
|
+
|
|
547
|
+
valid_params = self.get_params(deep=True)
|
|
548
|
+
nested_params = {}
|
|
549
|
+
for key, value in parameters.items():
|
|
550
|
+
key, delim, sub_key = key.partition("__")
|
|
551
|
+
if key not in valid_params:
|
|
552
|
+
local_valid_params = self.get_params(deep=False).keys()
|
|
553
|
+
raise ValueError(
|
|
554
|
+
f"Invalid parameter {key!r} for estimator {self}. "
|
|
555
|
+
f"Valid parameters are: {sorted(local_valid_params)!r}."
|
|
556
|
+
)
|
|
557
|
+
if delim:
|
|
558
|
+
nested_params.setdefault(key, {})[sub_key] = value
|
|
559
|
+
else:
|
|
560
|
+
setattr(self, key, value)
|
|
561
|
+
valid_params[key] = value
|
|
562
|
+
|
|
563
|
+
for key, sub_params in nested_params.items():
|
|
564
|
+
if key == "Base":
|
|
565
|
+
self._set_base_params(sub_params)
|
|
566
|
+
else:
|
|
567
|
+
valid_params[key].set_params(**sub_params)
|
|
497
568
|
return self
|
|
498
569
|
|
|
499
570
|
def get_params(self, deep=True):
|
|
500
571
|
"""
|
|
501
572
|
Parameters
|
|
502
573
|
----------
|
|
503
|
-
deep :
|
|
574
|
+
deep : bool, default=True
|
|
575
|
+
If True, return nested parameters for the base learner or learners.
|
|
504
576
|
Returns
|
|
505
577
|
----------
|
|
506
578
|
params : returns an dictionary of parameters.
|
|
@@ -515,11 +587,26 @@ class NGBoost:
|
|
|
515
587
|
"minibatch_frac": self.minibatch_frac,
|
|
516
588
|
"col_sample": self.col_sample,
|
|
517
589
|
"verbose": self.verbose,
|
|
590
|
+
"verbose_eval": self.verbose_eval,
|
|
591
|
+
"tol": self.tol,
|
|
518
592
|
"random_state": self.random_state,
|
|
519
593
|
"validation_fraction": self.validation_fraction,
|
|
520
594
|
"early_stopping_rounds": self.early_stopping_rounds,
|
|
521
595
|
}
|
|
522
596
|
|
|
597
|
+
if not deep:
|
|
598
|
+
return params
|
|
599
|
+
|
|
600
|
+
if isinstance(self.Base, (list, tuple)):
|
|
601
|
+
for i, base in enumerate(self.Base):
|
|
602
|
+
params[f"Base__{i}"] = base
|
|
603
|
+
if hasattr(base, "get_params"):
|
|
604
|
+
for key, value in base.get_params(deep=True).items():
|
|
605
|
+
params[f"Base__{i}__{key}"] = value
|
|
606
|
+
elif hasattr(self.Base, "get_params"):
|
|
607
|
+
for key, value in self.Base.get_params(deep=True).items():
|
|
608
|
+
params[f"Base__{key}"] = value
|
|
609
|
+
|
|
523
610
|
return params
|
|
524
611
|
|
|
525
612
|
def score(self, X, Y): # for sklearn
|
|
@@ -616,8 +703,12 @@ class NGBoost:
|
|
|
616
703
|
# Check whether the model is fitted
|
|
617
704
|
if not self.base_models:
|
|
618
705
|
return None
|
|
619
|
-
# Check whether
|
|
620
|
-
if
|
|
706
|
+
# Check whether all base models are DecisionTreeRegressor
|
|
707
|
+
if any(
|
|
708
|
+
not isinstance(model, DecisionTreeRegressor)
|
|
709
|
+
for models in self.base_models
|
|
710
|
+
for model in models
|
|
711
|
+
):
|
|
621
712
|
return None
|
|
622
713
|
# Reshape the base_models
|
|
623
714
|
params_trees = zip(*self.base_models)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|