skpro 1.0.0b1__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.
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/__init__.py +10 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/__pycache__/__init__.cpython-35.pyc +0 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/__pycache__/base.cpython-35.pyc +0 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/__pycache__/density.cpython-35.pyc +0 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/__pycache__/ensemble.cpython-35.pyc +0 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/__pycache__/metrics.cpython-35.pyc +0 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/__pycache__/model_selection.cpython-35.pyc +0 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/__pycache__/utils.cpython-35.pyc +0 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/base.py +623 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/baselines/__init__.py +1 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/baselines/__pycache__/__init__.cpython-35.pyc +0 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/baselines/__pycache__/density.cpython-35.pyc +0 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/baselines/density.py +48 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/density.py +169 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/ensemble.py +86 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/metrics.py +219 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/model_selection.py +123 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/parametric/__init__.py +1 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/parametric/__pycache__/__init__.cpython-35.pyc +0 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/parametric/__pycache__/estimators.cpython-35.pyc +0 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/parametric/__pycache__/parametric.cpython-35.pyc +0 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/parametric/__pycache__/residuals.cpython-35.pyc +0 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/parametric/estimators.py +121 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/parametric/parametric.py +242 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/parametric/residuals.py +100 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/utils.py +66 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/vendors/__init__.py +0 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/vendors/__pycache__/__init__.cpython-35.pyc +0 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/vendors/__pycache__/pymc.cpython-35.pyc +0 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/vendors/pymc.py +49 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/workflow/__init__.py +1 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/workflow/__pycache__/__init__.cpython-35.pyc +0 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/workflow/__pycache__/base.cpython-35.pyc +0 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/workflow/__pycache__/cross_validation.cpython-35.pyc +0 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/workflow/__pycache__/utils.cpython-35.pyc +0 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/workflow/base.py +84 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/workflow/cross_validation.py +159 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/workflow/manager/__init__.py +2 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/workflow/manager/__pycache__/__init__.cpython-35.pyc +0 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/workflow/manager/__pycache__/data.cpython-35.pyc +0 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/workflow/manager/__pycache__/models.cpython-35.pyc +0 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/workflow/manager/data.py +178 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/workflow/manager/models.py +50 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/workflow/table/__init__.py +1 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/workflow/table/__pycache__/__init__.cpython-35.pyc +0 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/workflow/table/__pycache__/table.cpython-35.pyc +0 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/workflow/table/table.py +404 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/workflow/utils.py +60 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro-1.0.0b1-py3.5.egg-info/PKG-INFO +48 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro-1.0.0b1-py3.5.egg-info/SOURCES.txt +80 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro-1.0.0b1-py3.5.egg-info/dependency_links.txt +1 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro-1.0.0b1-py3.5.egg-info/not-zip-safe +1 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro-1.0.0b1-py3.5.egg-info/requires.txt +4 -0
- home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro-1.0.0b1-py3.5.egg-info/top_level.txt +1 -0
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,623 @@
|
|
|
1
|
+
import abc
|
|
2
|
+
import functools
|
|
3
|
+
import warnings
|
|
4
|
+
import numpy as np
|
|
5
|
+
|
|
6
|
+
from sklearn.base import BaseEstimator, clone
|
|
7
|
+
from .metrics import log_loss, make_scorer
|
|
8
|
+
from .density import DensityAdapter, KernelDensityAdapter
|
|
9
|
+
from .utils import ensure_existence
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def vectorvalued(f):
|
|
13
|
+
""" Decorates a distribution function to disable automatic vectorization.
|
|
14
|
+
|
|
15
|
+
Parameters
|
|
16
|
+
----------
|
|
17
|
+
f: The function to decorate
|
|
18
|
+
|
|
19
|
+
Returns
|
|
20
|
+
-------
|
|
21
|
+
Decorated function
|
|
22
|
+
"""
|
|
23
|
+
f.already_vectorized = True
|
|
24
|
+
return f
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _forward_meta(wrapper, f):
|
|
28
|
+
""" Forward meta information from decorated method to decoration
|
|
29
|
+
|
|
30
|
+
Parameters
|
|
31
|
+
----------
|
|
32
|
+
wrapper
|
|
33
|
+
f
|
|
34
|
+
|
|
35
|
+
Returns
|
|
36
|
+
-------
|
|
37
|
+
Method with meta information
|
|
38
|
+
"""
|
|
39
|
+
wrapper.already_vectorized = getattr(f, 'already_vectorized', False)
|
|
40
|
+
wrapper.non_existing = getattr(f, 'not_existing', False)
|
|
41
|
+
|
|
42
|
+
return wrapper
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _generalize(f):
|
|
46
|
+
""" Generalizes the signature to allow for the use with np.std() etc.
|
|
47
|
+
|
|
48
|
+
Parameters
|
|
49
|
+
----------
|
|
50
|
+
f: The function to decorate
|
|
51
|
+
|
|
52
|
+
Returns
|
|
53
|
+
-------
|
|
54
|
+
Decorated function
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
def wrapper(self, *args, **kwargs):
|
|
58
|
+
return f(self)
|
|
59
|
+
|
|
60
|
+
return _forward_meta(wrapper, f)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _vectorize(f):
|
|
64
|
+
""" Enables automatic vectorization of a function
|
|
65
|
+
|
|
66
|
+
The wrapper vectorizes a interface function unless
|
|
67
|
+
it is decorated with the vectorvalued decorator
|
|
68
|
+
|
|
69
|
+
Parameters
|
|
70
|
+
----------
|
|
71
|
+
f: The function to decorate
|
|
72
|
+
|
|
73
|
+
Returns
|
|
74
|
+
-------
|
|
75
|
+
Decorated function
|
|
76
|
+
"""
|
|
77
|
+
def wrapper(self, *args, **kwargs):
|
|
78
|
+
# cache index
|
|
79
|
+
index_ = self.index
|
|
80
|
+
self.index = slice(None)
|
|
81
|
+
|
|
82
|
+
if getattr(f, 'already_vectorized', False):
|
|
83
|
+
result = f(self, *args, **kwargs)
|
|
84
|
+
else:
|
|
85
|
+
result = []
|
|
86
|
+
for index in range(len(self.X)):
|
|
87
|
+
self.index = index
|
|
88
|
+
result.append(f(self, *args, **kwargs))
|
|
89
|
+
|
|
90
|
+
# rollback index
|
|
91
|
+
self.index = index_
|
|
92
|
+
|
|
93
|
+
if len(result) > 1:
|
|
94
|
+
return np.array(result)
|
|
95
|
+
else:
|
|
96
|
+
return result[0]
|
|
97
|
+
|
|
98
|
+
return _forward_meta(wrapper, f)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def _elementwise(f):
|
|
102
|
+
""" Enables elementwise operations
|
|
103
|
+
|
|
104
|
+
The wrapper implements two different modes of argument evaluation
|
|
105
|
+
for given p_1,..., p_k that represent the predicted distributions
|
|
106
|
+
and and x_1,...,x_m that represent the values to evaluate them on.
|
|
107
|
+
|
|
108
|
+
"elementwise" (default): Repeat the sequence of p_i until there are m,
|
|
109
|
+
i.e., p_1,...,p_k,p_1,p_2,...,p_k,p_1,...,p_m'
|
|
110
|
+
where m' is the remainder of dividing m by k.
|
|
111
|
+
|
|
112
|
+
"batch": x_1, ..., x_m is evaluated on every distribution p_i
|
|
113
|
+
resulting in a matrix m columns and k rows.
|
|
114
|
+
|
|
115
|
+
Parameters
|
|
116
|
+
----------
|
|
117
|
+
f: The function to decorate
|
|
118
|
+
|
|
119
|
+
Returns
|
|
120
|
+
-------
|
|
121
|
+
Decorated function
|
|
122
|
+
"""
|
|
123
|
+
|
|
124
|
+
def wrapper(self, x, *args, **kwargs):
|
|
125
|
+
if len(np.array(x).shape) > 1:
|
|
126
|
+
x = x.flatten()
|
|
127
|
+
|
|
128
|
+
# cache index
|
|
129
|
+
index_ = self.index
|
|
130
|
+
self.index = slice(None)
|
|
131
|
+
|
|
132
|
+
# disable elementwise mode if x is scalar
|
|
133
|
+
elementwise = (self.mode == 'elementwise' and len(np.array(x).shape) != 0)
|
|
134
|
+
|
|
135
|
+
if elementwise:
|
|
136
|
+
evaluations = len(x)
|
|
137
|
+
else:
|
|
138
|
+
evaluations = len(self.X)
|
|
139
|
+
|
|
140
|
+
# compose result
|
|
141
|
+
result = []
|
|
142
|
+
number_of_points = len(self.X)
|
|
143
|
+
for index in range(evaluations):
|
|
144
|
+
# set evaluation index and point
|
|
145
|
+
if elementwise:
|
|
146
|
+
self.index = index % number_of_points
|
|
147
|
+
at = x[index]
|
|
148
|
+
else:
|
|
149
|
+
self.index = index
|
|
150
|
+
at = x
|
|
151
|
+
|
|
152
|
+
# evaluate the function at this point
|
|
153
|
+
result.append(f(self, at, *args, **kwargs))
|
|
154
|
+
|
|
155
|
+
# rollback index
|
|
156
|
+
self.index = index_
|
|
157
|
+
|
|
158
|
+
if len(result) > 1:
|
|
159
|
+
return np.array(result)
|
|
160
|
+
else:
|
|
161
|
+
return result[0]
|
|
162
|
+
|
|
163
|
+
return _forward_meta(wrapper, f)
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def _cached(f):
|
|
167
|
+
""" Enables caching
|
|
168
|
+
|
|
169
|
+
Wrapper uses lru_cache to cache function result
|
|
170
|
+
|
|
171
|
+
Parameters
|
|
172
|
+
----------
|
|
173
|
+
f: The function to decorate
|
|
174
|
+
|
|
175
|
+
Returns
|
|
176
|
+
-------
|
|
177
|
+
Decorated function
|
|
178
|
+
"""
|
|
179
|
+
|
|
180
|
+
@functools.lru_cache()
|
|
181
|
+
def wrapper(self, *args, **kwargs):
|
|
182
|
+
return f(self, *args, **kwargs)
|
|
183
|
+
|
|
184
|
+
return _forward_meta(wrapper, f)
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
class ProbabilisticEstimator(BaseEstimator, metaclass=abc.ABCMeta):
|
|
188
|
+
""" Abstract base class for probabilistic prediction models
|
|
189
|
+
|
|
190
|
+
Notes
|
|
191
|
+
-----
|
|
192
|
+
All probabilistic estimators should specify all the parameters
|
|
193
|
+
that can be set at the class level in their ``__init__``
|
|
194
|
+
as explicit keyword arguments (no ``*args`` or ``**kwargs``).
|
|
195
|
+
"""
|
|
196
|
+
|
|
197
|
+
class ImplementsEnhancedInterface(abc.ABCMeta):
|
|
198
|
+
""" Meta-class for distribution interface
|
|
199
|
+
|
|
200
|
+
Enhances the distribution interface behind the scenes
|
|
201
|
+
with automatic caching and syntactic sugar for
|
|
202
|
+
element-wise access of the distributions
|
|
203
|
+
"""
|
|
204
|
+
|
|
205
|
+
def __init__(cls, name, bases, clsdict):
|
|
206
|
+
for method in ['pdf', 'cdf']:
|
|
207
|
+
if method in clsdict:
|
|
208
|
+
setattr(cls, method, _elementwise(ensure_existence(clsdict[method])))
|
|
209
|
+
|
|
210
|
+
for method in ['point', 'std', 'lp2']:
|
|
211
|
+
if method in clsdict:
|
|
212
|
+
setattr(cls, method, _cached(_vectorize(_generalize(ensure_existence(clsdict[method])))))
|
|
213
|
+
|
|
214
|
+
class Distribution(metaclass=ImplementsEnhancedInterface):
|
|
215
|
+
"""
|
|
216
|
+
Abstract base class for the distribution interface
|
|
217
|
+
returned by probabilistic estimators
|
|
218
|
+
|
|
219
|
+
Parameters
|
|
220
|
+
----------
|
|
221
|
+
estimator: ``skpro.base.ProbabilisticEstimator``
|
|
222
|
+
Parent probabilistic estimator object
|
|
223
|
+
X: np.array
|
|
224
|
+
Features
|
|
225
|
+
selection: slice | int (optional)
|
|
226
|
+
Subset point selection of the features
|
|
227
|
+
mode: str
|
|
228
|
+
Interface mode ('elementwise' or 'batch')
|
|
229
|
+
"""
|
|
230
|
+
|
|
231
|
+
def __init__(self, estimator, X, selection=slice(None), mode='elementwise'):
|
|
232
|
+
|
|
233
|
+
self.estimator = estimator
|
|
234
|
+
self._X = X
|
|
235
|
+
self.index = slice(None)
|
|
236
|
+
self.selection = selection
|
|
237
|
+
if mode not in ['elementwise', 'batch']:
|
|
238
|
+
mode = 'elementwise'
|
|
239
|
+
self.mode = mode
|
|
240
|
+
|
|
241
|
+
if callable(getattr(self, '_init', None)):
|
|
242
|
+
self._init()
|
|
243
|
+
|
|
244
|
+
@property
|
|
245
|
+
def X(self):
|
|
246
|
+
return self._X[self.selection, :][self.index]
|
|
247
|
+
|
|
248
|
+
@X.setter
|
|
249
|
+
def X(self, value):
|
|
250
|
+
self._X = value
|
|
251
|
+
|
|
252
|
+
def __len__(self):
|
|
253
|
+
shape = self.X.shape
|
|
254
|
+
return shape[0] if len(shape) > 1 else 1
|
|
255
|
+
|
|
256
|
+
def __setitem__(self, key, value):
|
|
257
|
+
raise Exception('skpro distributions are readonly')
|
|
258
|
+
|
|
259
|
+
def __delitem__(self, key):
|
|
260
|
+
raise Exception('skpro distributions are readonly')
|
|
261
|
+
|
|
262
|
+
def replicate(self, selection=None, mode=None):
|
|
263
|
+
""" Replicates the distribution object
|
|
264
|
+
|
|
265
|
+
Parameters
|
|
266
|
+
----------
|
|
267
|
+
selection: None | slice | int (optional)
|
|
268
|
+
Subset point selection of the distribution copy
|
|
269
|
+
mode: str (optional)
|
|
270
|
+
Interface mode ('elementwise' or 'batch')
|
|
271
|
+
|
|
272
|
+
Returns
|
|
273
|
+
-------
|
|
274
|
+
``skpro.base.ProbabilisticEstimator.Distribution``
|
|
275
|
+
"""
|
|
276
|
+
if selection is None:
|
|
277
|
+
selection = self.selection
|
|
278
|
+
|
|
279
|
+
if mode is None:
|
|
280
|
+
mode = self.mode
|
|
281
|
+
|
|
282
|
+
return self.__class__(self.estimator, self._X, selection, mode)
|
|
283
|
+
|
|
284
|
+
def __getitem__(self, key):
|
|
285
|
+
"""Returns a subset of the distribution object
|
|
286
|
+
|
|
287
|
+
Parameters
|
|
288
|
+
----------
|
|
289
|
+
- slice indexing, mode (optional)
|
|
290
|
+
- mode only (in which full subset is returned)
|
|
291
|
+
|
|
292
|
+
Returns
|
|
293
|
+
-------
|
|
294
|
+
``skpro.base.ProbabilisticEstimator.Distribution``
|
|
295
|
+
"""
|
|
296
|
+
|
|
297
|
+
# cache index
|
|
298
|
+
index_ = self.index
|
|
299
|
+
self.index = slice(None)
|
|
300
|
+
|
|
301
|
+
# parse key
|
|
302
|
+
if isinstance(key, tuple) and len(key) == 2:
|
|
303
|
+
selection = key[0]
|
|
304
|
+
mode = key[1]
|
|
305
|
+
elif isinstance(key, str):
|
|
306
|
+
selection = slice(None)
|
|
307
|
+
mode = key
|
|
308
|
+
else:
|
|
309
|
+
selection = key
|
|
310
|
+
mode = None
|
|
311
|
+
|
|
312
|
+
# convert index to slice for consistent usage
|
|
313
|
+
if isinstance(selection, int):
|
|
314
|
+
if selection >= len(self):
|
|
315
|
+
raise IndexError('Selection is out of bounds')
|
|
316
|
+
|
|
317
|
+
selection = slice(selection, selection+1)
|
|
318
|
+
|
|
319
|
+
# check for out of bounds subsets
|
|
320
|
+
if len(range(*selection.indices(len(self)))) == 0:
|
|
321
|
+
raise IndexError('Selection is out of bounds')
|
|
322
|
+
|
|
323
|
+
# create subset replication
|
|
324
|
+
replication = self.replicate(selection, mode)
|
|
325
|
+
|
|
326
|
+
# rollback index
|
|
327
|
+
self.index = index_
|
|
328
|
+
|
|
329
|
+
return replication
|
|
330
|
+
|
|
331
|
+
def __point__(self, name):
|
|
332
|
+
if len(self) > 1:
|
|
333
|
+
raise TypeError('Multiple distributions can not be converted to ' + name)
|
|
334
|
+
|
|
335
|
+
return self.point()
|
|
336
|
+
|
|
337
|
+
def __float__(self):
|
|
338
|
+
return float(self.__point__('float'))
|
|
339
|
+
|
|
340
|
+
def __int__(self):
|
|
341
|
+
return int(self.__point__('int'))
|
|
342
|
+
|
|
343
|
+
@abc.abstractmethod
|
|
344
|
+
def point(self):
|
|
345
|
+
""" Point prediction
|
|
346
|
+
|
|
347
|
+
Returns
|
|
348
|
+
-------
|
|
349
|
+
The point prediction that corresponds to self.X
|
|
350
|
+
"""
|
|
351
|
+
raise NotImplementedError()
|
|
352
|
+
|
|
353
|
+
@abc.abstractmethod
|
|
354
|
+
def std(self):
|
|
355
|
+
""" Variance prediction
|
|
356
|
+
|
|
357
|
+
Returns
|
|
358
|
+
-------
|
|
359
|
+
The estimated standard deviation that corresponds to self.X
|
|
360
|
+
"""
|
|
361
|
+
raise NotImplementedError()
|
|
362
|
+
|
|
363
|
+
def pdf(self, x):
|
|
364
|
+
""" Probability density function
|
|
365
|
+
|
|
366
|
+
Parameters
|
|
367
|
+
----------
|
|
368
|
+
x
|
|
369
|
+
|
|
370
|
+
Returns
|
|
371
|
+
-------
|
|
372
|
+
mixed Density function evaluated at x
|
|
373
|
+
"""
|
|
374
|
+
warnings.warn(self.__class__.__name__ + ' does not implement a pdf function', UserWarning)
|
|
375
|
+
|
|
376
|
+
def cdf(self, x):
|
|
377
|
+
""" Cumulative density function
|
|
378
|
+
|
|
379
|
+
Parameters
|
|
380
|
+
----------
|
|
381
|
+
x
|
|
382
|
+
|
|
383
|
+
Returns
|
|
384
|
+
-------
|
|
385
|
+
mixed Cumulative density function evaluated at x
|
|
386
|
+
"""
|
|
387
|
+
warnings.warn(self.__class__.__name__ + ' does not implement a cdf function', UserWarning)
|
|
388
|
+
|
|
389
|
+
def ppf(self, q, *args, **kwargs):
|
|
390
|
+
""" Percent point function (inverse of cdf — percentiles).
|
|
391
|
+
|
|
392
|
+
Parameters
|
|
393
|
+
----------
|
|
394
|
+
q
|
|
395
|
+
|
|
396
|
+
Returns
|
|
397
|
+
-------
|
|
398
|
+
float
|
|
399
|
+
"""
|
|
400
|
+
warnings.warn(self.__class__.__name__ + ' does not implement a ppf function', UserWarning)
|
|
401
|
+
|
|
402
|
+
def lp2(self):
|
|
403
|
+
"""
|
|
404
|
+
Implements the Lp2 norm of the probability density function
|
|
405
|
+
|
|
406
|
+
..math::
|
|
407
|
+
L^2 = \int PDF(x)^2 dx
|
|
408
|
+
|
|
409
|
+
Returns
|
|
410
|
+
-------
|
|
411
|
+
float: Lp2-norm of the density function
|
|
412
|
+
"""
|
|
413
|
+
warnings.warn(self.__class__.__name__ +
|
|
414
|
+
' does not implement a lp2 function, defaulting to numerical approximation', UserWarning)
|
|
415
|
+
|
|
416
|
+
from scipy.integrate import quad as integrate
|
|
417
|
+
# y, y_err of
|
|
418
|
+
return integrate(lambda x: self[self.index].pdf(x)**2, -np.inf, np.inf)[0]
|
|
419
|
+
|
|
420
|
+
def name(self):
|
|
421
|
+
return self.__class__.__name__
|
|
422
|
+
|
|
423
|
+
def __str__(self):
|
|
424
|
+
return '%s()' % self.__class__.__name__
|
|
425
|
+
|
|
426
|
+
def __repr__(self):
|
|
427
|
+
return '%s()' % self.__class__.__name__
|
|
428
|
+
|
|
429
|
+
@classmethod
|
|
430
|
+
def _distribution(cls):
|
|
431
|
+
return cls.Distribution
|
|
432
|
+
|
|
433
|
+
def predict(self, X):
|
|
434
|
+
return self._distribution()(self, X)
|
|
435
|
+
|
|
436
|
+
def fit(self, X, y):
|
|
437
|
+
warnings.warn('The estimator doesn\'t implement a fit procedure', UserWarning)
|
|
438
|
+
|
|
439
|
+
return self
|
|
440
|
+
|
|
441
|
+
def score(self, X, y, sample=True, return_std=False):
|
|
442
|
+
return make_scorer(log_loss, greater_is_better=False)(self, X, y, sample=sample, return_std=return_std)
|
|
443
|
+
|
|
444
|
+
|
|
445
|
+
###############################################################################
|
|
446
|
+
|
|
447
|
+
|
|
448
|
+
class VendorInterface(metaclass=abc.ABCMeta):
|
|
449
|
+
""" Abstract base class for a vendor interface
|
|
450
|
+
"""
|
|
451
|
+
|
|
452
|
+
def on_fit(self, X, y):
|
|
453
|
+
""" Implements vendor fit procedure
|
|
454
|
+
|
|
455
|
+
Parameters
|
|
456
|
+
----------
|
|
457
|
+
X : np.array
|
|
458
|
+
Training features
|
|
459
|
+
y : np.array
|
|
460
|
+
Training labels
|
|
461
|
+
|
|
462
|
+
Returns
|
|
463
|
+
-------
|
|
464
|
+
None
|
|
465
|
+
"""
|
|
466
|
+
pass
|
|
467
|
+
|
|
468
|
+
def on_predict(self, X):
|
|
469
|
+
""" Implements vendor predict procedure
|
|
470
|
+
|
|
471
|
+
Parameters
|
|
472
|
+
----------
|
|
473
|
+
X : np.array
|
|
474
|
+
Test features
|
|
475
|
+
|
|
476
|
+
Returns
|
|
477
|
+
-------
|
|
478
|
+
None
|
|
479
|
+
"""
|
|
480
|
+
pass
|
|
481
|
+
|
|
482
|
+
|
|
483
|
+
class VendorEstimator(ProbabilisticEstimator):
|
|
484
|
+
""" VendorEstimator
|
|
485
|
+
|
|
486
|
+
ProbabilisticEstimator that interfaces a vendor using
|
|
487
|
+
a VendorInterface and Adapter.
|
|
488
|
+
|
|
489
|
+
Parameters
|
|
490
|
+
----------
|
|
491
|
+
model: skpro.base.VendorInterface
|
|
492
|
+
Vendor interface
|
|
493
|
+
adapter: skpro.density.DensityAdapter
|
|
494
|
+
Density adapter
|
|
495
|
+
"""
|
|
496
|
+
|
|
497
|
+
class Distribution(ProbabilisticEstimator.Distribution, metaclass=abc.ABCMeta):
|
|
498
|
+
|
|
499
|
+
pass
|
|
500
|
+
|
|
501
|
+
def __init__(self, model=None, adapter=None):
|
|
502
|
+
self.model = self._check_model(model)
|
|
503
|
+
self.adapter = self._check_adapter(adapter)
|
|
504
|
+
|
|
505
|
+
def _check_model(self, model=None):
|
|
506
|
+
""" Checks the model
|
|
507
|
+
|
|
508
|
+
Checks if vendor interface is valid
|
|
509
|
+
|
|
510
|
+
Parameters
|
|
511
|
+
----------
|
|
512
|
+
model: skpro.base.VendorInterface
|
|
513
|
+
Vendor interface
|
|
514
|
+
Returns
|
|
515
|
+
-------
|
|
516
|
+
skpro.base.VendorInterface
|
|
517
|
+
"""
|
|
518
|
+
if not issubclass(model.__class__, VendorInterface):
|
|
519
|
+
raise ValueError('model has to be a VendorInterface'
|
|
520
|
+
'%s given.' % model.__class__)
|
|
521
|
+
|
|
522
|
+
return model
|
|
523
|
+
|
|
524
|
+
def _check_adapter(self, adapter):
|
|
525
|
+
""" Checks the adapter
|
|
526
|
+
|
|
527
|
+
Can be overwritten to implement checking procedures for a
|
|
528
|
+
density adapter that are applied during the object
|
|
529
|
+
initialisation.
|
|
530
|
+
|
|
531
|
+
Parameters
|
|
532
|
+
----------
|
|
533
|
+
adapter: skpro.density.DensityAdapter
|
|
534
|
+
Adapter
|
|
535
|
+
|
|
536
|
+
Returns
|
|
537
|
+
-------
|
|
538
|
+
skpro.density.DensityAdapter
|
|
539
|
+
"""
|
|
540
|
+
return adapter
|
|
541
|
+
|
|
542
|
+
def fit(self, X, y):
|
|
543
|
+
self.model.on_fit(X, y)
|
|
544
|
+
|
|
545
|
+
return self
|
|
546
|
+
|
|
547
|
+
def predict(self, X):
|
|
548
|
+
self.model.on_predict(X)
|
|
549
|
+
|
|
550
|
+
return super().predict(X)
|
|
551
|
+
|
|
552
|
+
|
|
553
|
+
class BayesianVendorInterface(VendorInterface):
|
|
554
|
+
""" Abstract base class for a Bayesian vendor
|
|
555
|
+
|
|
556
|
+
Notes
|
|
557
|
+
-----
|
|
558
|
+
Must implement the samples method that returns
|
|
559
|
+
Bayesian posterior samples. The sample method
|
|
560
|
+
should be cached using the ``functools.lru_cache``
|
|
561
|
+
decorator to increase performance
|
|
562
|
+
"""
|
|
563
|
+
|
|
564
|
+
@abc.abstractmethod
|
|
565
|
+
@functools.lru_cache()
|
|
566
|
+
def samples(self):
|
|
567
|
+
raise NotImplementedError()
|
|
568
|
+
|
|
569
|
+
|
|
570
|
+
class BayesianVendorEstimator(VendorEstimator):
|
|
571
|
+
""" Vendor estimator for Bayesian methods
|
|
572
|
+
|
|
573
|
+
ProbabilisticEstimator that interfaces a Bayesian vendor using
|
|
574
|
+
a BayesianVendorInterface and and sample-based Adapter.
|
|
575
|
+
|
|
576
|
+
"""
|
|
577
|
+
|
|
578
|
+
class Distribution(VendorEstimator.Distribution):
|
|
579
|
+
|
|
580
|
+
def _init(self):
|
|
581
|
+
# initialise adapter with samples
|
|
582
|
+
self.adapters_ = []
|
|
583
|
+
self.samples = self.estimator.model.samples()
|
|
584
|
+
for index in range(len(self.X)):
|
|
585
|
+
adapter = clone(self.estimator.adapter)
|
|
586
|
+
adapter(self.samples[index, :])
|
|
587
|
+
self.adapters_.append(adapter)
|
|
588
|
+
|
|
589
|
+
@vectorvalued
|
|
590
|
+
def point(self):
|
|
591
|
+
return self.samples.mean(axis=1)
|
|
592
|
+
|
|
593
|
+
@vectorvalued
|
|
594
|
+
def std(self):
|
|
595
|
+
return self.samples.std(axis=1)
|
|
596
|
+
|
|
597
|
+
def cdf(self, x):
|
|
598
|
+
ensure_existence(self.adapters_[self.index].cdf)
|
|
599
|
+
|
|
600
|
+
return self.adapters_[self.index].cdf(x)
|
|
601
|
+
|
|
602
|
+
def pdf(self, x):
|
|
603
|
+
ensure_existence(self.adapters_[self.index].pdf)
|
|
604
|
+
|
|
605
|
+
return self.adapters_[self.index].pdf(x)
|
|
606
|
+
|
|
607
|
+
def _check_model(self, model=None):
|
|
608
|
+
if not issubclass(model.__class__, BayesianVendorInterface):
|
|
609
|
+
raise ValueError('model has to be a subclass of skpro.base.BayesianVendorInterface'
|
|
610
|
+
'%s given.' % model.__class__)
|
|
611
|
+
|
|
612
|
+
return model
|
|
613
|
+
|
|
614
|
+
def _check_adapter(self, adapter=None):
|
|
615
|
+
if adapter is None:
|
|
616
|
+
# default adapter
|
|
617
|
+
adapter = KernelDensityAdapter()
|
|
618
|
+
|
|
619
|
+
if not issubclass(adapter.__class__, DensityAdapter):
|
|
620
|
+
raise ValueError('adapter has to be a subclass of skpro.density.DensityAdapter'
|
|
621
|
+
'%s given.' % adapter.__class__)
|
|
622
|
+
|
|
623
|
+
return adapter
|
home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/baselines/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .density import DensityBaseline
|
|
Binary file
|
|
Binary file
|
home/frithjof/Code/Python/environments/skpro/lib/python3.5/site-packages/skpro/baselines/density.py
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from ..base import ProbabilisticEstimator, vectorvalued
|
|
4
|
+
from ..density import DensityAdapter, KernelDensityAdapter
|
|
5
|
+
from ..utils import ensure_existence
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class DensityBaseline(ProbabilisticEstimator):
|
|
9
|
+
|
|
10
|
+
class Distribution(ProbabilisticEstimator.Distribution):
|
|
11
|
+
|
|
12
|
+
@vectorvalued
|
|
13
|
+
def point(self):
|
|
14
|
+
return np.ones((len(self.X), )) * self.estimator.training_mean_
|
|
15
|
+
|
|
16
|
+
@vectorvalued
|
|
17
|
+
def std(self):
|
|
18
|
+
return np.ones((len(self.X), )) * self.estimator.training_std_
|
|
19
|
+
|
|
20
|
+
def cdf(self, x):
|
|
21
|
+
ensure_existence(self.estimator.adapter.cdf)
|
|
22
|
+
|
|
23
|
+
return self.estimator.adapter.cdf(x)
|
|
24
|
+
|
|
25
|
+
def pdf(self, x):
|
|
26
|
+
ensure_existence(self.estimator.adapter.pdf)
|
|
27
|
+
|
|
28
|
+
return self.estimator.adapter.pdf(x)
|
|
29
|
+
|
|
30
|
+
def __init__(self, adapter=None):
|
|
31
|
+
if adapter is None:
|
|
32
|
+
adapter = KernelDensityAdapter()
|
|
33
|
+
|
|
34
|
+
if not issubclass(adapter.__class__, DensityAdapter):
|
|
35
|
+
raise ValueError('adapter has to be a subclass of skpro.density.DensityAdapter'
|
|
36
|
+
'%s given.' % adapter.__class__)
|
|
37
|
+
|
|
38
|
+
self.adapter = adapter
|
|
39
|
+
self.training_mean_ = None
|
|
40
|
+
self.training_std_ = None
|
|
41
|
+
|
|
42
|
+
def fit(self, X, y):
|
|
43
|
+
# Use the labels to estimate the density
|
|
44
|
+
self.adapter(y)
|
|
45
|
+
self.training_mean_ = np.mean(y)
|
|
46
|
+
self.training_std_ = np.std(y)
|
|
47
|
+
|
|
48
|
+
return self
|