Skip to content

Commit 32e1014

Browse files
committed
Substantial optimisation
Ludicrously large change for one single commit. Moved univariate fitters to univariate folder. Substantial change to mle fitting logic with large clean up of code and removal of older functions. Changed some moments to use scipy stats moments. Moved GumbelLEV into tests and highest level import. Implemented use of expm1 and log1p where it was logical to do so.
1 parent 84bf5a1 commit 32e1014

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+393
-392
lines changed

pyproject.toml

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ line-length = 79
55
# So isort is compatible with black
66
[tool.isort]
77
profile = "black"
8+
skip = ["__init__.py"]
89

910
# mypy
1011
[tool.mypy]

surpyval/__init__.py

+11-9
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
from autograd import numpy as np
44

55
from surpyval.distribution import Distribution
6-
from surpyval.nonparametric import (
6+
from surpyval.univariate.nonparametric import (
77
FlemingHarrington,
88
KaplanMeier,
99
NelsonAalen,
1010
NonParametric,
1111
Turnbull,
1212
)
13-
from surpyval.parametric import (
13+
from surpyval.univariate.parametric import (
1414
Bernoulli,
1515
Beta,
1616
CustomDistribution,
@@ -22,6 +22,7 @@
2222
Gamma,
2323
Gauss,
2424
Gumbel,
25+
GumbelLEV,
2526
InstantlyOccurs,
2627
Logistic,
2728
LogLogistic,
@@ -34,13 +35,6 @@
3435
Uniform,
3536
Weibull,
3637
)
37-
from surpyval.regression import (
38-
CoxPH,
39-
ExponentialPH,
40-
RandomSurvivalForest,
41-
SurvivalTree,
42-
WeibullPH,
43-
)
4438
from surpyval.utils import (
4539
fs_to_xcn,
4640
fs_to_xrd,
@@ -58,6 +52,14 @@
5852

5953
from .fit_best import fit_best
6054

55+
from surpyval.regression import ( # isort: skip
56+
CoxPH,
57+
ExponentialPH,
58+
RandomSurvivalForest,
59+
SurvivalTree,
60+
WeibullPH,
61+
)
62+
6163
NUM = np.float64
6264
TINIEST = np.finfo(np.float64).tiny
6365
EPS = np.sqrt(np.finfo(NUM).eps)

surpyval/fit_best.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import numpy as np
55

6-
from surpyval.parametric import (
6+
from surpyval.univariate.parametric import (
77
Beta,
88
Exponential,
99
ExpoWeibull,

surpyval/parametric/fitters/__init__.py

-85
This file was deleted.

surpyval/regression/__init__.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,16 @@
44
import autograd.numpy as np
55

66
import surpyval as surv
7-
from surpyval.parametric.parametric_fitter import ParametricFitter
87
from surpyval.regression.lifemodels.lifemodel import LifeModel
8+
from surpyval.univariate.parametric import (
9+
Gumbel,
10+
Logistic,
11+
LogNormal,
12+
Normal,
13+
Weibull,
14+
)
15+
from surpyval.univariate.parametric.parametric_fitter import ParametricFitter
916

10-
from ..parametric import Gumbel, Logistic, LogNormal, Normal, Weibull
1117
from .accelerated_failure_time import AcceleratedFailureTimeFitter
1218
from .cox_ph import CoxPH
1319
from .forest.forest import RandomSurvivalForest

surpyval/regression/accelerated_failure_time.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
from scipy.optimize import minimize
33

44
import surpyval
5+
from surpyval.univariate.parametric.fitters import bounds_convert
56

6-
from ..parametric.fitters import bounds_convert, fix_idx_and_function
77
from .regression import Regression
88

99

@@ -154,9 +154,8 @@ def fit(self, Z, x, c=None, n=None, t=None, init=[], fixed={}):
154154
**{k: v + len(self.param_map) for k, v in phi_param_map.items()},
155155
}
156156

157-
transform, inv_trans, funcs, inv_f = bounds_convert(x, bounds)
158-
const, fixed_idx, not_fixed = fix_idx_and_function(
159-
fixed, param_map, funcs
157+
transform, inv_trans, const, fixed_idx, not_fixed = bounds_convert(
158+
x, bounds, fixed, param_map
160159
)
161160

162161
init = transform(init)[not_fixed]

surpyval/regression/cox_ph.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,13 @@
1717
from scipy.optimize import root
1818
from scipy.stats import norm
1919

20-
from ..nonparametric import (
20+
from surpyval.univariate.nonparametric import (
2121
FlemingHarrington,
2222
KaplanMeier,
2323
NelsonAalen,
2424
Turnbull,
2525
)
26+
2627
from ..utils import validate_coxph, validate_coxph_df_inputs
2728
from .proportional_hazards import ProportionalHazardsModel
2829
from .regression import Regression

surpyval/regression/forest/node.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
from numpy.typing import ArrayLike, NDArray
77

88
from surpyval import Exponential, NelsonAalen, Weibull
9-
from surpyval.parametric import NeverOccurs
109
from surpyval.regression.forest.log_rank_split import log_rank_split
10+
from surpyval.univariate.parametric import NeverOccurs
1111
from surpyval.utils.surpyval_data import SurpyvalData
1212

1313

surpyval/regression/parameter_substitution.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
from scipy.optimize import minimize
66

77
import surpyval
8+
from surpyval.univariate.parametric.fitters import bounds_convert
89

9-
from ..parametric.fitters import bounds_convert, fix_idx_and_function
1010
from .regression import Regression
1111

1212

@@ -288,9 +288,8 @@ def fit(
288288
}
289289
self.param_map = param_map
290290

291-
transform, inv_trans, funcs, inv_f = bounds_convert(x, bounds)
292-
const, fixed_idx, not_fixed = fix_idx_and_function(
293-
fixed, param_map, funcs
291+
transform, inv_trans, const, fixed_idx, not_fixed = bounds_convert(
292+
x, bounds, fixed, param_map
294293
)
295294

296295
init = transform(init)[not_fixed]

surpyval/regression/proportional_hazards.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
from scipy.optimize import minimize
55

66
import surpyval
7+
from surpyval.univariate.parametric.fitters import bounds_convert
78

8-
from ..parametric.fitters import bounds_convert, fix_idx_and_function
99
from ..utils import _get_idx
1010
from .regression import Regression
1111

@@ -233,9 +233,8 @@ def fit(self, Z, x, c=None, n=None, t=None, init=[], fixed={}):
233233
model.phi_param_map = self.phi_param_map
234234
param_map = {**self.param_map, **phi_param_map}
235235

236-
transform, inv_trans, funcs, inv_f = bounds_convert(x, bounds)
237-
const, fixed_idx, not_fixed = fix_idx_and_function(
238-
fixed, param_map, funcs
236+
transform, inv_trans, const, fixed_idx, not_fixed = bounds_convert(
237+
x, bounds, fixed, param_map
239238
)
240239

241240
init = transform(init)[not_fixed]

surpyval/tests/test_lfp_zi.py

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import numpy as np
2+
3+
from surpyval import (
4+
Beta,
5+
Gamma,
6+
Gumbel,
7+
GumbelLEV,
8+
Logistic,
9+
LogLogistic,
10+
LogNormal,
11+
Normal,
12+
Weibull,
13+
)
14+
15+
16+
def test_zi():
17+
for dist in [Beta, Weibull, LogNormal, LogLogistic, Gamma]:
18+
for zeros in [1, 10, 100, 1000, 10000]:
19+
x = dist.random(100, 10, 2)
20+
x = np.concatenate((x, np.zeros(zeros)))
21+
model = dist.fit(x, zi=True)
22+
assert model.res.success
23+
24+
25+
def test_lfp():
26+
for dist in [
27+
Beta,
28+
Gamma,
29+
Gumbel,
30+
GumbelLEV,
31+
Logistic,
32+
LogLogistic,
33+
LogNormal,
34+
Normal,
35+
Weibull,
36+
]:
37+
for censored in [1, 10, 100, 1000, 10000]:
38+
x = dist.random(100, 10, 2)
39+
c = np.concatenate((np.zeros_like(x), np.ones(censored)))
40+
x = np.concatenate((x, x.max() * np.ones(censored)))
41+
model = dist.fit(x, c=c, lfp=True)
42+
assert model.res.success
43+
44+
45+
def test_lfp_zi():
46+
for dist in [Gamma, Weibull, LogNormal, LogLogistic]:
47+
for zi_lfp_values in [1, 10, 100]:
48+
for num_samples in [100, 1000, 10000]:
49+
x = dist.random(num_samples, 10, 2)
50+
c = np.concatenate(
51+
(
52+
np.zeros_like(x),
53+
np.zeros(zi_lfp_values),
54+
np.ones(zi_lfp_values),
55+
)
56+
)
57+
x = np.concatenate(
58+
(
59+
x,
60+
np.zeros(zi_lfp_values),
61+
x.max() * np.ones(zi_lfp_values) + 1,
62+
)
63+
)
64+
model = dist.fit(x, c=c, zi=True, lfp=True)
65+
if not model.res.success:
66+
raise ValueError(model, model.res)

surpyval/univariate/__init__.py

Whitespace-only changes.

surpyval/nonparametric/filliben.py surpyval/univariate/nonparametric/filliben.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import numpy as np
22

3-
from surpyval import nonparametric as nonp
3+
from surpyval.univariate.nonparametric import rank_adjust
44
from surpyval.utils import xcnt_handler
55

66

@@ -26,7 +26,7 @@ def filliben(x, c, n, t):
2626
c = c[idx2]
2727
N = len(x)
2828

29-
ranks = nonp.rank_adjust(x, c)
29+
ranks = rank_adjust(x, c)
3030
d = 1 - c
3131
r = np.linspace(N, 1, num=N)
3232

surpyval/nonparametric/fleming_harrington.py surpyval/univariate/nonparametric/fleming_harrington.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import numpy as np
22

3-
from surpyval.nonparametric.nonparametric_fitter import NonParametricFitter
3+
from surpyval.univariate.nonparametric.nonparametric_fitter import (
4+
NonParametricFitter,
5+
)
46

57

68
def fh_h(r_i, d_i):

surpyval/nonparametric/kaplan_meier.py surpyval/univariate/nonparametric/kaplan_meier.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import numpy as np
22

3-
from surpyval.nonparametric.nonparametric_fitter import NonParametricFitter
3+
from surpyval.univariate.nonparametric.nonparametric_fitter import (
4+
NonParametricFitter,
5+
)
46

57

68
def kaplan_meier(r, d):

surpyval/nonparametric/nelson_aalen.py surpyval/univariate/nonparametric/nelson_aalen.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import numpy as np
22

3-
from surpyval.nonparametric.nonparametric_fitter import NonParametricFitter
3+
from surpyval.univariate.nonparametric.nonparametric_fitter import (
4+
NonParametricFitter,
5+
)
46

57

68
def nelson_aalen(r, d):

0 commit comments

Comments
 (0)