lifelines 0.27.5__py3-none-any.whl → 0.27.7__py3-none-any.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.
@@ -1965,7 +1965,6 @@ class ParametricRegressionFitter(RegressionFitter):
1965
1965
  raise exceptions.ConvergenceError(
1966
1966
  dedent(
1967
1967
  f"""\
1968
- {minimum_results=}
1969
1968
 
1970
1969
  Fitting did not converge. Try the following:
1971
1970
 
@@ -1976,6 +1975,8 @@ class ParametricRegressionFitter(RegressionFitter):
1976
1975
  4. Try using an alternate minimizer: ``fitter._scipy_fit_method = "SLSQP"``.
1977
1976
  5. Trying adding a small penalizer (or changing it, if already present). Example: `{self._class_name}(penalizer=0.01).fit(...)`.
1978
1977
  6. Are there any extreme outliers? Try modeling them or dropping them to see if it helps convergence.
1978
+
1979
+ minimum_results={minimum_results}
1979
1980
  """
1980
1981
  )
1981
1982
  )
@@ -107,6 +107,49 @@ class ProportionalHazardMixin:
107
107
 
108
108
  for variable in self.params_.index.intersection(columns or self.params_.index):
109
109
  minumum_observed_p_value = test_results.summary.loc[variable, "p"].min()
110
+
111
+ # plot is done (regardless of test result) whenever `show_plots = True`
112
+ if show_plots:
113
+ axes.append([])
114
+ print()
115
+ print(" Bootstrapping lowess lines. May take a moment...")
116
+ print()
117
+ from matplotlib import pyplot as plt
118
+
119
+ fig = plt.figure()
120
+
121
+ # plot variable against all time transformations.
122
+ for i, (transform_name, transformer) in enumerate(TimeTransformers().iter(["rank", "km"]), start=1):
123
+ p_value = test_results.summary.loc[(variable, transform_name), "p"]
124
+
125
+ ax = fig.add_subplot(1, 2, i)
126
+
127
+ y = residuals_and_duration[variable]
128
+ tt = transformer(self.durations, self.event_observed, self.weights)[self.event_observed.values]
129
+
130
+ ax.scatter(tt, y, alpha=0.75)
131
+
132
+ y_lowess = lowess(tt.values, y.values)
133
+ ax.plot(tt, y_lowess, color="k", alpha=1.0, linewidth=2)
134
+
135
+ # bootstrap some possible other lowess lines. This is an approximation of the 100% confidence intervals
136
+ for _ in range(plot_n_bootstraps):
137
+ ix = sorted(np.random.choice(n, n))
138
+ tt_ = tt.values[ix]
139
+ y_lowess = lowess(tt_, y.values[ix])
140
+ ax.plot(tt_, y_lowess, color="k", alpha=0.30)
141
+
142
+ best_xlim = ax.get_xlim()
143
+ ax.hlines(0, 0, tt.max(), linestyles="dashed", linewidths=1)
144
+ ax.set_xlim(best_xlim)
145
+
146
+ ax.set_xlabel("%s-transformed time\n(p=%.4f)" % (transform_name, p_value), fontsize=10)
147
+ axes[-1].append(ax)
148
+
149
+ fig.suptitle("Scaled Schoenfeld residuals of '%s'" % variable, fontsize=14)
150
+ plt.tight_layout()
151
+ plt.subplots_adjust(top=0.90)
152
+
110
153
  if np.round(minumum_observed_p_value, 2) > p_value_threshold:
111
154
  continue
112
155
 
@@ -181,48 +224,9 @@ class ProportionalHazardMixin:
181
224
  ),
182
225
  end="\n\n",
183
226
  )
227
+ #################
184
228
 
185
- if show_plots:
186
- axes.append([])
187
- print()
188
- print(" Bootstrapping lowess lines. May take a moment...")
189
- print()
190
- from matplotlib import pyplot as plt
191
-
192
- fig = plt.figure()
193
-
194
- # plot variable against all time transformations.
195
- for i, (transform_name, transformer) in enumerate(TimeTransformers().iter(["rank", "km"]), start=1):
196
- p_value = test_results.summary.loc[(variable, transform_name), "p"]
197
-
198
- ax = fig.add_subplot(1, 2, i)
199
-
200
- y = residuals_and_duration[variable]
201
- tt = transformer(self.durations, self.event_observed, self.weights)[self.event_observed.values]
202
-
203
- ax.scatter(tt, y, alpha=0.75)
204
-
205
- y_lowess = lowess(tt.values, y.values)
206
- ax.plot(tt, y_lowess, color="k", alpha=1.0, linewidth=2)
207
-
208
- # bootstrap some possible other lowess lines. This is an approximation of the 100% confidence intervals
209
- for _ in range(plot_n_bootstraps):
210
- ix = sorted(np.random.choice(n, n))
211
- tt_ = tt.values[ix]
212
- y_lowess = lowess(tt_, y.values[ix])
213
- ax.plot(tt_, y_lowess, color="k", alpha=0.30)
214
-
215
- best_xlim = ax.get_xlim()
216
- ax.hlines(0, 0, tt.max(), linestyles="dashed", linewidths=1)
217
- ax.set_xlim(best_xlim)
218
-
219
- ax.set_xlabel("%s-transformed time\n(p=%.4f)" % (transform_name, p_value), fontsize=10)
220
- axes[-1].append(ax)
221
-
222
- fig.suptitle("Scaled Schoenfeld residuals of '%s'" % variable, fontsize=14)
223
- plt.tight_layout()
224
- plt.subplots_adjust(top=0.90)
225
-
229
+
226
230
  if advice and counter > 0:
227
231
  print(
228
232
  dedent(
lifelines/metrics.py ADDED
@@ -0,0 +1,60 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ import numpy as np
4
+ from lifelines.utils import concordance_index, ConvergenceError
5
+
6
+ __all__ = ["concordance_index", "uncensored_l2_log_loss", "uncensored_l1_log_loss"]
7
+
8
+
9
+ def uncensored_l1_log_loss(event_times, predicted_event_times, event_observed=None):
10
+ r"""
11
+ Calculates the l1 log-loss of predicted event times to true event times for *non-censored*
12
+ individuals only.
13
+
14
+ .. math:: 1/N \sum_{i} |log(t_i) - log(q_i)|
15
+
16
+ Parameters
17
+ ----------
18
+ event_times:
19
+ a (n,) array of observed survival times.
20
+ predicted_event_times:
21
+ a (n,) array of predicted survival times.
22
+ event_observed:
23
+ a (n,) array of censored flags, 1 if observed, 0 if not. Default None assumes all observed.
24
+
25
+ Returns
26
+ -------
27
+ l1-log-loss: a scalar
28
+ """
29
+ if event_observed is None:
30
+ event_observed = np.ones_like(event_times, dtype=bool)
31
+
32
+ ix = event_observed.astype(bool)
33
+ return np.abs(np.log(event_times[ix]) - np.log(predicted_event_times[ix])).mean()
34
+
35
+
36
+ def uncensored_l2_log_loss(event_times, predicted_event_times, event_observed=None):
37
+ r"""
38
+ Calculates the l2 log-loss of predicted event times to true event times for *non-censored*
39
+ individuals only.
40
+
41
+ .. math:: 1/N \sum_{i} (log(t_i) - log(q_i))**2
42
+
43
+ Parameters
44
+ ----------
45
+ event_times:
46
+ a (n,) array of observed survival times.
47
+ predicted_event_times:
48
+ a (n,) array of predicted survival times.
49
+ event_observed:
50
+ a (n,) array of censored flags, 1 if observed, 0 if not. Default None assumes all observed.
51
+
52
+ Returns
53
+ -------
54
+ l2-log-loss: a scalar
55
+ """
56
+ if event_observed is None:
57
+ event_observed = np.ones_like(event_times, dtype=bool)
58
+
59
+ ix = event_observed.astype(bool)
60
+ return np.power(np.log(event_times[ix]) - np.log(predicted_event_times[ix]), 2).mean()
lifelines/version.py CHANGED
@@ -1,4 +1,4 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  from __future__ import unicode_literals
3
3
 
4
- __version__ = "0.27.5"
4
+ __version__ = "0.27.7"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lifelines
3
- Version: 0.27.5
3
+ Version: 0.27.7
4
4
  Summary: Survival analysis in Python, including Kaplan Meier, Nelson Aalen and regression
5
5
  Home-page: https://github.com/CamDavidsonPilon/lifelines
6
6
  Author: Cameron Davidson-Pilon
@@ -1,10 +1,12 @@
1
- lifelines/__init__.py,sha256=qPF0ennAJGEAK-s63Z0e4DHiWnfRT98slfHjR-tjGw4,2235
1
+ lifelines/__init__.py,sha256=F_sKrawq6L4GwTPgOu4FjoGUKQ2gfelAVIQOW1Ee8Ao,2241
2
2
  lifelines/calibration.py,sha256=Luii7bkJ2YB0jpuOYYhI22aUyEc1gLsS10Pno6Sqo98,4113
3
3
  lifelines/exceptions.py,sha256=Kf6GN2vB-SHde2mbPomj2PhpnCvCBOSTUZLY1jwOw-U,514
4
4
  lifelines/generate_datasets.py,sha256=WsvvrZt0jEYQ7-Fp53vrCq7MzmAM2pPUSoCaiQRwN5g,10155
5
+ lifelines/metrics.py,sha256=1NY5CAwETP7C8lIUjmQz2ye648W64oChs2zdi-rqEzc,1889
5
6
  lifelines/plotting.py,sha256=AKRFHz0ye_pu5kE_nod3kM5AhQKL8h1tdrHt77nDDa4,33150
6
7
  lifelines/statistics.py,sha256=cOszUYz87elnbTAt6V3fTrHwPjB9HFI1hxjLvKypS6k,35129
7
- lifelines/version.py,sha256=JBLJotCZSiROHDoXzVOQQ__ruAm8MRSl4IwA_Zhp12M,88
8
+ lifelines/version.py,sha256=5c99jzzH3waN_PF9HgeSaexk7Z6Rucqb2uRdXVlPMt4,88
9
+ lifelines/datasets/ACTG175.csv,sha256=VvujH6DXv7_5ZntxSf2WqXw1LnKqWChxpiqTXoEvDgc,185144
8
10
  lifelines/datasets/CuZn-LeftCensoredDataset.csv,sha256=PxTdZcJPPbhtaadpHjhMFVcUxmSn84BuDarujZIJpm4,1996
9
11
  lifelines/datasets/__init__.py,sha256=9OIUjJUP6mK4oiFIRwHTh9tI5icDj4z8owUfPPDiY8c,19990
10
12
  lifelines/datasets/anderson.csv,sha256=nTAtTK8mf0ymU88nKvO2Fj0WL9SE9o4S0GVujmX8Cl4,580
@@ -35,7 +37,7 @@ lifelines/datasets/rossi.csv,sha256=AhRAAXDgfzAVooXtyiAUysDa6KrBJfy6rWQkkOBfiSw,
35
37
  lifelines/datasets/stanford_heart.csv,sha256=HWS9SqJjQ6gDmvxxKCJLR1cOIJ8XKuwTNu4bW8tKWVM,8859
36
38
  lifelines/datasets/static_test.csv,sha256=w2PtSkXknCZfciwqcOZGlA8znBO7jTcq_AJ5e6NStAk,101
37
39
  lifelines/datasets/waltons_dataset.csv,sha256=Fd4UX6tGYxgGhXtH3T-S81wIGIbVohv5yom4aw0kXL8,2449
38
- lifelines/fitters/__init__.py,sha256=-4N1nTjafrvjJbzv15FZPSUKGn5C5Ei_QLzJSzDd5as,151111
40
+ lifelines/fitters/__init__.py,sha256=vQ4AtidwM-gDGkGIzwSwRTB1c2LogpjQirKKrn1kQ-I,151127
39
41
  lifelines/fitters/aalen_additive_fitter.py,sha256=vRQb38weMcknyxC9bJwiALwCzxmJ5DsEZwHkz2zV93k,21518
40
42
  lifelines/fitters/aalen_johansen_fitter.py,sha256=fIsyi_al5X5QhAzQbrkCreYLjlY_4mcuSEhcm6Ul7Oo,12515
41
43
  lifelines/fitters/breslow_fleming_harrington_fitter.py,sha256=Te1Y73lIIKhTC6yMADe35RVHI4XOLF17ub-N8oudS4I,4091
@@ -50,7 +52,7 @@ lifelines/fitters/log_logistic_aft_fitter.py,sha256=cw179z0_IqvuWgOORHSZ1lBiidHc
50
52
  lifelines/fitters/log_logistic_fitter.py,sha256=iTH97i9TrLp5IVBIZHC8nx5rvSn2-KM-wfv1wR_YSPU,4004
51
53
  lifelines/fitters/log_normal_aft_fitter.py,sha256=aOcdMR8T4vhy2BKGebrpEJD_lTZIQQ5VsrnuuKkU0RA,7890
52
54
  lifelines/fitters/log_normal_fitter.py,sha256=NLn1DCxJ9WJrVaairJPcOu_lShko_-vwoXw6goRR42w,3557
53
- lifelines/fitters/mixins.py,sha256=_ht2WvDztBsvgGQ5vmprhfiChEP5DfdwNQfa9JkyxtY,12399
55
+ lifelines/fitters/mixins.py,sha256=6k5-g8cit8ODbU7PbVD9tfYsY0jpde0HID3wJQ5kz1k,12527
54
56
  lifelines/fitters/mixture_cure_fitter.py,sha256=UetFlv9EfFYMDt95M2iR354lna5RKeWtO_lkoaMmoZE,5416
55
57
  lifelines/fitters/nelson_aalen_fitter.py,sha256=UNlEX5wR6xsUmEmJ2n2MEqblz-KvGmvlh8eGHfuQf6Y,10666
56
58
  lifelines/fitters/npmle.py,sha256=HV3yeu1byVv5oBSdv5TuLUg2X5NUxydxj8-h_xYScB0,10143
@@ -66,8 +68,8 @@ lifelines/utils/lowess.py,sha256=MMydVcnbxqIgsiNcIgVUFtlFycD7v3ezwEGpituvBHs,254
66
68
  lifelines/utils/printer.py,sha256=-nXxu02gs0kaKfoQQ65sH-I45tGmgoFeOOIUSEc53iE,5861
67
69
  lifelines/utils/safe_exp.py,sha256=HCCAkwQTx6G2qRC03v9Q_GWqVj8at1Eac1JVrMgS9hg,4350
68
70
  lifelines/utils/sklearn_adapter.py,sha256=S5qotbZ1hf1fhFBsx39Yd_NpA31jB9HhRiLjE8TWlhw,4202
69
- lifelines-0.27.5.dist-info/LICENSE,sha256=AasDeD139SnTdfXbKgN4BMyMgBlRy9YFs60tNrB4wf0,1079
70
- lifelines-0.27.5.dist-info/METADATA,sha256=iydwn5g_0UfE4g4thVCJfiVvtAaKyZ-5F1vjyOzE4pk,3297
71
- lifelines-0.27.5.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
72
- lifelines-0.27.5.dist-info/top_level.txt,sha256=3i57Z4mtpc6jWrsW0n-_o9Y7CpzytMTeLMPJBHYAo0o,10
73
- lifelines-0.27.5.dist-info/RECORD,,
71
+ lifelines-0.27.7.dist-info/LICENSE,sha256=AasDeD139SnTdfXbKgN4BMyMgBlRy9YFs60tNrB4wf0,1079
72
+ lifelines-0.27.7.dist-info/METADATA,sha256=N0RFCC7WLIaqHa6CYMMvvMkYVWE-Er77nqFYI6m3uWI,3297
73
+ lifelines-0.27.7.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
74
+ lifelines-0.27.7.dist-info/top_level.txt,sha256=3i57Z4mtpc6jWrsW0n-_o9Y7CpzytMTeLMPJBHYAo0o,10
75
+ lifelines-0.27.7.dist-info/RECORD,,