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.
Files changed (32) hide show
  1. {ngboost-0.5.10.dev0 → ngboost-0.5.11}/PKG-INFO +1 -1
  2. {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/api.py +49 -7
  3. {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/learners.py +1 -1
  4. {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/ngboost.py +100 -9
  5. {ngboost-0.5.10.dev0 → ngboost-0.5.11}/pyproject.toml +1 -1
  6. {ngboost-0.5.10.dev0 → ngboost-0.5.11}/LICENSE +0 -0
  7. {ngboost-0.5.10.dev0 → ngboost-0.5.11}/README.md +0 -0
  8. {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/__init__.py +0 -0
  9. {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/__init__.py +0 -0
  10. {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/beta.py +0 -0
  11. {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/beta_bernoulli.py +0 -0
  12. {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/betabinomial.py +0 -0
  13. {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/categorical.py +0 -0
  14. {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/cauchy.py +0 -0
  15. {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/distn.py +0 -0
  16. {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/exponential.py +0 -0
  17. {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/gamma.py +0 -0
  18. {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/halfnormal.py +0 -0
  19. {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/laplace.py +0 -0
  20. {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/logitnormal.py +0 -0
  21. {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/lognormal.py +0 -0
  22. {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/multivariate_normal.py +0 -0
  23. {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/normal.py +0 -0
  24. {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/poisson.py +0 -0
  25. {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/sympy_utils.py +0 -0
  26. {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/t.py +0 -0
  27. {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/utils.py +0 -0
  28. {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/distns/weibull.py +0 -0
  29. {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/evaluation.py +0 -0
  30. {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/helpers.py +0 -0
  31. {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/manifold.py +0 -0
  32. {ngboost-0.5.10.dev0 → ngboost-0.5.11}/ngboost/scores.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: ngboost
3
- Version: 0.5.10.dev0
3
+ Version: 0.5.11
4
4
  Summary: Library for probabilistic predictions via gradient boosting.
5
5
  License: Apache-2.0
6
6
  Author: Stanford ML Group
@@ -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
- Any instantiated sklearn regressor, e.g. DecisionTreeRegressor()
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
- Any instantiated sklearn regressor, e.g. DecisionTreeRegressor()
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
- Any instantiated sklearn regressor, e.g. DecisionTreeRegressor()
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="friedman_mse",
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
- Any instantiated sklearn regressor, e.g. DecisionTreeRegressor()
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(self.Base).fit(X, g) for g in grads.T]
193
+ models = [clone(base).fit(X, g) for base, g in zip(base_learners, grads.T)]
173
194
  else:
174
195
  models = [
175
- clone(self.Base).fit(X, g, sample_weight=sample_weight) for g in grads.T
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
- for parameter, value in parameters.items():
496
- setattr(self, parameter, value)
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 : Ignored. (for compatibility with sklearn)
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 the base model is DecisionTreeRegressor
620
- if not isinstance(self.base_models[0][0], DecisionTreeRegressor):
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)
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "ngboost"
3
- version = "0.5.10dev"
3
+ version = "0.5.11"
4
4
  description = "Library for probabilistic predictions via gradient boosting."
5
5
  authors = ["Stanford ML Group <avati@cs.stanford.edu>"]
6
6
  readme = "README.md"
File without changes
File without changes