scikit-survival 0.25.0__cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
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.
- scikit_survival-0.25.0.dist-info/METADATA +185 -0
- scikit_survival-0.25.0.dist-info/RECORD +58 -0
- scikit_survival-0.25.0.dist-info/WHEEL +6 -0
- scikit_survival-0.25.0.dist-info/licenses/COPYING +674 -0
- scikit_survival-0.25.0.dist-info/top_level.txt +1 -0
- sksurv/__init__.py +183 -0
- sksurv/base.py +115 -0
- sksurv/bintrees/__init__.py +15 -0
- sksurv/bintrees/_binarytrees.cpython-311-x86_64-linux-gnu.so +0 -0
- sksurv/column.py +205 -0
- sksurv/compare.py +123 -0
- sksurv/datasets/__init__.py +12 -0
- sksurv/datasets/base.py +614 -0
- sksurv/datasets/data/GBSG2.arff +700 -0
- sksurv/datasets/data/actg320.arff +1169 -0
- sksurv/datasets/data/bmt.arff +46 -0
- sksurv/datasets/data/breast_cancer_GSE7390-metastasis.arff +283 -0
- sksurv/datasets/data/cgvhd.arff +118 -0
- sksurv/datasets/data/flchain.arff +7887 -0
- sksurv/datasets/data/veteran.arff +148 -0
- sksurv/datasets/data/whas500.arff +520 -0
- sksurv/docstrings.py +99 -0
- sksurv/ensemble/__init__.py +2 -0
- sksurv/ensemble/_coxph_loss.cpython-311-x86_64-linux-gnu.so +0 -0
- sksurv/ensemble/boosting.py +1564 -0
- sksurv/ensemble/forest.py +902 -0
- sksurv/ensemble/survival_loss.py +151 -0
- sksurv/exceptions.py +18 -0
- sksurv/functions.py +114 -0
- sksurv/io/__init__.py +2 -0
- sksurv/io/arffread.py +89 -0
- sksurv/io/arffwrite.py +181 -0
- sksurv/kernels/__init__.py +1 -0
- sksurv/kernels/_clinical_kernel.cpython-311-x86_64-linux-gnu.so +0 -0
- sksurv/kernels/clinical.py +348 -0
- sksurv/linear_model/__init__.py +3 -0
- sksurv/linear_model/_coxnet.cpython-311-x86_64-linux-gnu.so +0 -0
- sksurv/linear_model/aft.py +208 -0
- sksurv/linear_model/coxnet.py +592 -0
- sksurv/linear_model/coxph.py +637 -0
- sksurv/meta/__init__.py +4 -0
- sksurv/meta/base.py +35 -0
- sksurv/meta/ensemble_selection.py +724 -0
- sksurv/meta/stacking.py +370 -0
- sksurv/metrics.py +1028 -0
- sksurv/nonparametric.py +911 -0
- sksurv/preprocessing.py +183 -0
- sksurv/svm/__init__.py +11 -0
- sksurv/svm/_minlip.cpython-311-x86_64-linux-gnu.so +0 -0
- sksurv/svm/_prsvm.cpython-311-x86_64-linux-gnu.so +0 -0
- sksurv/svm/minlip.py +690 -0
- sksurv/svm/naive_survival_svm.py +249 -0
- sksurv/svm/survival_svm.py +1236 -0
- sksurv/testing.py +108 -0
- sksurv/tree/__init__.py +1 -0
- sksurv/tree/_criterion.cpython-311-x86_64-linux-gnu.so +0 -0
- sksurv/tree/tree.py +790 -0
- sksurv/util.py +415 -0
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
# This program is free software: you can redistribute it and/or modify
|
|
2
|
+
# it under the terms of the GNU General Public License as published by
|
|
3
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
4
|
+
# (at your option) any later version.
|
|
5
|
+
#
|
|
6
|
+
# This program is distributed in the hope that it will be useful,
|
|
7
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
8
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
9
|
+
# GNU General Public License for more details.
|
|
10
|
+
#
|
|
11
|
+
# You should have received a copy of the GNU General Public License
|
|
12
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
13
|
+
import numpy as np
|
|
14
|
+
import pandas as pd
|
|
15
|
+
from pandas.api.types import CategoricalDtype, is_numeric_dtype
|
|
16
|
+
from sklearn.base import BaseEstimator, TransformerMixin
|
|
17
|
+
from sklearn.utils.validation import _check_feature_names, _check_n_features, check_is_fitted
|
|
18
|
+
|
|
19
|
+
from ._clinical_kernel import (
|
|
20
|
+
continuous_ordinal_kernel,
|
|
21
|
+
continuous_ordinal_kernel_with_ranges,
|
|
22
|
+
pairwise_continuous_ordinal_kernel,
|
|
23
|
+
pairwise_nominal_kernel,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
__all__ = ["clinical_kernel", "ClinicalKernelTransform"]
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _nominal_kernel(x, y, out):
|
|
30
|
+
"""Number of features that match exactly"""
|
|
31
|
+
for i in range(x.shape[0]):
|
|
32
|
+
for j in range(y.shape[0]):
|
|
33
|
+
out[i, j] += (x[i, :] == y[j, :]).sum()
|
|
34
|
+
|
|
35
|
+
return out
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _get_continuous_and_ordinal_array(x):
|
|
39
|
+
"""Convert array from continuous and ordered categorical columns"""
|
|
40
|
+
nominal_columns = x.select_dtypes(include=["object", "category"]).columns
|
|
41
|
+
ordinal_columns = pd.Index([v for v in nominal_columns if x[v].cat.ordered])
|
|
42
|
+
continuous_columns = x.select_dtypes(include=[np.number]).columns
|
|
43
|
+
|
|
44
|
+
x_num = x.loc[:, continuous_columns].astype(np.float64).values
|
|
45
|
+
if len(ordinal_columns) > 0:
|
|
46
|
+
x = _ordinal_as_numeric(x, ordinal_columns)
|
|
47
|
+
|
|
48
|
+
nominal_columns = nominal_columns.difference(ordinal_columns)
|
|
49
|
+
x_out = np.column_stack((x_num, x))
|
|
50
|
+
else:
|
|
51
|
+
x_out = x_num
|
|
52
|
+
|
|
53
|
+
return x_out, nominal_columns
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _ordinal_as_numeric(x, ordinal_columns):
|
|
57
|
+
x_numeric = np.empty((x.shape[0], len(ordinal_columns)), dtype=np.float64)
|
|
58
|
+
|
|
59
|
+
for i, c in enumerate(ordinal_columns):
|
|
60
|
+
x_numeric[:, i] = x[c].cat.codes
|
|
61
|
+
return x_numeric
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def clinical_kernel(x, y=None):
|
|
65
|
+
"""Computes clinical kernel.
|
|
66
|
+
|
|
67
|
+
The clinical kernel distinguishes between continuous
|
|
68
|
+
ordinal, and nominal variables.
|
|
69
|
+
Kernel values are normalized to lie within [0, 1].
|
|
70
|
+
|
|
71
|
+
See [1]_ for further description.
|
|
72
|
+
|
|
73
|
+
Parameters
|
|
74
|
+
----------
|
|
75
|
+
x : pandas.DataFrame, shape = (n_samples_x, n_features)
|
|
76
|
+
Training data
|
|
77
|
+
|
|
78
|
+
y : pandas.DataFrame, shape = (n_samples_y, n_features)
|
|
79
|
+
Testing data
|
|
80
|
+
|
|
81
|
+
Returns
|
|
82
|
+
-------
|
|
83
|
+
kernel : array, shape = (n_samples_x, n_samples_y)
|
|
84
|
+
Kernel matrix.
|
|
85
|
+
|
|
86
|
+
References
|
|
87
|
+
----------
|
|
88
|
+
.. [1] Daemen, A., De Moor, B.,
|
|
89
|
+
"Development of a kernel function for clinical data".
|
|
90
|
+
Annual International Conference of the IEEE Engineering in Medicine and Biology Society, 5913-7, 2009
|
|
91
|
+
|
|
92
|
+
Examples
|
|
93
|
+
--------
|
|
94
|
+
>>> import pandas as pd
|
|
95
|
+
>>> from sksurv.kernels import clinical_kernel
|
|
96
|
+
>>>
|
|
97
|
+
>>> data = pd.DataFrame({
|
|
98
|
+
... 'feature_num': [1.0, 2.0, 3.0],
|
|
99
|
+
... 'feature_ord': pd.Categorical(['low', 'medium', 'high'], ordered=True),
|
|
100
|
+
... 'feature_nom': pd.Categorical(['A', 'B', 'A'])
|
|
101
|
+
... })
|
|
102
|
+
>>>
|
|
103
|
+
>>> kernel_matrix = clinical_kernel(data)
|
|
104
|
+
>>> print(kernel_matrix)
|
|
105
|
+
[[1. 0.33333333 0.5 ]
|
|
106
|
+
[0.33333333 1. 0.16666667]
|
|
107
|
+
[0.5 0.16666667 1. ]]
|
|
108
|
+
"""
|
|
109
|
+
if y is not None:
|
|
110
|
+
if x.shape[1] != y.shape[1]:
|
|
111
|
+
raise ValueError("x and y have different number of features")
|
|
112
|
+
if not x.columns.equals(y.columns):
|
|
113
|
+
raise ValueError("columns do not match")
|
|
114
|
+
else:
|
|
115
|
+
y = x
|
|
116
|
+
|
|
117
|
+
mat = np.zeros((x.shape[0], y.shape[0]), dtype=float)
|
|
118
|
+
|
|
119
|
+
x_numeric, nominal_columns = _get_continuous_and_ordinal_array(x)
|
|
120
|
+
if id(x) != id(y):
|
|
121
|
+
y_numeric, _ = _get_continuous_and_ordinal_array(y)
|
|
122
|
+
else:
|
|
123
|
+
y_numeric = x_numeric
|
|
124
|
+
|
|
125
|
+
continuous_ordinal_kernel(x_numeric, y_numeric, mat)
|
|
126
|
+
_nominal_kernel(x.loc[:, nominal_columns].values, y.loc[:, nominal_columns].values, mat)
|
|
127
|
+
mat /= x.shape[1]
|
|
128
|
+
return mat
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
class ClinicalKernelTransform(BaseEstimator, TransformerMixin):
|
|
132
|
+
"""Transform data using a clinical Kernel
|
|
133
|
+
|
|
134
|
+
The clinical kernel distinguishes between continuous
|
|
135
|
+
ordinal, and nominal variables.
|
|
136
|
+
|
|
137
|
+
See [1]_ for further description.
|
|
138
|
+
|
|
139
|
+
Parameters
|
|
140
|
+
----------
|
|
141
|
+
fit_once : bool, optional
|
|
142
|
+
If set to ``True``, fit() does only transform the training data, but not update
|
|
143
|
+
its internal state. You should call prepare() once before calling transform().
|
|
144
|
+
If set to ``False``, it behaves like a regular estimator, i.e., you need to
|
|
145
|
+
call fit() before transform().
|
|
146
|
+
|
|
147
|
+
Attributes
|
|
148
|
+
----------
|
|
149
|
+
n_features_in_ : int
|
|
150
|
+
Number of features seen during ``fit``.
|
|
151
|
+
|
|
152
|
+
feature_names_in_ : ndarray, shape = (`n_features_in_`,)
|
|
153
|
+
Names of features seen during ``fit``. Defined only when `X`
|
|
154
|
+
has feature names that are all strings.
|
|
155
|
+
|
|
156
|
+
References
|
|
157
|
+
----------
|
|
158
|
+
.. [1] Daemen, A., De Moor, B.,
|
|
159
|
+
"Development of a kernel function for clinical data".
|
|
160
|
+
Annual International Conference of the IEEE Engineering in Medicine and Biology Society, 5913-7, 2009
|
|
161
|
+
"""
|
|
162
|
+
|
|
163
|
+
def __init__(self, *, fit_once=False, _numeric_ranges=None, _numeric_columns=None, _nominal_columns=None):
|
|
164
|
+
self.fit_once = fit_once
|
|
165
|
+
|
|
166
|
+
self._numeric_ranges = _numeric_ranges
|
|
167
|
+
self._numeric_columns = _numeric_columns
|
|
168
|
+
self._nominal_columns = _nominal_columns
|
|
169
|
+
|
|
170
|
+
def prepare(self, X):
|
|
171
|
+
"""Determine transformation parameters from data in X.
|
|
172
|
+
|
|
173
|
+
Use if `fit_once` is `True`, in which case `fit()` does
|
|
174
|
+
not set the parameters of the clinical kernel.
|
|
175
|
+
|
|
176
|
+
Parameters
|
|
177
|
+
----------
|
|
178
|
+
X: pandas.DataFrame, shape = (n_samples, n_features)
|
|
179
|
+
Data to estimate parameters from.
|
|
180
|
+
"""
|
|
181
|
+
if not self.fit_once:
|
|
182
|
+
raise ValueError("prepare can only be used if fit_once parameter is set to True")
|
|
183
|
+
|
|
184
|
+
self._prepare_by_column_dtype(X)
|
|
185
|
+
|
|
186
|
+
def _prepare_by_column_dtype(self, X):
|
|
187
|
+
"""Get distance functions for each column's dtype"""
|
|
188
|
+
if not isinstance(X, pd.DataFrame):
|
|
189
|
+
raise TypeError("X must be a pandas DataFrame")
|
|
190
|
+
|
|
191
|
+
numeric_columns = []
|
|
192
|
+
nominal_columns = []
|
|
193
|
+
numeric_ranges = []
|
|
194
|
+
|
|
195
|
+
fit_data = np.empty(X.shape, dtype=np.float64)
|
|
196
|
+
|
|
197
|
+
for i, dt in enumerate(X.dtypes):
|
|
198
|
+
col = X.iloc[:, i]
|
|
199
|
+
if isinstance(dt, CategoricalDtype):
|
|
200
|
+
if col.cat.ordered:
|
|
201
|
+
numeric_ranges.append(col.cat.codes.max() - col.cat.codes.min())
|
|
202
|
+
numeric_columns.append(i)
|
|
203
|
+
else:
|
|
204
|
+
nominal_columns.append(i)
|
|
205
|
+
|
|
206
|
+
col = col.cat.codes
|
|
207
|
+
elif is_numeric_dtype(dt):
|
|
208
|
+
numeric_ranges.append(col.max() - col.min())
|
|
209
|
+
numeric_columns.append(i)
|
|
210
|
+
else:
|
|
211
|
+
raise TypeError(f"unsupported dtype: {dt!r}")
|
|
212
|
+
|
|
213
|
+
fit_data[:, i] = col.values
|
|
214
|
+
|
|
215
|
+
self._numeric_columns = np.asarray(numeric_columns)
|
|
216
|
+
self._nominal_columns = np.asarray(nominal_columns)
|
|
217
|
+
self._numeric_ranges = np.asarray(numeric_ranges, dtype=float)
|
|
218
|
+
self.X_fit_ = fit_data
|
|
219
|
+
|
|
220
|
+
def fit(self, X, y=None, **kwargs): # pylint: disable=unused-argument
|
|
221
|
+
"""Determine transformation parameters from data in X.
|
|
222
|
+
|
|
223
|
+
Subsequent calls to `transform(Y)` compute the pairwise
|
|
224
|
+
distance to `X`.
|
|
225
|
+
Parameters of the clinical kernel are only updated
|
|
226
|
+
if `fit_once` is `False`, otherwise you have to
|
|
227
|
+
explicitly call `prepare()` once.
|
|
228
|
+
|
|
229
|
+
Parameters
|
|
230
|
+
----------
|
|
231
|
+
X: pandas.DataFrame, shape = (n_samples, n_features)
|
|
232
|
+
Data to estimate parameters from.
|
|
233
|
+
|
|
234
|
+
y : None
|
|
235
|
+
Ignored. This parameter exists only for compatibility with
|
|
236
|
+
:class:`sklearn.pipeline.Pipeline`.
|
|
237
|
+
|
|
238
|
+
kwargs : dict
|
|
239
|
+
Ignored. This parameter exists only for compatibility with
|
|
240
|
+
:class:`sklearn.pipeline.Pipeline`.
|
|
241
|
+
|
|
242
|
+
Returns
|
|
243
|
+
-------
|
|
244
|
+
self : object
|
|
245
|
+
Returns the instance itself.
|
|
246
|
+
"""
|
|
247
|
+
if X.ndim != 2:
|
|
248
|
+
raise ValueError(f"expected 2d array, but got {X.ndim}")
|
|
249
|
+
|
|
250
|
+
_check_feature_names(self, X, reset=True)
|
|
251
|
+
_check_n_features(self, X, reset=True)
|
|
252
|
+
|
|
253
|
+
if self.fit_once:
|
|
254
|
+
self.X_fit_ = X
|
|
255
|
+
else:
|
|
256
|
+
self._prepare_by_column_dtype(X)
|
|
257
|
+
|
|
258
|
+
return self
|
|
259
|
+
|
|
260
|
+
def transform(self, Y):
|
|
261
|
+
r"""Compute all pairwise distances between `self.X_fit_` and `Y`.
|
|
262
|
+
|
|
263
|
+
Parameters
|
|
264
|
+
----------
|
|
265
|
+
Y : array-like, shape = (n_samples_y, n_features)
|
|
266
|
+
|
|
267
|
+
Returns
|
|
268
|
+
-------
|
|
269
|
+
kernel : ndarray, shape = (n_samples_y, n_samples_X_fit\_)
|
|
270
|
+
Kernel matrix. Values are normalized to lie within [0, 1].
|
|
271
|
+
"""
|
|
272
|
+
check_is_fitted(self, "X_fit_")
|
|
273
|
+
|
|
274
|
+
_check_feature_names(self, Y, reset=False)
|
|
275
|
+
_check_n_features(self, Y, reset=False)
|
|
276
|
+
|
|
277
|
+
n_samples_x = self.X_fit_.shape[0]
|
|
278
|
+
|
|
279
|
+
Y = np.asarray(Y)
|
|
280
|
+
|
|
281
|
+
n_samples_y = Y.shape[0]
|
|
282
|
+
|
|
283
|
+
mat = np.zeros((n_samples_y, n_samples_x), dtype=float)
|
|
284
|
+
|
|
285
|
+
continuous_ordinal_kernel_with_ranges(
|
|
286
|
+
Y[:, self._numeric_columns].astype(np.float64),
|
|
287
|
+
self.X_fit_[:, self._numeric_columns].astype(np.float64),
|
|
288
|
+
self._numeric_ranges,
|
|
289
|
+
mat,
|
|
290
|
+
)
|
|
291
|
+
|
|
292
|
+
if len(self._nominal_columns) > 0:
|
|
293
|
+
_nominal_kernel(Y[:, self._nominal_columns], self.X_fit_[:, self._nominal_columns], mat)
|
|
294
|
+
|
|
295
|
+
mat /= self.n_features_in_
|
|
296
|
+
|
|
297
|
+
return mat
|
|
298
|
+
|
|
299
|
+
def __call__(self, X, Y):
|
|
300
|
+
"""Compute Kernel matrix between `X` and `Y`.
|
|
301
|
+
|
|
302
|
+
Parameters
|
|
303
|
+
----------
|
|
304
|
+
x : pandas.DataFrame, shape = (n_samples_x, n_features)
|
|
305
|
+
Training data
|
|
306
|
+
|
|
307
|
+
y : pandas.DataFrame, shape = (n_samples_y, n_features)
|
|
308
|
+
Testing data
|
|
309
|
+
|
|
310
|
+
Returns
|
|
311
|
+
-------
|
|
312
|
+
kernel : ndarray, shape = (n_samples_x, n_samples_y)
|
|
313
|
+
Kernel matrix. Values are normalized to lie within [0, 1].
|
|
314
|
+
"""
|
|
315
|
+
return self.fit(X).transform(Y).T
|
|
316
|
+
|
|
317
|
+
def pairwise_kernel(self, X, Y):
|
|
318
|
+
"""Function to use with :func:`sklearn.metrics.pairwise.pairwise_kernels`.
|
|
319
|
+
|
|
320
|
+
Parameters
|
|
321
|
+
----------
|
|
322
|
+
X : ndarray, shape = (n_features,)
|
|
323
|
+
|
|
324
|
+
Y : ndarray, shape = (n_features,)
|
|
325
|
+
|
|
326
|
+
Returns
|
|
327
|
+
-------
|
|
328
|
+
similarity : float
|
|
329
|
+
Similarities are normalized to be within [0, 1].
|
|
330
|
+
"""
|
|
331
|
+
check_is_fitted(self, "X_fit_")
|
|
332
|
+
if X.shape[0] != Y.shape[0]:
|
|
333
|
+
raise ValueError(
|
|
334
|
+
f"Incompatible dimension for X and Y matrices: X.shape[0] == {X.shape[0]} "
|
|
335
|
+
f"while Y.shape[0] == {Y.shape[0]}"
|
|
336
|
+
)
|
|
337
|
+
|
|
338
|
+
val = pairwise_continuous_ordinal_kernel(
|
|
339
|
+
X[self._numeric_columns], Y[self._numeric_columns], self._numeric_ranges
|
|
340
|
+
)
|
|
341
|
+
if len(self._nominal_columns) > 0:
|
|
342
|
+
val += pairwise_nominal_kernel(
|
|
343
|
+
X[self._nominal_columns].astype(np.int8), Y[self._nominal_columns].astype(np.int8)
|
|
344
|
+
)
|
|
345
|
+
|
|
346
|
+
val /= X.shape[0]
|
|
347
|
+
|
|
348
|
+
return val
|
|
Binary file
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
# This program is free software: you can redistribute it and/or modify
|
|
2
|
+
# it under the terms of the GNU General Public License as published by
|
|
3
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
4
|
+
# (at your option) any later version.
|
|
5
|
+
#
|
|
6
|
+
# This program is distributed in the hope that it will be useful,
|
|
7
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
8
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
9
|
+
# GNU General Public License for more details.
|
|
10
|
+
#
|
|
11
|
+
# You should have received a copy of the GNU General Public License
|
|
12
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
13
|
+
import numpy as np
|
|
14
|
+
from sklearn.linear_model import Ridge
|
|
15
|
+
|
|
16
|
+
from ..base import SurvivalAnalysisMixin
|
|
17
|
+
from ..nonparametric import ipc_weights
|
|
18
|
+
from ..util import check_array_survival
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class IPCRidge(Ridge, SurvivalAnalysisMixin):
|
|
22
|
+
r"""Accelerated failure time model with inverse probability of censoring weights.
|
|
23
|
+
|
|
24
|
+
This model assumes a regression model of the form
|
|
25
|
+
|
|
26
|
+
.. math::
|
|
27
|
+
|
|
28
|
+
\log y = \beta_0 + \mathbf{X} \beta + \epsilon
|
|
29
|
+
|
|
30
|
+
L2-shrinkage is applied to the coefficients :math:`\beta` and
|
|
31
|
+
each sample is weighted by the inverse probability of censoring
|
|
32
|
+
to account for right censoring (under the assumption that
|
|
33
|
+
censoring is independent of the features, i.e., random censoring).
|
|
34
|
+
|
|
35
|
+
See [1]_ for further description.
|
|
36
|
+
|
|
37
|
+
Parameters
|
|
38
|
+
----------
|
|
39
|
+
alpha : float, optional, default: 1.0
|
|
40
|
+
Small positive values of alpha improve the conditioning of the problem
|
|
41
|
+
and reduce the variance of the estimates.
|
|
42
|
+
`alpha` must be a non-negative float i.e. in `[0, inf)`.
|
|
43
|
+
|
|
44
|
+
For numerical reasons, using `alpha = 0` is not advised.
|
|
45
|
+
|
|
46
|
+
fit_intercept : bool, default: True
|
|
47
|
+
Whether to fit the intercept for this model. If set
|
|
48
|
+
to false, no intercept will be used in calculations
|
|
49
|
+
(i.e. ``X`` and ``y`` are expected to be centered).
|
|
50
|
+
|
|
51
|
+
copy_X : bool, default: True
|
|
52
|
+
If True, X will be copied; else, it may be overwritten.
|
|
53
|
+
|
|
54
|
+
max_iter : int, default: None
|
|
55
|
+
Maximum number of iterations for conjugate gradient solver.
|
|
56
|
+
For 'sparse_cg' and 'lsqr' solvers, the default value is determined
|
|
57
|
+
by scipy.sparse.linalg. For 'sag' solver, the default value is 1000.
|
|
58
|
+
For 'lbfgs' solver, the default value is 15000.
|
|
59
|
+
|
|
60
|
+
tol : float, default: 1e-3
|
|
61
|
+
Precision of the solution. Note that `tol` has no effect for solvers 'svd' and
|
|
62
|
+
'cholesky'.
|
|
63
|
+
|
|
64
|
+
solver : {'auto', 'svd', 'cholesky', 'lsqr', 'sparse_cg', \
|
|
65
|
+
'sag', 'saga', 'lbfgs'}, default: 'auto'
|
|
66
|
+
Solver to use in the computational routines:
|
|
67
|
+
|
|
68
|
+
- 'auto' chooses the solver automatically based on the type of data.
|
|
69
|
+
|
|
70
|
+
- 'svd' uses a Singular Value Decomposition of X to compute the Ridge
|
|
71
|
+
coefficients. It is the most stable solver, in particular more stable
|
|
72
|
+
for singular matrices than 'cholesky' at the cost of being slower.
|
|
73
|
+
|
|
74
|
+
- 'cholesky' uses the standard scipy.linalg.solve function to
|
|
75
|
+
obtain a closed-form solution.
|
|
76
|
+
|
|
77
|
+
- 'sparse_cg' uses the conjugate gradient solver as found in
|
|
78
|
+
scipy.sparse.linalg.cg. As an iterative algorithm, this solver is
|
|
79
|
+
more appropriate than 'cholesky' for large-scale data
|
|
80
|
+
(possibility to set `tol` and `max_iter`).
|
|
81
|
+
|
|
82
|
+
- 'lsqr' uses the dedicated regularized least-squares routine
|
|
83
|
+
scipy.sparse.linalg.lsqr. It is the fastest and uses an iterative
|
|
84
|
+
procedure.
|
|
85
|
+
|
|
86
|
+
- 'sag' uses a Stochastic Average Gradient descent, and 'saga' uses
|
|
87
|
+
its improved, unbiased version named SAGA. Both methods also use an
|
|
88
|
+
iterative procedure, and are often faster than other solvers when
|
|
89
|
+
both n_samples and n_features are large. Note that 'sag' and
|
|
90
|
+
'saga' fast convergence is only guaranteed on features with
|
|
91
|
+
approximately the same scale. You can preprocess the data with a
|
|
92
|
+
scaler from sklearn.preprocessing.
|
|
93
|
+
|
|
94
|
+
- 'lbfgs' uses L-BFGS-B algorithm implemented in
|
|
95
|
+
`scipy.optimize.minimize`. It can be used only when `positive`
|
|
96
|
+
is True.
|
|
97
|
+
|
|
98
|
+
All solvers except 'svd' support both dense and sparse data. However, only
|
|
99
|
+
'lsqr', 'sag', 'sparse_cg', and 'lbfgs' support sparse input when
|
|
100
|
+
`fit_intercept` is True.
|
|
101
|
+
|
|
102
|
+
positive : bool, default: False
|
|
103
|
+
When set to ``True``, forces the coefficients to be positive.
|
|
104
|
+
Only 'lbfgs' solver is supported in this case.
|
|
105
|
+
|
|
106
|
+
random_state : int, RandomState instance, default: None
|
|
107
|
+
Used when ``solver`` == 'sag' or 'saga' to shuffle the data.
|
|
108
|
+
|
|
109
|
+
Attributes
|
|
110
|
+
----------
|
|
111
|
+
coef_ : ndarray, shape = (n_features,)
|
|
112
|
+
Weight vector.
|
|
113
|
+
|
|
114
|
+
intercept_ : float or ndarray, shape = (n_targets,)
|
|
115
|
+
Independent term in decision function. Set to 0.0 if
|
|
116
|
+
``fit_intercept = False``.
|
|
117
|
+
|
|
118
|
+
n_iter_ : None or ndarray, shape = (n_targets,)
|
|
119
|
+
Actual number of iterations for each target. Available only for
|
|
120
|
+
sag and lsqr solvers. Other solvers will return None.
|
|
121
|
+
|
|
122
|
+
n_features_in_ : int
|
|
123
|
+
Number of features seen during ``fit``.
|
|
124
|
+
|
|
125
|
+
feature_names_in_ : ndarray, shape = (`n_features_in_`,)
|
|
126
|
+
Names of features seen during ``fit``. Defined only when `X`
|
|
127
|
+
has feature names that are all strings.
|
|
128
|
+
|
|
129
|
+
References
|
|
130
|
+
----------
|
|
131
|
+
.. [1] W. Stute, "Consistent estimation under random censorship when covariables are
|
|
132
|
+
present", Journal of Multivariate Analysis, vol. 45, no. 1, pp. 89-103, 1993.
|
|
133
|
+
doi:10.1006/jmva.1993.1028.
|
|
134
|
+
"""
|
|
135
|
+
|
|
136
|
+
_parameter_constraints = {**Ridge._parameter_constraints}
|
|
137
|
+
|
|
138
|
+
def __init__(
|
|
139
|
+
self,
|
|
140
|
+
alpha=1.0,
|
|
141
|
+
*,
|
|
142
|
+
fit_intercept=True,
|
|
143
|
+
copy_X=True,
|
|
144
|
+
max_iter=None,
|
|
145
|
+
tol=1e-3,
|
|
146
|
+
solver="auto",
|
|
147
|
+
positive=False,
|
|
148
|
+
random_state=None,
|
|
149
|
+
):
|
|
150
|
+
super().__init__(
|
|
151
|
+
alpha=alpha,
|
|
152
|
+
fit_intercept=fit_intercept,
|
|
153
|
+
copy_X=copy_X,
|
|
154
|
+
max_iter=max_iter,
|
|
155
|
+
tol=tol,
|
|
156
|
+
solver=solver,
|
|
157
|
+
positive=positive,
|
|
158
|
+
random_state=random_state,
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
@property
|
|
162
|
+
def _predict_risk_score(self):
|
|
163
|
+
return False
|
|
164
|
+
|
|
165
|
+
def fit(self, X, y):
|
|
166
|
+
"""Build an accelerated failure time model.
|
|
167
|
+
|
|
168
|
+
Parameters
|
|
169
|
+
----------
|
|
170
|
+
X : array-like, shape = (n_samples, n_features)
|
|
171
|
+
Data matrix.
|
|
172
|
+
|
|
173
|
+
y : structured array, shape = (n_samples,)
|
|
174
|
+
A structured array with two fields. The first field is a boolean
|
|
175
|
+
where ``True`` indicates an event and ``False`` indicates right-censoring.
|
|
176
|
+
The second field is a float with the time of event or time of censoring.
|
|
177
|
+
|
|
178
|
+
Returns
|
|
179
|
+
-------
|
|
180
|
+
self
|
|
181
|
+
"""
|
|
182
|
+
event, time = check_array_survival(X, y)
|
|
183
|
+
|
|
184
|
+
weights = ipc_weights(event, time)
|
|
185
|
+
super().fit(X, np.log(time), sample_weight=weights)
|
|
186
|
+
|
|
187
|
+
return self
|
|
188
|
+
|
|
189
|
+
def predict(self, X):
|
|
190
|
+
"""Predict using the linear accelerated failure time model.
|
|
191
|
+
|
|
192
|
+
Parameters
|
|
193
|
+
----------
|
|
194
|
+
X : {array-like, sparse matrix}, shape = (n_samples, n_features)
|
|
195
|
+
Samples.
|
|
196
|
+
|
|
197
|
+
Returns
|
|
198
|
+
-------
|
|
199
|
+
y_pred : array, shape = (n_samples,)
|
|
200
|
+
Returns predicted values on original scale (NOT log scale).
|
|
201
|
+
"""
|
|
202
|
+
return np.exp(super().predict(X))
|
|
203
|
+
|
|
204
|
+
def score(self, X, y, sample_weight=None):
|
|
205
|
+
return SurvivalAnalysisMixin.score(self, X, y)
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
IPCRidge.score.__doc__ = SurvivalAnalysisMixin.score.__doc__
|