Skip to content

Commit 5393e36

Browse files
the spline scipy options were not propogating through
1 parent 479fb78 commit 5393e36

File tree

6 files changed

+12
-51
lines changed

6 files changed

+12
-51
lines changed

README.md

Lines changed: 3 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -15,52 +15,16 @@ But outside of medicine and actuarial science, there are many other interesting
1515
- SaaS providers are interested in measuring subscriber lifetimes, or time to some first action
1616
- inventory stock out is a censoring event for true "demand" of a good.
1717
- sociologists are interested in measuring political parties' lifetimes, or relationships, or marriages
18-
- analyzing [Godwin's law](https://raw.githubusercontent.com/lukashalim/GODWIN/master/Kaplan-Meier-Godwin.png) in Reddit comments
1918
- A/B tests to determine how long it takes different groups to perform an action.
2019

2120
*lifelines* is a pure Python implementation of the best parts of survival analysis. We'd love to hear if you are using *lifelines*, please leave an Issue and let us know your thoughts on the library.
2221

23-
## Installation:
2422

25-
You can install *lifelines* using
23+
## Documentation and intro to survival analysis
2624

27-
pip install lifelines
25+
If you are new to survival analysis, wondering why it is useful, or are interested in *lifelines* examples, API, and syntax, please read the [Documentation and Tutorials page](http://lifelines.readthedocs.org/en/latest/index.html)
2826

29-
or conda install:
30-
31-
conda install -c conda-forge lifelines
32-
33-
Or getting the bleeding edge version with:
34-
35-
pip install --upgrade --no-deps git+https://github.com/CamDavidsonPilon/lifelines.git
36-
37-
from the command line.
38-
39-
### Installation Issues?
40-
41-
See the common [problems/solutions for installing lifelines](https://github.com/CamDavidsonPilon/lifelines/issues?utf8=%E2%9C%93&q=label%3Ainstallation+).
42-
43-
44-
## *lifelines* documentation and an intro to survival analysis
45-
46-
If you are new to survival analysis, wondering why it is useful, or are interested in *lifelines* examples, API, and syntax, please check out the [Documentation and Tutorials page](http://lifelines.readthedocs.org/en/latest/index.html)
47-
48-
Example:
49-
```python
50-
from lifelines import KaplanMeierFitter
51-
52-
durations = [11, 74, 71, 76, 28, 92, 89, 48, 90, 39, 63, 36, 54, 64, 34, 73, 94, 37, 56, 76]
53-
event_observed = [True, True, False, True, True, True, True, False, False, True, True,
54-
True, True, True, True, True, False, True, False, True]
55-
56-
kmf = KaplanMeierFitter()
57-
kmf.fit(durations, event_observed)
58-
kmf.plot()
59-
```
60-
61-
<img src="https://imgur.com/d4Gi5J0.png" width="600">
62-
63-
## Contacting & troubleshooting
27+
## Contact
6428
- There is a [Gitter](https://gitter.im/python-lifelines/) channel available.
6529
- Some users have posted common questions at [stats.stackexchange.com](https://stats.stackexchange.com/search?tab=votes&q=%22lifelines%22%20is%3aquestion)
6630
- creating an issue in the [Github repository](https://github.com/camdavidsonpilon/lifelines).
@@ -72,8 +36,6 @@ You can find the roadmap for lifelines [here](https://www.notion.so/camdp/6e2965
7236

7337
See our [Contributing](https://github.com/CamDavidsonPilon/lifelines/blob/master/.github/CONTRIBUTING.md) guidelines.
7438

75-
-------------------------------------------------------------------------------
76-
7739
## Citing lifelines
7840

7941
You can use this badge below to generate a DOI and reference text for the latest related version of lifelines:

lifelines/fitters/coxph_fitter.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,16 @@ class _PHSplineFitter(ParametricRegressionFitter, SplineFitterMixin, Proportiona
6262
"""
6363

6464
_KNOWN_MODEL = True
65+
_scipy_fit_method = "SLSQP"
66+
_scipy_fit_options = {"maxiter": 1000, "iprint": 100}
6567

6668
def __init__(self, n_baseline_knots=1, *args, **kwargs):
6769
self.n_baseline_knots = n_baseline_knots
6870
self._fitted_parameter_names = ["beta_"] + ["phi%d_" % i for i in range(1, self.n_baseline_knots + 2)]
6971
super(_PHSplineFitter, self).__init__(*args, **kwargs)
7072

7173
def set_knots(self, T, E):
72-
self.knots = np.percentile(T[E.astype(bool).values], np.linspace(20, 80, self.n_baseline_knots + 2))
74+
self.knots = np.percentile(T[E.astype(bool).values], np.linspace(5, 95, self.n_baseline_knots + 2))
7375
return
7476

7577
def _pre_fit_model(self, Ts, E, df):
@@ -78,10 +80,9 @@ def _pre_fit_model(self, Ts, E, df):
7880
def _create_initial_point(self, Ts, E, entries, weights, Xs):
7981
return [
8082
{
81-
**{"beta_": np.zeros(len(Xs.mappings["beta_"])), "phi1_": np.array([0.5]), "phi2_": np.array([-0.75])},
83+
**{"beta_": np.zeros(len(Xs.mappings["beta_"])), "phi1_": np.array([0.05]), "phi2_": np.array([-0.05])},
8284
**{"phi%d_" % i: np.array([0.0]) for i in range(3, self.n_baseline_knots + 2)},
83-
},
84-
super(_PHSplineFitter, self)._create_initial_point(Ts, E, entries, weights, Xs),
85+
}
8586
]
8687

8788
def _cumulative_hazard(self, params, T, Xs):
@@ -724,7 +725,6 @@ def _fit_model_spline(
724725
df, "T", "E", weights_col="weights", show_progress=show_progress, robust=self.robust, regressors=regressors
725726
)
726727
self._ll_null_ = cph._ll_null
727-
cph.print_summary()
728728
baseline_hazard_ = cph.predict_hazard(df.mean()).rename(columns={0: "baseline hazard"})
729729
baseline_cumulative_hazard_ = cph.predict_cumulative_hazard(df.mean()).rename(
730730
columns={0: "baseline cumulative hazard"}

lifelines/fitters/mixins.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,6 @@
1010

1111

1212
class SplineFitterMixin:
13-
# TODO: this should implement the knot choosing logic.
14-
_scipy_fit_method = "SLSQP"
15-
1613
@staticmethod
1714
def relu(x: np.array):
1815
return anp.maximum(0, x)

lifelines/fitters/spline_fitter.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ class SplineFitter(KnownModelParametricUnivariateFitter, SplineFitterMixin):
7373
The locations of the cubic breakpoints.
7474
7575
"""
76+
_scipy_fit_method = "SLSQP"
77+
_scipy_fit_options = {"maxiter": 1000}
7678

7779
def __init__(self, knot_locations: np.array, *args, **kwargs):
7880
self.knot_locations = knot_locations

lifelines/tests/test_estimation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1747,7 +1747,7 @@ def test_duration_vector_can_be_normalized_up_to_an_intercept(self, regression_m
17471747
check_less_precise=2,
17481748
)
17491749
else:
1750-
assert_series_equal(hazards, hazards_norm, check_less_precise=2)
1750+
assert_series_equal(hazards, hazards_norm, check_less_precise=1)
17511751

17521752
def test_prediction_methods_respect_index(self, regression_models, rossi):
17531753
X = rossi.iloc[:4].sort_index(ascending=False)

perf_tests/cp_perf_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
reps = 1
1414
df = load_rossi()
1515
df = pd.concat([df] * reps)
16-
cp_breslow = CoxPHFitter(penalizer=0.01, l1_ratio=0.0, baseline_estimation_method="spline")
16+
cp_breslow = CoxPHFitter(penalizer=0.1, l1_ratio=1.0, baseline_estimation_method="spline")
1717
start_time = time.time()
1818
cp_breslow.fit(df, duration_col="week", event_col="arrest", show_progress=True)
1919
print("--- %s seconds ---" % (time.time() - start_time))

0 commit comments

Comments
 (0)