ngboost 0.5.9__tar.gz → 0.5.10.dev0__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 (33) hide show
  1. {ngboost-0.5.9 → ngboost-0.5.10.dev0}/PKG-INFO +1 -1
  2. {ngboost-0.5.9 → ngboost-0.5.10.dev0}/ngboost/__init__.py +8 -1
  3. ngboost-0.5.10.dev0/ngboost/helpers.py +137 -0
  4. {ngboost-0.5.9 → ngboost-0.5.10.dev0}/pyproject.toml +1 -1
  5. ngboost-0.5.9/ngboost/helpers.py +0 -23
  6. {ngboost-0.5.9 → ngboost-0.5.10.dev0}/LICENSE +0 -0
  7. {ngboost-0.5.9 → ngboost-0.5.10.dev0}/README.md +0 -0
  8. {ngboost-0.5.9 → ngboost-0.5.10.dev0}/ngboost/api.py +0 -0
  9. {ngboost-0.5.9 → ngboost-0.5.10.dev0}/ngboost/distns/__init__.py +0 -0
  10. {ngboost-0.5.9 → ngboost-0.5.10.dev0}/ngboost/distns/beta.py +0 -0
  11. {ngboost-0.5.9 → ngboost-0.5.10.dev0}/ngboost/distns/beta_bernoulli.py +0 -0
  12. {ngboost-0.5.9 → ngboost-0.5.10.dev0}/ngboost/distns/betabinomial.py +0 -0
  13. {ngboost-0.5.9 → ngboost-0.5.10.dev0}/ngboost/distns/categorical.py +0 -0
  14. {ngboost-0.5.9 → ngboost-0.5.10.dev0}/ngboost/distns/cauchy.py +0 -0
  15. {ngboost-0.5.9 → ngboost-0.5.10.dev0}/ngboost/distns/distn.py +0 -0
  16. {ngboost-0.5.9 → ngboost-0.5.10.dev0}/ngboost/distns/exponential.py +0 -0
  17. {ngboost-0.5.9 → ngboost-0.5.10.dev0}/ngboost/distns/gamma.py +0 -0
  18. {ngboost-0.5.9 → ngboost-0.5.10.dev0}/ngboost/distns/halfnormal.py +0 -0
  19. {ngboost-0.5.9 → ngboost-0.5.10.dev0}/ngboost/distns/laplace.py +0 -0
  20. {ngboost-0.5.9 → ngboost-0.5.10.dev0}/ngboost/distns/logitnormal.py +0 -0
  21. {ngboost-0.5.9 → ngboost-0.5.10.dev0}/ngboost/distns/lognormal.py +0 -0
  22. {ngboost-0.5.9 → ngboost-0.5.10.dev0}/ngboost/distns/multivariate_normal.py +0 -0
  23. {ngboost-0.5.9 → ngboost-0.5.10.dev0}/ngboost/distns/normal.py +0 -0
  24. {ngboost-0.5.9 → ngboost-0.5.10.dev0}/ngboost/distns/poisson.py +0 -0
  25. {ngboost-0.5.9 → ngboost-0.5.10.dev0}/ngboost/distns/sympy_utils.py +0 -0
  26. {ngboost-0.5.9 → ngboost-0.5.10.dev0}/ngboost/distns/t.py +0 -0
  27. {ngboost-0.5.9 → ngboost-0.5.10.dev0}/ngboost/distns/utils.py +0 -0
  28. {ngboost-0.5.9 → ngboost-0.5.10.dev0}/ngboost/distns/weibull.py +0 -0
  29. {ngboost-0.5.9 → ngboost-0.5.10.dev0}/ngboost/evaluation.py +0 -0
  30. {ngboost-0.5.9 → ngboost-0.5.10.dev0}/ngboost/learners.py +0 -0
  31. {ngboost-0.5.9 → ngboost-0.5.10.dev0}/ngboost/manifold.py +0 -0
  32. {ngboost-0.5.9 → ngboost-0.5.10.dev0}/ngboost/ngboost.py +0 -0
  33. {ngboost-0.5.9 → ngboost-0.5.10.dev0}/ngboost/scores.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: ngboost
3
- Version: 0.5.9
3
+ Version: 0.5.10.dev0
4
4
  Summary: Library for probabilistic predictions via gradient boosting.
5
5
  License: Apache-2.0
6
6
  Author: Stanford ML Group
@@ -7,8 +7,15 @@ except ImportError:
7
7
  from importlib_metadata import version
8
8
 
9
9
  from .api import NGBClassifier, NGBRegressor, NGBSurvival
10
+ from .helpers import load_ngboost_model
10
11
  from .ngboost import NGBoost
11
12
 
12
- __all__ = ["NGBClassifier", "NGBRegressor", "NGBSurvival", "NGBoost"]
13
+ __all__ = [
14
+ "NGBClassifier",
15
+ "NGBRegressor",
16
+ "NGBSurvival",
17
+ "NGBoost",
18
+ "load_ngboost_model",
19
+ ]
13
20
 
14
21
  __version__ = version(__name__)
@@ -0,0 +1,137 @@
1
+ import sys
2
+ import threading
3
+ import types as _types
4
+
5
+ import joblib
6
+ import numpy as np
7
+ import sklearn.tree._tree as _sklearn_tree # pylint: disable=c-extension-no-member
8
+ from sklearn.utils import check_array
9
+
10
+ # ---------------------------------------------------------------------------
11
+ # Backward compatibility helpers (issue #389)
12
+ # ---------------------------------------------------------------------------
13
+
14
+ _TREE_MODULE_SWAP_LOCK = threading.RLock()
15
+
16
+
17
+ class _CompatTree(_sklearn_tree.Tree): # pylint: disable=too-few-public-methods
18
+ """Transient subclass of sklearn's Tree used only during loading.
19
+
20
+ Overrides ``__setstate__`` to transparently inject the ``missing_go_to_left``
21
+ field that was added in scikit-learn 1.3, so that models pickled with older
22
+ sklearn can be loaded without raising ``ValueError``.
23
+ """
24
+
25
+ def __setstate__(self, state):
26
+ nodes = state.get("nodes")
27
+ if (
28
+ nodes is not None
29
+ and nodes.dtype.names is not None
30
+ and "missing_go_to_left" not in nodes.dtype.names
31
+ ):
32
+ new_dtype = np.dtype(nodes.dtype.descr + [("missing_go_to_left", "u1")])
33
+ new_nodes = np.zeros(nodes.shape, dtype=new_dtype)
34
+ for name in nodes.dtype.names:
35
+ new_nodes[name] = nodes[name]
36
+ new_nodes["missing_go_to_left"] = 1 # default: send missing values left
37
+ state = {**state, "nodes": new_nodes}
38
+ super().__setstate__(state)
39
+
40
+
41
+ def _make_compat_tree_module():
42
+ """Return a drop-in replacement for sklearn.tree._tree with Tree → _CompatTree."""
43
+ mod = _types.ModuleType("sklearn.tree._tree")
44
+ for _attr in dir(_sklearn_tree):
45
+ setattr(mod, _attr, getattr(_sklearn_tree, _attr))
46
+ mod.Tree = _CompatTree
47
+ return mod
48
+
49
+
50
+ def _to_proper_tree(compat_tree):
51
+ """Re-wrap a _CompatTree as a standard sklearn Tree (same state, proper type)."""
52
+ state = compat_tree.__getstate__()
53
+ n_classes = compat_tree.n_classes
54
+ if isinstance(n_classes, int):
55
+ n_classes = np.array([n_classes], dtype=np.intp)
56
+ proper = _sklearn_tree.Tree( # pylint: disable=c-extension-no-member
57
+ compat_tree.n_features, n_classes.copy(), compat_tree.n_outputs
58
+ )
59
+ proper.__setstate__(state)
60
+ return proper
61
+
62
+
63
+ def _fix_compat_trees(model):
64
+ """Replace every _CompatTree in model.base_models with a proper sklearn Tree."""
65
+ if not hasattr(model, "base_models"):
66
+ return
67
+ for iter_models in model.base_models:
68
+ for estimator in iter_models:
69
+ if hasattr(estimator, "tree_") and isinstance(estimator.tree_, _CompatTree):
70
+ estimator.tree_ = _to_proper_tree(estimator.tree_)
71
+
72
+
73
+ def load_ngboost_model(filepath):
74
+ """Load an NGBoost model with backward compatibility for older scikit-learn versions.
75
+
76
+ Scikit-learn 1.3 added a ``missing_go_to_left`` field to the internal node
77
+ structure of decision trees. Models trained and saved with scikit-learn < 1.3
78
+ do not contain this field, so loading them under scikit-learn >= 1.3 raises::
79
+
80
+ ValueError: node array from the pickle has an incompatible dtype
81
+
82
+ This function handles the incompatibility transparently by temporarily replacing
83
+ ``sklearn.tree._tree.Tree`` in ``sys.modules`` with a compatible subclass that
84
+ injects the missing field during ``__setstate__``. After loading, all trees are
85
+ converted back to standard sklearn ``Tree`` objects so that subsequent use and
86
+ re-serialisation behave normally.
87
+
88
+ Args:
89
+ filepath: Path to the saved model file (joblib or pickle format).
90
+
91
+ Returns:
92
+ The loaded NGBoost model.
93
+
94
+ Example::
95
+
96
+ from ngboost import load_ngboost_model
97
+ model = load_ngboost_model("my_old_model.pkl")
98
+ preds = model.predict(X)
99
+ """
100
+ with _TREE_MODULE_SWAP_LOCK:
101
+ compat_module = _make_compat_tree_module()
102
+ original_module = sys.modules.get("sklearn.tree._tree")
103
+ sys.modules["sklearn.tree._tree"] = compat_module
104
+ try:
105
+ model = joblib.load(filepath)
106
+ finally:
107
+ if original_module is None:
108
+ sys.modules.pop("sklearn.tree._tree", None)
109
+ else:
110
+ sys.modules["sklearn.tree._tree"] = original_module
111
+
112
+ _fix_compat_trees(model)
113
+ return model
114
+
115
+
116
+ # ---------------------------------------------------------------------------
117
+
118
+
119
+ def Y_from_censored(T, E=None):
120
+ if T is None:
121
+ return None
122
+ if T.dtype == [
123
+ ("Event", "?"),
124
+ ("Time", "<f8"),
125
+ ]: # already processed. Necessary for when d_score() calls score() as in LogNormalCRPScore
126
+ return T
127
+ T = check_array(T, ensure_2d=False)
128
+ T = T.reshape(T.shape[0])
129
+ if E is None:
130
+ E = np.ones_like(T)
131
+ else:
132
+ E = check_array(E, ensure_2d=False)
133
+ E = E.reshape(E.shape[0])
134
+ Y = np.empty(dtype=[("Event", np.bool_), ("Time", np.float64)], shape=T.shape[0])
135
+ Y["Event"] = E.astype(np.bool_)
136
+ Y["Time"] = T.astype(np.float64)
137
+ return Y
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "ngboost"
3
- version = "0.5.9"
3
+ version = "0.5.10dev"
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"
@@ -1,23 +0,0 @@
1
- import numpy as np
2
- from sklearn.utils import check_array
3
-
4
-
5
- def Y_from_censored(T, E=None):
6
- if T is None:
7
- return None
8
- if T.dtype == [
9
- ("Event", "?"),
10
- ("Time", "<f8"),
11
- ]: # already processed. Necessary for when d_score() calls score() as in LogNormalCRPScore
12
- return T
13
- T = check_array(T, ensure_2d=False)
14
- T = T.reshape(T.shape[0])
15
- if E is None:
16
- E = np.ones_like(T)
17
- else:
18
- E = check_array(E, ensure_2d=False)
19
- E = E.reshape(E.shape[0])
20
- Y = np.empty(dtype=[("Event", np.bool_), ("Time", np.float64)], shape=T.shape[0])
21
- Y["Event"] = E.astype(np.bool_)
22
- Y["Time"] = T.astype(np.float64)
23
- return Y
File without changes
File without changes
File without changes
File without changes