scikit-survival 0.26.0__cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_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.
Files changed (58) hide show
  1. scikit_survival-0.26.0.dist-info/METADATA +185 -0
  2. scikit_survival-0.26.0.dist-info/RECORD +58 -0
  3. scikit_survival-0.26.0.dist-info/WHEEL +6 -0
  4. scikit_survival-0.26.0.dist-info/licenses/COPYING +674 -0
  5. scikit_survival-0.26.0.dist-info/top_level.txt +1 -0
  6. sksurv/__init__.py +183 -0
  7. sksurv/base.py +115 -0
  8. sksurv/bintrees/__init__.py +15 -0
  9. sksurv/bintrees/_binarytrees.cpython-312-x86_64-linux-gnu.so +0 -0
  10. sksurv/column.py +204 -0
  11. sksurv/compare.py +123 -0
  12. sksurv/datasets/__init__.py +12 -0
  13. sksurv/datasets/base.py +614 -0
  14. sksurv/datasets/data/GBSG2.arff +700 -0
  15. sksurv/datasets/data/actg320.arff +1169 -0
  16. sksurv/datasets/data/bmt.arff +46 -0
  17. sksurv/datasets/data/breast_cancer_GSE7390-metastasis.arff +283 -0
  18. sksurv/datasets/data/cgvhd.arff +118 -0
  19. sksurv/datasets/data/flchain.arff +7887 -0
  20. sksurv/datasets/data/veteran.arff +148 -0
  21. sksurv/datasets/data/whas500.arff +520 -0
  22. sksurv/docstrings.py +99 -0
  23. sksurv/ensemble/__init__.py +2 -0
  24. sksurv/ensemble/_coxph_loss.cpython-312-x86_64-linux-gnu.so +0 -0
  25. sksurv/ensemble/boosting.py +1564 -0
  26. sksurv/ensemble/forest.py +902 -0
  27. sksurv/ensemble/survival_loss.py +151 -0
  28. sksurv/exceptions.py +18 -0
  29. sksurv/functions.py +114 -0
  30. sksurv/io/__init__.py +2 -0
  31. sksurv/io/arffread.py +91 -0
  32. sksurv/io/arffwrite.py +181 -0
  33. sksurv/kernels/__init__.py +1 -0
  34. sksurv/kernels/_clinical_kernel.cpython-312-x86_64-linux-gnu.so +0 -0
  35. sksurv/kernels/clinical.py +348 -0
  36. sksurv/linear_model/__init__.py +3 -0
  37. sksurv/linear_model/_coxnet.cpython-312-x86_64-linux-gnu.so +0 -0
  38. sksurv/linear_model/aft.py +208 -0
  39. sksurv/linear_model/coxnet.py +592 -0
  40. sksurv/linear_model/coxph.py +637 -0
  41. sksurv/meta/__init__.py +4 -0
  42. sksurv/meta/base.py +35 -0
  43. sksurv/meta/ensemble_selection.py +724 -0
  44. sksurv/meta/stacking.py +370 -0
  45. sksurv/metrics.py +1028 -0
  46. sksurv/nonparametric.py +911 -0
  47. sksurv/preprocessing.py +195 -0
  48. sksurv/svm/__init__.py +11 -0
  49. sksurv/svm/_minlip.cpython-312-x86_64-linux-gnu.so +0 -0
  50. sksurv/svm/_prsvm.cpython-312-x86_64-linux-gnu.so +0 -0
  51. sksurv/svm/minlip.py +695 -0
  52. sksurv/svm/naive_survival_svm.py +249 -0
  53. sksurv/svm/survival_svm.py +1236 -0
  54. sksurv/testing.py +155 -0
  55. sksurv/tree/__init__.py +1 -0
  56. sksurv/tree/_criterion.cpython-312-x86_64-linux-gnu.so +0 -0
  57. sksurv/tree/tree.py +790 -0
  58. sksurv/util.py +416 -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].to_numpy(dtype=np.float64)
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].to_numpy(), y.loc[:, nominal_columns].to_numpy(), 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.to_numpy()
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
@@ -0,0 +1,3 @@
1
+ from .aft import IPCRidge # noqa: F401
2
+ from .coxnet import CoxnetSurvivalAnalysis # noqa: F401
3
+ from .coxph import CoxPHSurvivalAnalysis # noqa: F401
@@ -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__