From cfcf70677959c497095ade20274876bb4100b59d Mon Sep 17 00:00:00 2001 From: CamDavidsonPilon Date: Tue, 23 Jun 2020 10:46:56 -0400 Subject: [PATCH 1/6] fix printer bug --- docs/Survival Regression.rst | 2 +- lifelines/utils/printer.py | 17 +++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/docs/Survival Regression.rst b/docs/Survival Regression.rst index c0a00444a..efeff9ba2 100644 --- a/docs/Survival Regression.rst +++ b/docs/Survival Regression.rst @@ -1176,7 +1176,7 @@ Back to our original problem of predicting the event time of censored individual .. note:: It's important to remember that this is now computing a _conditional_ probability (or metric), so if the result of ``predict_median`` is 10.5, then the *entire lifetime* is 10.5 + ``conditional_after``. -.. note:: If using `conditional_after` to predict *un*censored subjects, then ``conditional_after`` should probably be set to 0, or left blank. +.. note:: If using ``conditional_after`` to predict *uncensored* subjects, then ``conditional_after`` should probably be set to 0, or left blank. .. _Assessing Cox model fit using residuals: jupyter_notebooks/Cox%20residuals.html diff --git a/lifelines/utils/printer.py b/lifelines/utils/printer.py index 65def7956..95188d3f9 100644 --- a/lifelines/utils/printer.py +++ b/lifelines/utils/printer.py @@ -97,6 +97,7 @@ def ascii_print(self): decimals = self.decimals df = self.model.summary justify = self.justify + ci = 100 * (1 - self.model.alpha) print(self.model) for string, value in self.headers: @@ -114,10 +115,10 @@ def ascii_print(self): "coef", "exp(coef)", "se(coef)", - "coef lower 95%", - "coef upper 95%", - "exp(coef) lower 95%", - "exp(coef) upper 95%", + "coef lower %d%%" % ci, + "coef upper %d%%" % ci, + "exp(coef) lower %d%%" % ci, + "exp(coef) upper %d%%" % ci, "z", "p", "-log2(p)", @@ -129,10 +130,10 @@ def ascii_print(self): "coef", "exp(coef)", "se(coef)", - "coef lower 95%", - "coef upper 95%", - "exp(coef) lower 95%", - "exp(coef) upper 95%", + "coef lower %d%%" % ci, + "coef upper %d%%" % ci, + "exp(coef) lower %d%%" % ci, + "exp(coef) upper %d%%" % ci, ] second_row_set = ["z", "p", "-log2(p)"] From d9f40a7619e38dc87817efd11f0bf95efc0edef8 Mon Sep 17 00:00:00 2001 From: CamDavidsonPilon Date: Wed, 1 Jul 2020 14:08:16 -0400 Subject: [PATCH 2/6] some docs; digging into prop-hz-test changes in R --- lifelines/datasets/__init__.py | 7 +++++- lifelines/fitters/__init__.py | 10 +++++++- lifelines/fitters/coxph_fitter.py | 1 + lifelines/statistics.py | 41 +++++++++++++++++++++---------- 4 files changed, 44 insertions(+), 15 deletions(-) diff --git a/lifelines/datasets/__init__.py b/lifelines/datasets/__init__.py index c0673ca20..d7c13745d 100644 --- a/lifelines/datasets/__init__.py +++ b/lifelines/datasets/__init__.py @@ -200,8 +200,13 @@ def load_larynx(**kwargs): def load_lung(**kwargs): """ - Survival in patients with advanced lung cancer from the North Central Cancer Treatment Group. Performance scores rate how well the patient can perform usual daily activities.:: + Survival in patients with advanced lung cancer from the North Central Cancer Treatment Group. Performance scores rate how well the patient can perform usual daily activities. + Note + --------- + Be mindful of the ``status`` column, as lifelines will treat _any_ non-zero entry as censored. + + :: Size: (288,10) Example: inst time status age sex ph.ecog ph.karno pat.karno meal.cal wt.loss diff --git a/lifelines/fitters/__init__.py b/lifelines/fitters/__init__.py index 1c58adceb..6a1155b9d 100644 --- a/lifelines/fitters/__init__.py +++ b/lifelines/fitters/__init__.py @@ -1185,7 +1185,15 @@ def compute_residuals(self, training_dataframe: pd.DataFrame, kind: str) -> pd.D training_dataframe : DataFrame the same training DataFrame given in `fit` kind : string - {'schoenfeld', 'score', 'delta_beta', 'deviance', 'martingale', 'scaled_schoenfeld'} + One of {'schoenfeld', 'score', 'delta_beta', 'deviance', 'martingale', 'scaled_schoenfeld'} + + + + Notes + ------- + - ``'scaled_schoenfeld'``: *lifelines* does not add the coefficients to the final results, but R does when you call ``residuals(c, "scaledsch")`` + + """ assert kind in self._ALLOWED_RESIDUALS, "kind must be in %s" % self._ALLOWED_RESIDUALS diff --git a/lifelines/fitters/coxph_fitter.py b/lifelines/fitters/coxph_fitter.py index 46005c96b..ef0959b19 100644 --- a/lifelines/fitters/coxph_fitter.py +++ b/lifelines/fitters/coxph_fitter.py @@ -1339,6 +1339,7 @@ def _compute_schoenfeld( def _compute_schoenfeld_within_strata(self, X: ndarray, T: ndarray, E: ndarray, weights: ndarray) -> ndarray: """ A positive value of the residual shows an X value that is higher than expected at that death time. + """ # TODO: the diff_against is gross # This uses Efron ties. diff --git a/lifelines/statistics.py b/lifelines/statistics.py index 7aa094122..232d3270a 100644 --- a/lifelines/statistics.py +++ b/lifelines/statistics.py @@ -1,14 +1,14 @@ # -*- coding: utf-8 -*- from itertools import combinations +import warnings import numpy as np from scipy import stats import pandas as pd +from lifelines import utils from lifelines.utils import ( - _to_1d_array, - _to_list, group_survival_table_from_events, string_justify, format_p_value, @@ -60,13 +60,13 @@ def __init__(self, p_value, test_statistic, name=None, test_name=None, **kwargs) self.test_statistic = test_statistic self.test_name = test_name - self._p_value = _to_1d_array(p_value) - self._test_statistic = _to_1d_array(test_statistic) + self._p_value = utils._to_1d_array(p_value) + self._test_statistic = utils._to_1d_array(test_statistic) assert len(self._p_value) == len(self._test_statistic) if name is not None: - self.name = _to_list(name) + self.name = utils._to_list(name) assert len(self.name) == len(self._test_statistic) else: self.name = None @@ -840,7 +840,8 @@ def proportional_hazard_test( fitted_cox_model, training_df, time_transform="rank", precomputed_residuals=None, **kwargs ) -> StatisticalResult: """ - Test whether any variable in a Cox model breaks the proportional hazard assumption. + Test whether any variable in a Cox model breaks the proportional hazard assumption. This method uses an approximation + that R's ``survival`` use to use, but changed it in late 2019, hence there will be differences here between lifelines and R. Parameters ---------- @@ -862,20 +863,32 @@ def proportional_hazard_test( R uses the default `km`, we use `rank`, as this performs well versus other transforms. See http://eprints.lse.ac.uk/84988/1/06_ParkHendry2015-ReassessingSchoenfeldTests_Final.pdf + References + ----------- + - http://eprints.lse.ac.uk/84988/1/06_ParkHendry2015-ReassessingSchoenfeldTests_Final.pdf + - "Extending the Cox Model" + - https://github.com/therneau/survival/commit/5da455de4f16fbed7f867b1fc5b15f2157a132cd#diff-c784cc3eeb38f0a6227988a30f9c0730R36 + """ + if "transform" in kwargs: + warnings.warn("Found 'transform' keyword being set. Did you mean to set 'time_transform' instead?", UserWarning) events, durations, weights = fitted_cox_model.event_observed, fitted_cox_model.durations, fitted_cox_model.weights - deaths = events.sum() + n_deaths = events.sum() if precomputed_residuals is None: scaled_resids = fitted_cox_model.compute_residuals(training_df, kind="scaled_schoenfeld") else: scaled_resids = precomputed_residuals - def compute_statistic(times, resids): + scaled_resids = ( + fitted_cox_model.compute_residuals(training_df, kind="schoenfeld").dot(fitted_cox_model.variance_matrix_) * n_deaths + ) + + def compute_statistic(times, resids, n_deaths): demeaned_times = times - times.mean() T = (demeaned_times.values[:, None] * resids.values).sum(0) ** 2 / ( - deaths * np.diag(fitted_cox_model.variance_matrix_) * (demeaned_times ** 2).sum() + n_deaths * (fitted_cox_model.standard_errors_ ** 2) * (demeaned_times ** 2).sum() ) return T @@ -889,8 +902,8 @@ def compute_statistic(times, resids): # yuck for transform_name, transform in ((_, TimeTransformers().get(_)) for _ in time_transform): times = transform(durations, events, weights)[events.values] - T = compute_statistic(times, scaled_resids) - p_values = _to_1d_array([_chisq_test_p_value(t, 1) for t in T]) + T = compute_statistic(times, scaled_resids, n_deaths) + p_values = utils._to_1d_array([_chisq_test_p_value(t, 1) for t in T]) result += StatisticalResult( p_values, T, @@ -898,6 +911,7 @@ def compute_statistic(times, resids): test_name="proportional_hazard_test", null_distribution="chi squared", degrees_of_freedom=1, + model=str(fitted_cox_model), **kwargs ) @@ -909,9 +923,9 @@ def compute_statistic(times, resids): times = time_transformer(durations, events, weights)[events.values] - T = compute_statistic(times, scaled_resids) + T = compute_statistic(times, scaled_resids, n_deaths) - p_values = _to_1d_array([_chisq_test_p_value(t, 1) for t in T]) + p_values = utils._to_1d_array([_chisq_test_p_value(t, 1) for t in T]) result = StatisticalResult( p_values, T, @@ -920,6 +934,7 @@ def compute_statistic(times, resids): time_transform=time_transform, null_distribution="chi squared", degrees_of_freedom=1, + model=str(fitted_cox_model), **kwargs ) return result From 50c80e1d9561069b7beaf04309e0c2750772dad4 Mon Sep 17 00:00:00 2001 From: CamDavidsonPilon Date: Wed, 1 Jul 2020 20:45:55 -0400 Subject: [PATCH 3/6] update testing environments --- .travis.yml | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index de5181005..53206c917 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,22 +4,18 @@ dist: xenial python: - "3.6" - "3.7" + - "3.8" env: matrix: - - export PANDAS_VERSION=0.23.4 && export NUMPY_VERSION=1.18.1 - - export PANDAS_VERSION=0.24.2 && export NUMPY_VERSION=1.18.1 - - export PANDAS_VERSION=0.25.3 && export NUMPY_VERSION=1.18.1 - - export NUMPY_VERSION=1.16.4 && export PANDAS_VERSION=1.0.0 - - export NUMPY_VERSION=1.15.4 && export PANDAS_VERSION=1.0.0 - - export NUMPY_VERSION=1.17.3 && export PANDAS_VERSION=1.0.0 - - export NUMPY_VERSION=1.18.1 && export PANDAS_VERSION=1.0.0 + - export PANDAS_VERSION=0.23.4 && export NUMPY_VERSION=1.19.0 + - export PANDAS_VERSION=0.25.3 && export NUMPY_VERSION=1.19.0 + - export NUMPY_VERSION=1.15.4 && export PANDAS_VERSION=1.0.5 + - export NUMPY_VERSION=1.19.0 && export PANDAS_VERSION=1.0.5 before_install: - ls # - sudo apt-get update install: "make" script: - # enforce formatting - - make check_format # command to run tests - make test after_success: From c873e5916bd99e2990c3d10c452dbea309d2ac81 Mon Sep 17 00:00:00 2001 From: CamDavidsonPilon Date: Thu, 2 Jul 2020 07:52:20 -0400 Subject: [PATCH 4/6] fix some bugs in the spline model and create a failing test (times.shape != conditional_after.shape) --- lifelines/fitters/__init__.py | 2 -- lifelines/fitters/coxph_fitter.py | 14 ++++++++++++++ lifelines/tests/test_estimation.py | 24 +++++++++++++++++++++++- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/lifelines/fitters/__init__.py b/lifelines/fitters/__init__.py index 6a1155b9d..334927de8 100644 --- a/lifelines/fitters/__init__.py +++ b/lifelines/fitters/__init__.py @@ -1187,8 +1187,6 @@ def compute_residuals(self, training_dataframe: pd.DataFrame, kind: str) -> pd.D kind : string One of {'schoenfeld', 'score', 'delta_beta', 'deviance', 'martingale', 'scaled_schoenfeld'} - - Notes ------- - ``'scaled_schoenfeld'``: *lifelines* does not add the coefficients to the final results, but R does when you call ``residuals(c, "scaledsch")`` diff --git a/lifelines/fitters/coxph_fitter.py b/lifelines/fitters/coxph_fitter.py index ef0959b19..ccfac6200 100644 --- a/lifelines/fitters/coxph_fitter.py +++ b/lifelines/fitters/coxph_fitter.py @@ -306,6 +306,7 @@ def _fit_model_spline(self, *args, **kwargs): raise ValueError("strata is not available for this baseline estimation method") if kwargs["cluster_col"] is not None: raise ValueError("cluster_col is not available for this baseline estimation method") + assert self.n_baseline_knots is not None, "n_baseline_knots must be set in initialization." # these are not needed kwargs.pop("strata") @@ -2437,6 +2438,19 @@ def predict_hazard(self, df, *, times=None): return pd.DataFrame(self._hazard(params_dict, np.tile(times, (n, 1)).T, Xs), index=times, columns=df.index) + def score(self, df: pd.DataFrame, scoring_method: str = "log_likelihood") -> float: + df = df.copy() + df["_intercept"] = 1 + return super(ParametricSplinePHFitter, self).score(df, scoring_method) + + @property + def AIC_partial_(self): + warnings.warn( + "Since the spline model is fully parametric (and not semi-parametric), the partial AIC does not exist. You probably want the `.AIC_` property instead", + StatisticalWarning, + ) + return None + class _BatchVsSingle: diff --git a/lifelines/tests/test_estimation.py b/lifelines/tests/test_estimation.py index 7042fd593..7c2f10827 100644 --- a/lifelines/tests/test_estimation.py +++ b/lifelines/tests/test_estimation.py @@ -1799,7 +1799,11 @@ def test_alpha_will_vary_the_statistics_in_summary(self, rossi): assert reg_005.summary.loc[("beta_", "fin"), "coef lower 95%"] < reg_010.summary.loc[("beta_", "fin"), "coef lower 90%"] def test_score_method_returns_same_value_for_unpenalized_models(self, rossi): - regression_models = [CoxPHFitter(), WeibullAFTFitter()] + regression_models = [ + CoxPHFitter(), + WeibullAFTFitter(), + CoxPHFitter(baseline_estimation_method="spine", n_baseline_knots=2), + ] for fitter in regression_models: fitter.fit(rossi, "week", "arrest") npt.assert_almost_equal(fitter.score(rossi, scoring_method="log_likelihood"), fitter.log_likelihood_ / rossi.shape[0]) @@ -2871,6 +2875,24 @@ def test_conditional_after_in_prediction(self, rossi, cph): npt.assert_allclose(explicit.loc[12.0, 0], p2.loc[4.0, 0]) npt.assert_allclose(explicit.loc[20.0, 0], p2.loc[12.0, 0]) + def test_conditional_after_with_custom_times(self, rossi): + cph_semi = CoxPHFitter(baseline_estimation_method="breslow").fit(rossi, "week", "arrest") + cph_spline = CoxPHFitter(n_baseline_knots=2, baseline_estimation_method="spline").fit(rossi, "week", "arrest") + + # predict single + cph_semi.fit(rossi, "week", "arrest").predict_survival_function(rossi.iloc[0], times=np.arange(5), conditional_after=[10]) + cph_spline.fit(rossi, "week", "arrest").predict_survival_function( + rossi.iloc[0], times=np.arange(5), conditional_after=[10] + ) + + # predict multiple + cph_semi.fit(rossi, "week", "arrest").predict_survival_function( + rossi.iloc[:10], times=np.arange(5), conditional_after=[10] * 10 + ) + cph_spline.fit(rossi, "week", "arrest").predict_survival_function( + rossi.iloc[:10], times=np.arange(5), conditional_after=[10] * 10 + ) + def test_conditional_after_with_strata_in_prediction(self, rossi, cph): rossi.loc[rossi["week"] == 1, "week"] = 0 cph.fit(rossi, "week", "arrest", strata=["fin"]) From 2af31b78d244e9717a05526152d1237e431b5c8e Mon Sep 17 00:00:00 2001 From: CamDavidsonPilon Date: Thu, 2 Jul 2020 11:00:14 -0400 Subject: [PATCH 5/6] fix more bugs --- CHANGELOG.md | 7 + docs/Changelog.rst | 307 +++++++++++++++-------------- lifelines/fitters/__init__.py | 2 +- lifelines/fitters/coxph_fitter.py | 33 +--- lifelines/tests/test_statistics.py | 11 +- lifelines/version.py | 2 +- 6 files changed, 180 insertions(+), 182 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dea227df8..1cbefd561 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ #### 0.24.13 - 2020-06-22 +##### Bug fixes +- fixed a bug where using `conditional_after` and `times` in prediction methods would result in a shape error +- fixed a bug where `score` was not able to be used in splined `CoxPHFitter` +- fixed a bug where some columns would not be displayed in `print_summary` + +#### 0.24.13 - 2020-06-22 + ##### Bug fixes - fixed a bug where `CoxPHFitter` would ignore inputed `alpha` levels for confidence intervals - fixed a bug where `CoxPHFitter` would fail with working with `sklearn_adapter` diff --git a/docs/Changelog.rst b/docs/Changelog.rst index da771fbb3..e5822db0c 100644 --- a/docs/Changelog.rst +++ b/docs/Changelog.rst @@ -7,12 +7,29 @@ Changelog Bug fixes ''''''''' +- fixed a bug where using ``conditional_after`` and ``times`` in + prediction methods would result in a shape error +- fixed a bug where ``score`` was not able to be used in splined + ``CoxPHFitter`` +- fixed a bug where some columns would not be displayed in + ``print_summary`` + +.. _section-1: + +0.24.13 - 2020-06-22 +^^^^^^^^^^^^^^^^^^^^ + +.. _bug-fixes-1: + +Bug fixes +''''''''' + - fixed a bug where ``CoxPHFitter`` would ignore inputed ``alpha`` levels for confidence intervals - fixed a bug where ``CoxPHFitter`` would fail with working with ``sklearn_adapter`` -.. _section-1: +.. _section-2: 0.24.12 - 2020-06-20 ^^^^^^^^^^^^^^^^^^^^ @@ -22,7 +39,7 @@ New features - improved convergence of ``GeneralizedGamma(Regression)Fitter``. -.. _section-2: +.. _section-3: 0.24.11 - 2020-06-17 ^^^^^^^^^^^^^^^^^^^^ @@ -48,7 +65,7 @@ API Changes penalized by ``penalizer`` - we now penalizing everything except intercept terms in linear relationships. -.. _section-3: +.. _section-4: 0.24.10 - 2020-06-16 ^^^^^^^^^^^^^^^^^^^^ @@ -70,7 +87,7 @@ API Changes - Related to above: the fitted spline parameters are now available in the ``.summary`` and ``.print_summary`` methods. -.. _bug-fixes-1: +.. _bug-fixes-2: Bug fixes ''''''''' @@ -78,7 +95,7 @@ Bug fixes - fixed a bug in initialization of some interval-censoring models -> better convergence. -.. _section-4: +.. _section-5: 0.24.9 - 2020-06-05 ^^^^^^^^^^^^^^^^^^^ @@ -93,7 +110,7 @@ New features ``tarone-ware``, ``peto``, ``fleming-harrington``. Thanks @sean-reed - new interval censored dataset: ``lifelines.datasets.load_mice`` -.. _bug-fixes-2: +.. _bug-fixes-3: Bug fixes ''''''''' @@ -101,7 +118,7 @@ Bug fixes - Cleared up some mislabeling in ``plot_loglogs``. Thanks @sean-reed! - tuples are now able to be used as input in univariate models. -.. _section-5: +.. _section-6: 0.24.8 - 2020-05-17 ^^^^^^^^^^^^^^^^^^^ @@ -115,7 +132,7 @@ New features Not all edge cases are fully checked, and some features are missing. Try it under ``KaplanMeierFitter.fit_interval_censoring`` -.. _section-6: +.. _section-7: 0.24.7 - 2020-05-17 ^^^^^^^^^^^^^^^^^^^ @@ -136,7 +153,7 @@ New features - some convergence tweaks which should help recent performance regressions. -.. _section-7: +.. _section-8: 0.24.6 - 2020-05-05 ^^^^^^^^^^^^^^^^^^^ @@ -151,7 +168,7 @@ New features - New ``lifelines.plotting.plot_interval_censored_lifetimes`` for plotting interval censored data - thanks @sean-reed! -.. _bug-fixes-3: +.. _bug-fixes-4: Bug fixes ''''''''' @@ -159,7 +176,7 @@ Bug fixes - fixed bug where ``cdf_plot`` and ``qq_plot`` were not factoring in the weights correctly. -.. _section-8: +.. _section-9: 0.24.5 - 2020-05-01 ^^^^^^^^^^^^^^^^^^^ @@ -171,7 +188,7 @@ New features - ``plot_lifetimes`` accepts pandas Series. -.. _bug-fixes-4: +.. _bug-fixes-5: Bug fixes ''''''''' @@ -181,12 +198,12 @@ Bug fixes - Improved ``at_risk_counts`` for subplots. - More data validation checks for ``CoxTimeVaryingFitter`` -.. _section-9: +.. _section-10: 0.24.4 - 2020-04-13 ^^^^^^^^^^^^^^^^^^^ -.. _bug-fixes-5: +.. _bug-fixes-6: Bug fixes ''''''''' @@ -195,7 +212,7 @@ Bug fixes - setting a dataframe in ``ancillary_df`` works for interval censoring - ``.score`` works for interval censored models -.. _section-10: +.. _section-11: 0.24.3 - 2020-03-25 ^^^^^^^^^^^^^^^^^^^ @@ -210,7 +227,7 @@ New features the hazard ratio would be at previous times. This is useful because the final hazard ratio is some weighted average of these. -.. _bug-fixes-6: +.. _bug-fixes-7: Bug fixes ''''''''' @@ -218,12 +235,12 @@ Bug fixes - Fixed error in HTML printer that was hiding concordance index information. -.. _section-11: +.. _section-12: 0.24.2 - 2020-03-15 ^^^^^^^^^^^^^^^^^^^ -.. _bug-fixes-7: +.. _bug-fixes-8: Bug fixes ''''''''' @@ -235,7 +252,7 @@ Bug fixes - Fixed a keyword bug in ``plot_covariate_groups`` for parametric models. -.. _section-12: +.. _section-13: 0.24.1 - 2020-03-05 ^^^^^^^^^^^^^^^^^^^ @@ -248,14 +265,14 @@ New features - Stability improvements for GeneralizedGammaRegressionFitter and CoxPHFitter with spline estimation. -.. _bug-fixes-8: +.. _bug-fixes-9: Bug fixes ''''''''' - Fixed bug with plotting hazards in NelsonAalenFitter. -.. _section-13: +.. _section-14: 0.24.0 - 2020-02-20 ^^^^^^^^^^^^^^^^^^^ @@ -316,7 +333,7 @@ API Changes to ``scoring_method``. - removed ``_score_`` and ``path`` from Cox model. -.. _bug-fixes-9: +.. _bug-fixes-10: Bug fixes ''''''''' @@ -329,12 +346,12 @@ Bug fixes - Cox models now incorporate any penalizers in their ``log_likelihood_`` -.. _section-14: +.. _section-15: 0.23.9 - 2020-01-28 ^^^^^^^^^^^^^^^^^^^ -.. _bug-fixes-10: +.. _bug-fixes-11: Bug fixes ''''''''' @@ -345,12 +362,12 @@ Bug fixes of ``GeneralizedGammaRegressionFitter`` and any custom regression models should update their code as soon as possible. -.. _section-15: +.. _section-16: 0.23.8 - 2020-01-21 ^^^^^^^^^^^^^^^^^^^ -.. _bug-fixes-11: +.. _bug-fixes-12: Bug fixes ''''''''' @@ -361,14 +378,14 @@ Bug fixes ``GeneralizedGammaRegressionFitter`` and any custom regression models should update their code as soon as possible. -.. _section-16: +.. _section-17: 0.23.7 - 2020-01-14 ^^^^^^^^^^^^^^^^^^^ Bug fixes for py3.5. -.. _section-17: +.. _section-18: 0.23.6 - 2020-01-07 ^^^^^^^^^^^^^^^^^^^ @@ -387,7 +404,7 @@ New features - custom parametric regression models can now do left and interval censoring. -.. _section-18: +.. _section-19: 0.23.5 - 2020-01-05 ^^^^^^^^^^^^^^^^^^^ @@ -401,7 +418,7 @@ New features - New lymph node cancer dataset, originally from *H.F. for the German Breast Cancer Study Group (GBSG) (1994)* -.. _bug-fixes-12: +.. _bug-fixes-13: Bug fixes ''''''''' @@ -411,14 +428,14 @@ Bug fixes - fixed bug where large exponential numbers in ``print_summary`` were not being suppressed correctly. -.. _section-19: +.. _section-20: 0.23.4 - 2019-12-15 ^^^^^^^^^^^^^^^^^^^ - Bug fix for PyPI -.. _section-20: +.. _section-21: 0.23.3 - 2019-12-11 ^^^^^^^^^^^^^^^^^^^ @@ -430,7 +447,7 @@ New features - ``StatisticalResult.print_summary`` supports html output. -.. _bug-fixes-13: +.. _bug-fixes-14: Bug fixes ''''''''' @@ -438,7 +455,7 @@ Bug fixes - fix import in ``printer.py`` - fix html printing with Univariate models. -.. _section-21: +.. _section-22: 0.23.2 - 2019-12-07 ^^^^^^^^^^^^^^^^^^^ @@ -455,7 +472,7 @@ New features - performance improvements on regression models’ preprocessing. Should make datasets with high number of columns more performant. -.. _bug-fixes-14: +.. _bug-fixes-15: Bug fixes ''''''''' @@ -464,7 +481,7 @@ Bug fixes - fixed repr for ``sklearn_adapter`` classes. - fixed ``conditional_after`` in Cox model with strata was used. -.. _section-22: +.. _section-23: 0.23.1 - 2019-11-27 ^^^^^^^^^^^^^^^^^^^ @@ -479,7 +496,7 @@ New features - performance improvements for ``CoxPHFitter`` - up to 30% performance improvements for some datasets. -.. _bug-fixes-15: +.. _bug-fixes-16: Bug fixes ''''''''' @@ -491,7 +508,7 @@ Bug fixes - fixed bug when using ``print_summary`` with left censored models. - lots of minor bug fixes. -.. _section-23: +.. _section-24: 0.23.0 - 2019-11-17 ^^^^^^^^^^^^^^^^^^^ @@ -505,7 +522,7 @@ New features Jupyter notebooks! - silenced some warnings. -.. _bug-fixes-16: +.. _bug-fixes-17: Bug fixes ''''''''' @@ -527,7 +544,7 @@ API Changes - ``left_censorship`` in ``fit`` has been removed in favour of ``fit_left_censoring``. -.. _section-24: +.. _section-25: 0.22.10 - 2019-11-08 ^^^^^^^^^^^^^^^^^^^^ @@ -535,7 +552,7 @@ API Changes The tests were re-factored to be shipped with the package. Let me know if this causes problems. -.. _bug-fixes-17: +.. _bug-fixes-18: Bug fixes ''''''''' @@ -545,12 +562,12 @@ Bug fixes - fixed bug in plot_covariate_groups for AFT models when >1d arrays were used for values arg. -.. _section-25: +.. _section-26: 0.22.9 - 2019-10-30 ^^^^^^^^^^^^^^^^^^^ -.. _bug-fixes-18: +.. _bug-fixes-19: Bug fixes ''''''''' @@ -562,7 +579,7 @@ Bug fixes - ``CoxPHFitter`` now displays correct columns values when changing alpha param. -.. _section-26: +.. _section-27: 0.22.8 - 2019-10-06 ^^^^^^^^^^^^^^^^^^^ @@ -577,14 +594,14 @@ New features - ``conditional_after`` now available in ``CoxPHFitter.predict_median`` - Suppressed some unimportant warnings. -.. _bug-fixes-19: +.. _bug-fixes-20: Bug fixes ''''''''' - fixed initial_point being ignored in AFT models. -.. _section-27: +.. _section-28: 0.22.7 - 2019-09-29 ^^^^^^^^^^^^^^^^^^^ @@ -597,7 +614,7 @@ New features - new ``ApproximationWarning`` to tell you if the package is making an potentially mislead approximation. -.. _bug-fixes-20: +.. _bug-fixes-21: Bug fixes ''''''''' @@ -616,7 +633,7 @@ API Changes - Some previous ``StatisticalWarnings`` have been replaced by ``ApproximationWarning`` -.. _section-28: +.. _section-29: 0.22.6 - 2019-09-25 ^^^^^^^^^^^^^^^^^^^ @@ -628,7 +645,7 @@ New features - ``conditional_after`` works for ``CoxPHFitter`` prediction models 😅 -.. _bug-fixes-21: +.. _bug-fixes-22: Bug fixes ''''''''' @@ -644,7 +661,7 @@ API Changes - ``utils.dataframe_interpolate_at_times`` renamed to ``utils.interpolate_at_times_and_return_pandas``. -.. _section-29: +.. _section-30: 0.22.5 - 2019-09-20 ^^^^^^^^^^^^^^^^^^^ @@ -658,7 +675,7 @@ New features weights. - Better support for predicting on Pandas Series -.. _bug-fixes-22: +.. _bug-fixes-23: Bug fixes ''''''''' @@ -675,7 +692,7 @@ API Changes - ``_get_initial_value`` in parametric univariate models is renamed ``_create_initial_point`` -.. _section-30: +.. _section-31: 0.22.4 - 2019-09-04 ^^^^^^^^^^^^^^^^^^^ @@ -699,7 +716,7 @@ API changes - ``KaplanMeierFitter.survival_function_``\ ‘s’ index is no longer given the name “timeline”. -.. _bug-fixes-23: +.. _bug-fixes-24: Bug fixes ''''''''' @@ -707,7 +724,7 @@ Bug fixes - Fixed issue where ``concordance_index`` would never exit if NaNs in dataset. -.. _section-31: +.. _section-32: 0.22.3 - 2019-08-08 ^^^^^^^^^^^^^^^^^^^ @@ -736,7 +753,7 @@ API changes gains only in Cox models, and only a small fraction of the API was being used. -.. _bug-fixes-24: +.. _bug-fixes-25: Bug fixes ''''''''' @@ -748,7 +765,7 @@ Bug fixes - Fixed an error in the ``predict_percentile`` of ``LogLogisticAFTFitter``. New tests have been added around this. -.. _section-32: +.. _section-33: 0.22.2 - 2019-07-25 ^^^^^^^^^^^^^^^^^^^ @@ -760,7 +777,7 @@ New features - lifelines is now compatible with scipy>=1.3.0 -.. _bug-fixes-25: +.. _bug-fixes-26: Bug fixes ''''''''' @@ -771,7 +788,7 @@ Bug fixes errors when using the library. The correctly numpy has been pinned (to 1.14.0+) -.. _section-33: +.. _section-34: 0.22.1 - 2019-07-14 ^^^^^^^^^^^^^^^^^^^ @@ -804,7 +821,7 @@ API changes ``.print_summary`` includes confidence intervals for the exponential of the value. -.. _bug-fixes-26: +.. _bug-fixes-27: Bug fixes ''''''''' @@ -814,7 +831,7 @@ Bug fixes - fixed an overflow bug in ``KaplanMeierFitter`` confidence intervals - improvements in data validation for ``CoxTimeVaryingFitter`` -.. _section-34: +.. _section-35: 0.22.0 - 2019-07-03 ^^^^^^^^^^^^^^^^^^^ @@ -853,7 +870,7 @@ API changes could set ``fit_intercept`` to False and not have to set ``ancillary_df`` - now one must specify a DataFrame. -.. _bug-fixes-27: +.. _bug-fixes-28: Bug fixes ''''''''' @@ -862,7 +879,7 @@ Bug fixes is now exact instead of an approximation. - fixed a name error bug in ``CoxTimeVaryingFitter.plot`` -.. _section-35: +.. _section-36: 0.21.5 - 2019-06-22 ^^^^^^^^^^^^^^^^^^^ @@ -876,7 +893,7 @@ New features - ``scoring_method`` now a kwarg on ``sklearn_adapter`` -.. _bug-fixes-28: +.. _bug-fixes-29: Bug fixes ''''''''' @@ -886,7 +903,7 @@ Bug fixes - fixed visual bug that misaligned x-axis ticks and at-risk counts. Thanks @christopherahern! -.. _section-36: +.. _section-37: 0.21.3 - 2019-06-04 ^^^^^^^^^^^^^^^^^^^ @@ -905,14 +922,14 @@ New features - ``CoxPHFitter.check_assumptions`` now accepts a ``columns`` parameter to specify only checking a subset of columns. -.. _bug-fixes-29: +.. _bug-fixes-30: Bug fixes ''''''''' - ``covariates_from_event_matrix`` handle nulls better -.. _section-37: +.. _section-38: 0.21.2 - 2019-05-16 ^^^^^^^^^^^^^^^^^^^ @@ -941,12 +958,12 @@ API changes - removing ``_compute_likelihood_ratio_test`` on regression models. Use ``log_likelihood_ratio_test`` now. -.. _bug-fixes-30: +.. _bug-fixes-31: Bug fixes ''''''''' -.. _section-38: +.. _section-39: 0.21.1 - 2019-04-26 ^^^^^^^^^^^^^^^^^^^ @@ -968,14 +985,14 @@ API changes - output of ``survival_table_from_events`` when collapsing rows to intervals now removes the “aggregate” column multi-index. -.. _bug-fixes-31: +.. _bug-fixes-32: Bug fixes ''''''''' - fixed bug in CoxTimeVaryingFitter when ax is provided, thanks @j-i-l! -.. _section-39: +.. _section-40: 0.21.0 - 2019-04-12 ^^^^^^^^^^^^^^^^^^^ @@ -1005,7 +1022,7 @@ API changes - ``entries`` property in multivariate parametric models has a new Series name: ``entry`` -.. _bug-fixes-32: +.. _bug-fixes-33: Bug fixes ''''''''' @@ -1015,7 +1032,7 @@ Bug fixes - Fixed an error that didn’t let users use Numpy arrays in prediction for AFT models -.. _section-40: +.. _section-41: 0.20.5 - 2019-04-08 ^^^^^^^^^^^^^^^^^^^ @@ -1037,7 +1054,7 @@ API changes - in ``AalenJohansenFitter``, the ``variance`` parameter is renamed to ``variance_`` to align with the usual lifelines convention. -.. _bug-fixes-33: +.. _bug-fixes-34: Bug fixes ''''''''' @@ -1046,7 +1063,7 @@ Bug fixes test when using strata. - Fixed some plotting bugs with ``AalenJohansenFitter`` -.. _section-41: +.. _section-42: 0.20.4 - 2019-03-27 ^^^^^^^^^^^^^^^^^^^ @@ -1070,7 +1087,7 @@ API changes - Pandas is now correctly pinned to >= 0.23.0. This was always the case, but not specified in setup.py correctly. -.. _bug-fixes-34: +.. _bug-fixes-35: Bug fixes ''''''''' @@ -1079,7 +1096,7 @@ Bug fixes - ``PiecewiseExponentialFitter`` is available with ``from lifelines import *``. -.. _section-42: +.. _section-43: 0.20.3 - 2019-03-23 ^^^^^^^^^^^^^^^^^^^ @@ -1097,7 +1114,7 @@ New features ``plot_survival_function`` and ``confidence_interval_survival_function_``. -.. _section-43: +.. _section-44: 0.20.2 - 2019-03-21 ^^^^^^^^^^^^^^^^^^^ @@ -1126,7 +1143,7 @@ API changes @vpolimenov! - The ``C`` column in ``load_lcd`` dataset is renamed to ``E``. -.. _bug-fixes-35: +.. _bug-fixes-36: Bug fixes ''''''''' @@ -1142,7 +1159,7 @@ Bug fixes the q parameter was below the truncation limit. This should have been ``-np.inf`` -.. _section-44: +.. _section-45: 0.20.1 - 2019-03-16 ^^^^^^^^^^^^^^^^^^^ @@ -1166,7 +1183,7 @@ API changes This is no longer the case. A 0 will still be added if there is a duration (observed or not) at 0 occurs however. -.. _section-45: +.. _section-46: 0.20.0 - 2019-03-05 ^^^^^^^^^^^^^^^^^^^ @@ -1195,14 +1212,14 @@ API changes transposed now (previous parameters where columns, now parameters are rows). -.. _bug-fixes-36: +.. _bug-fixes-37: Bug fixes ''''''''' - Fixed a bug with plotting and ``check_assumptions``. -.. _section-46: +.. _section-47: 0.19.5 - 2019-02-26 ^^^^^^^^^^^^^^^^^^^ @@ -1217,19 +1234,19 @@ New features features or categorical variables. - Convergence improvements for AFT models. -.. _section-47: +.. _section-48: 0.19.4 - 2019-02-25 ^^^^^^^^^^^^^^^^^^^ -.. _bug-fixes-37: +.. _bug-fixes-38: Bug fixes ''''''''' - remove some bad print statements in ``CoxPHFitter``. -.. _section-48: +.. _section-49: 0.19.3 - 2019-02-25 ^^^^^^^^^^^^^^^^^^^ @@ -1246,7 +1263,7 @@ New features - Performance increase to ``print_summary`` in the ``CoxPHFitter`` and ``CoxTimeVaryingFitter`` model. -.. _section-49: +.. _section-50: 0.19.2 - 2019-02-22 ^^^^^^^^^^^^^^^^^^^ @@ -1259,7 +1276,7 @@ New features - ``ParametricUnivariateFitters``, like ``WeibullFitter``, have smoothed plots when plotting (vs stepped plots) -.. _bug-fixes-38: +.. _bug-fixes-39: Bug fixes ''''''''' @@ -1269,7 +1286,7 @@ Bug fixes - Univariate fitters are more flexiable and can allow 2-d and DataFrames as inputs. -.. _section-50: +.. _section-51: 0.19.1 - 2019-02-21 ^^^^^^^^^^^^^^^^^^^ @@ -1291,7 +1308,7 @@ API changes ``PiecewiseExponential`` to the same as ``ExponentialFitter`` (from ``\lambda * t`` to ``t / \lambda``). -.. _section-51: +.. _section-52: 0.19.0 - 2019-02-20 ^^^^^^^^^^^^^^^^^^^ @@ -1335,7 +1352,7 @@ API changes means that the *default* for alpha is set to 0.05 in the latest lifelines, instead of 0.95 in previous versions. -.. _bug-fixes-39: +.. _bug-fixes-40: Bug Fixes ''''''''' @@ -1352,7 +1369,7 @@ Bug Fixes models. Thanks @airanmehr! - Fixed some Pandas <0.24 bugs. -.. _section-52: +.. _section-53: 0.18.6 - 2019-02-13 ^^^^^^^^^^^^^^^^^^^ @@ -1362,7 +1379,7 @@ Bug Fixes ``rank`` and ``km`` p-values now. - some performance improvements to ``qth_survival_time``. -.. _section-53: +.. _section-54: 0.18.5 - 2019-02-11 ^^^^^^^^^^^^^^^^^^^ @@ -1383,7 +1400,7 @@ Bug Fixes that can be used to turn off variance calculations since this can take a long time for large datasets. Thanks @pzivich! -.. _section-54: +.. _section-55: 0.18.4 - 2019-02-10 ^^^^^^^^^^^^^^^^^^^ @@ -1393,7 +1410,7 @@ Bug Fixes - adding left-truncation support to parametric univarite models with the ``entry`` kwarg in ``.fit`` -.. _section-55: +.. _section-56: 0.18.3 - 2019-02-07 ^^^^^^^^^^^^^^^^^^^ @@ -1403,7 +1420,7 @@ Bug Fixes warnings are more noticeable. - Improved some warning and error messages. -.. _section-56: +.. _section-57: 0.18.2 - 2019-02-05 ^^^^^^^^^^^^^^^^^^^ @@ -1419,7 +1436,7 @@ Bug Fixes Moved them all (most) to use ``autograd``. - ``LogNormalFitter`` no longer models ``log_sigma``. -.. _section-57: +.. _section-58: 0.18.1 - 2019-02-02 ^^^^^^^^^^^^^^^^^^^ @@ -1430,7 +1447,7 @@ Bug Fixes - use the ``autograd`` lib to help with gradients. - New ``LogLogisticFitter`` univariate fitter available. -.. _section-58: +.. _section-59: 0.18.0 - 2019-01-31 ^^^^^^^^^^^^^^^^^^^ @@ -1467,7 +1484,7 @@ Bug Fixes ``LinAlgError: Matrix is singular.`` and report back to the user advice. -.. _section-59: +.. _section-60: 0.17.5 - 2019-01-25 ^^^^^^^^^^^^^^^^^^^ @@ -1475,7 +1492,7 @@ Bug Fixes - more bugs in ``plot_covariate_groups`` fixed when using non-numeric strata. -.. _section-60: +.. _section-61: 0.17.4 -2019-01-25 ^^^^^^^^^^^^^^^^^^ @@ -1487,7 +1504,7 @@ Bug Fixes - ``groups`` is now called ``values`` in ``CoxPHFitter.plot_covariate_groups`` -.. _section-61: +.. _section-62: 0.17.3 - 2019-01-24 ^^^^^^^^^^^^^^^^^^^ @@ -1495,7 +1512,7 @@ Bug Fixes - Fix in ``compute_residuals`` when using ``schoenfeld`` and the minumum duration has only censored subjects. -.. _section-62: +.. _section-63: 0.17.2 2019-01-22 ^^^^^^^^^^^^^^^^^ @@ -1506,7 +1523,7 @@ Bug Fixes ``for`` loop. The downside is the code is more esoteric now. I’ve added comments as necessary though 🤞 -.. _section-63: +.. _section-64: 0.17.1 - 2019-01-20 ^^^^^^^^^^^^^^^^^^^ @@ -1523,7 +1540,7 @@ Bug Fixes - Fixes a Pandas performance warning in ``CoxTimeVaryingFitter``. - Performances improvements to ``CoxTimeVaryingFitter``. -.. _section-64: +.. _section-65: 0.17.0 - 2019-01-11 ^^^^^^^^^^^^^^^^^^^ @@ -1544,7 +1561,7 @@ Bug Fixes - some plotting improvemnts to ``plotting.plot_lifetimes`` -.. _section-65: +.. _section-66: 0.16.3 - 2019-01-03 ^^^^^^^^^^^^^^^^^^^ @@ -1552,7 +1569,7 @@ Bug Fixes - More ``CoxPHFitter`` performance improvements. Up to a 40% reduction vs 0.16.2 for some datasets. -.. _section-66: +.. _section-67: 0.16.2 - 2019-01-02 ^^^^^^^^^^^^^^^^^^^ @@ -1563,14 +1580,14 @@ Bug Fixes has lots of duplicate times. See https://github.com/CamDavidsonPilon/lifelines/issues/591 -.. _section-67: +.. _section-68: 0.16.1 - 2019-01-01 ^^^^^^^^^^^^^^^^^^^ - Fixed py2 division error in ``concordance`` method. -.. _section-68: +.. _section-69: 0.16.0 - 2019-01-01 ^^^^^^^^^^^^^^^^^^^ @@ -1606,7 +1623,7 @@ Bug Fixes ``lifelines.utils.to_episodic_format``. - ``CoxTimeVaryingFitter`` now accepts ``strata``. -.. _section-69: +.. _section-70: 0.15.4 ^^^^^^ @@ -1614,14 +1631,14 @@ Bug Fixes - bug fix for the Cox model likelihood ratio test when using non-trivial weights. -.. _section-70: +.. _section-71: 0.15.3 - 2018-12-18 ^^^^^^^^^^^^^^^^^^^ - Only allow matplotlib less than 3.0. -.. _section-71: +.. _section-72: 0.15.2 - 2018-11-23 ^^^^^^^^^^^^^^^^^^^ @@ -1632,7 +1649,7 @@ Bug Fixes - removed ``entry`` from ``ExponentialFitter`` and ``WeibullFitter`` as it was doing nothing. -.. _section-72: +.. _section-73: 0.15.1 - 2018-11-23 ^^^^^^^^^^^^^^^^^^^ @@ -1641,7 +1658,7 @@ Bug Fixes - Raise NotImplementedError if the ``robust`` flag is used in ``CoxTimeVaryingFitter`` - that’s not ready yet. -.. _section-73: +.. _section-74: 0.15.0 - 2018-11-22 ^^^^^^^^^^^^^^^^^^^ @@ -1712,7 +1729,7 @@ Bug Fixes When Estimating Risks in Pharmacoepidemiology” for a nice overview of the model. -.. _section-74: +.. _section-75: 0.14.6 - 2018-07-02 ^^^^^^^^^^^^^^^^^^^ @@ -1720,7 +1737,7 @@ Bug Fixes - fix for n > 2 groups in ``multivariate_logrank_test`` (again). - fix bug for when ``event_observed`` column was not boolean. -.. _section-75: +.. _section-76: 0.14.5 - 2018-06-29 ^^^^^^^^^^^^^^^^^^^ @@ -1728,7 +1745,7 @@ Bug Fixes - fix for n > 2 groups in ``multivariate_logrank_test`` - fix weights in KaplanMeierFitter when using a pandas Series. -.. _section-76: +.. _section-77: 0.14.4 - 2018-06-14 ^^^^^^^^^^^^^^^^^^^ @@ -1745,7 +1762,7 @@ Bug Fixes - New ``delay`` parameter in ``add_covariate_to_timeline`` - removed ``two_sided_z_test`` from ``statistics`` -.. _section-77: +.. _section-78: 0.14.3 - 2018-05-24 ^^^^^^^^^^^^^^^^^^^ @@ -1757,7 +1774,7 @@ Bug Fixes - adds a ``column`` argument to ``CoxTimeVaryingFitter`` and ``CoxPHFitter`` ``plot`` method to plot only a subset of columns. -.. _section-78: +.. _section-79: 0.14.2 - 2018-05-18 ^^^^^^^^^^^^^^^^^^^ @@ -1765,7 +1782,7 @@ Bug Fixes - some quality of life improvements for working with ``CoxTimeVaryingFitter`` including new ``predict_`` methods. -.. _section-79: +.. _section-80: 0.14.1 - 2018-04-01 ^^^^^^^^^^^^^^^^^^^ @@ -1783,7 +1800,7 @@ Bug Fixes faster completion of ``fit`` for large dataframes, and up to 10% faster for small dataframes. -.. _section-80: +.. _section-81: 0.14.0 - 2018-03-03 ^^^^^^^^^^^^^^^^^^^ @@ -1805,7 +1822,7 @@ Bug Fixes of a ``RuntimeWarning`` - New checks for complete separation in the dataset for regressions. -.. _section-81: +.. _section-82: 0.13.0 - 2017-12-22 ^^^^^^^^^^^^^^^^^^^ @@ -1834,7 +1851,7 @@ Bug Fixes group the same subjects together and give that observation a weight equal to the count. Altogether, this means a much faster regression. -.. _section-82: +.. _section-83: 0.12.0 ^^^^^^ @@ -1851,7 +1868,7 @@ Bug Fixes - Additional functionality to ``utils.survival_table_from_events`` to bin the index to make the resulting table more readable. -.. _section-83: +.. _section-84: 0.11.3 ^^^^^^ @@ -1863,7 +1880,7 @@ Bug Fixes observation or censorship. - More accurate prediction methods parametrics univariate models. -.. _section-84: +.. _section-85: 0.11.2 ^^^^^^ @@ -1871,14 +1888,14 @@ Bug Fixes - Changing liscense to valilla MIT. - Speed up ``NelsonAalenFitter.fit`` considerably. -.. _section-85: +.. _section-86: 0.11.1 - 2017-06-22 ^^^^^^^^^^^^^^^^^^^ - Python3 fix for ``CoxPHFitter.plot``. -.. _section-86: +.. _section-87: 0.11.0 - 2017-06-21 ^^^^^^^^^^^^^^^^^^^ @@ -1892,14 +1909,14 @@ Bug Fixes of a new ``loc`` kwarg. This is to align with Pandas deprecating ``ix`` -.. _section-87: +.. _section-88: 0.10.1 - 2017-06-05 ^^^^^^^^^^^^^^^^^^^ - fix in internal normalization for ``CoxPHFitter`` predict methods. -.. _section-88: +.. _section-89: 0.10.0 ^^^^^^ @@ -1914,7 +1931,7 @@ Bug Fixes mimic R’s ``basehaz`` API. - new ``predict_log_partial_hazards`` to ``CoxPHFitter`` -.. _section-89: +.. _section-90: 0.9.4 ^^^^^ @@ -1937,7 +1954,7 @@ Bug Fixes - performance improvements in ``CoxPHFitter`` - should see at least a 10% speed improvement in ``fit``. -.. _section-90: +.. _section-91: 0.9.2 ^^^^^ @@ -1946,7 +1963,7 @@ Bug Fixes - throw an error if no admissable pairs in the c-index calculation. Previously a NaN was returned. -.. _section-91: +.. _section-92: 0.9.1 ^^^^^ @@ -1954,7 +1971,7 @@ Bug Fixes - add two summary functions to Weibull and Exponential fitter, solves #224 -.. _section-92: +.. _section-93: 0.9.0 ^^^^^ @@ -1970,7 +1987,7 @@ Bug Fixes - Default predict method in ``k_fold_cross_validation`` is now ``predict_expectation`` -.. _section-93: +.. _section-94: 0.8.1 - 2015-08-01 ^^^^^^^^^^^^^^^^^^ @@ -1987,7 +2004,7 @@ Bug Fixes - scaling of smooth hazards in NelsonAalenFitter was off by a factor of 0.5. -.. _section-94: +.. _section-95: 0.8.0 ^^^^^ @@ -2006,7 +2023,7 @@ Bug Fixes ``lifelines.statistics. power_under_cph``. - fixed a bug when using KaplanMeierFitter for left-censored data. -.. _section-95: +.. _section-96: 0.7.1 ^^^^^ @@ -2025,7 +2042,7 @@ Bug Fixes - refactor each fitter into it’s own submodule. For now, the tests are still in the same file. This will also *not* break the API. -.. _section-96: +.. _section-97: 0.7.0 - 2015-03-01 ^^^^^^^^^^^^^^^^^^ @@ -2044,7 +2061,7 @@ Bug Fixes duration remaining until the death event, given survival up until time t. -.. _section-97: +.. _section-98: 0.6.1 ^^^^^ @@ -2056,7 +2073,7 @@ Bug Fixes your work is to sum up the survival function (for expected values or something similar), it’s more difficult to make a mistake. -.. _section-98: +.. _section-99: 0.6.0 - 2015-02-04 ^^^^^^^^^^^^^^^^^^ @@ -2079,7 +2096,7 @@ Bug Fixes - In ``KaplanMeierFitter``, ``epsilon`` has been renamed to ``precision``. -.. _section-99: +.. _section-100: 0.5.1 - 2014-12-24 ^^^^^^^^^^^^^^^^^^ @@ -2100,7 +2117,7 @@ Bug Fixes ``lifelines.plotting.add_at_risk_counts``. - Fix bug Epanechnikov kernel. -.. _section-100: +.. _section-101: 0.5.0 - 2014-12-07 ^^^^^^^^^^^^^^^^^^ @@ -2113,7 +2130,7 @@ Bug Fixes - add test for summary() - Alternate metrics can be used for ``k_fold_cross_validation``. -.. _section-101: +.. _section-102: 0.4.4 - 2014-11-27 ^^^^^^^^^^^^^^^^^^ @@ -2125,7 +2142,7 @@ Bug Fixes - Fixes bug in 1-d input not returning in CoxPHFitter - Lots of new tests. -.. _section-102: +.. _section-103: 0.4.3 - 2014-07-23 ^^^^^^^^^^^^^^^^^^ @@ -2146,7 +2163,7 @@ Bug Fixes - Adds option ``include_likelihood`` to CoxPHFitter fit method to save the final log-likelihood value. -.. _section-103: +.. _section-104: 0.4.2 - 2014-06-19 ^^^^^^^^^^^^^^^^^^ @@ -2166,7 +2183,7 @@ Bug Fixes from failing so often (this a stop-gap) - pep8 everything -.. _section-104: +.. _section-105: 0.4.1.1 ^^^^^^^ @@ -2179,7 +2196,7 @@ Bug Fixes - Adding more robust cross validation scheme based on issue #67. - fixing ``regression_dataset`` in ``datasets``. -.. _section-105: +.. _section-106: 0.4.1 - 2014-06-11 ^^^^^^^^^^^^^^^^^^ @@ -2198,7 +2215,7 @@ Bug Fixes - Adding a Changelog. - more sanitizing for the statistical tests =) -.. _section-106: +.. _section-107: 0.4.0 - 2014-06-08 ^^^^^^^^^^^^^^^^^^ diff --git a/lifelines/fitters/__init__.py b/lifelines/fitters/__init__.py index 334927de8..8b8025635 100644 --- a/lifelines/fitters/__init__.py +++ b/lifelines/fitters/__init__.py @@ -2262,7 +2262,7 @@ def predict_cumulative_hazard(self, df, *, times=None, conditional_after=None): return pd.DataFrame( np.clip( self._cumulative_hazard(params_dict, times_to_evaluate_at, Xs) - - self._cumulative_hazard(params_dict, conditional_after, Xs), + - self._cumulative_hazard(params_dict, conditional_after.reshape(n), Xs), 0, np.inf, ), diff --git a/lifelines/fitters/coxph_fitter.py b/lifelines/fitters/coxph_fitter.py index ccfac6200..855a622b8 100644 --- a/lifelines/fitters/coxph_fitter.py +++ b/lifelines/fitters/coxph_fitter.py @@ -2368,38 +2368,9 @@ def predict_cumulative_hazard(self, df, *, times=None, conditional_after=None): the cumulative hazards of individuals over the timeline """ - if isinstance(df, pd.Series): - df = df.to_frame().T - - df = self._filter_dataframe_to_covariates(df).copy().astype(float) - - # this is needed for these models + df = df.copy() df["_intercept"] = 1 - - times = utils.coalesce(times, self.timeline) - times = np.atleast_1d(times).astype(float) - - n = df.shape[0] - Xs = self._create_Xs_dict(df) - - params_dict = {parameter_name: self.params_.loc[parameter_name].values for parameter_name in self._fitted_parameter_names} - - columns = utils._get_index(df) - if conditional_after is None: - return pd.DataFrame(self._cumulative_hazard(params_dict, np.tile(times, (n, 1)).T, Xs), index=times, columns=columns) - else: - conditional_after = np.asarray(conditional_after).reshape((n, 1)) - times_to_evaluate_at = (conditional_after + np.tile(times, (n, 1))).T - return pd.DataFrame( - np.clip( - self._cumulative_hazard(params_dict, times_to_evaluate_at, Xs) - - self._cumulative_hazard(params_dict, conditional_after, Xs), - 0, - np.inf, - ), - index=times, - columns=columns, - ) + return super(ParametricSplinePHFitter, self).predict_cumulative_hazard(df, times=None, conditional_after=None) def predict_hazard(self, df, *, times=None): """ diff --git a/lifelines/tests/test_statistics.py b/lifelines/tests/test_statistics.py index 759d23cd9..f38b73a29 100644 --- a/lifelines/tests/test_statistics.py +++ b/lifelines/tests/test_statistics.py @@ -321,7 +321,7 @@ def test_proportional_hazard_test_with_weights(): { "var1": [0.209325, 0.693919, 0.443804, 0.065636, 0.386294], "T": [5.269797, 6.601666, 7.335846, 11.684092, 12.678458], - "w": [1, 1, 1, 1, 1], + "w": [1, 0.5, 2, 1, 1], } ) df["E"] = True @@ -331,7 +331,7 @@ def test_proportional_hazard_test_with_weights(): results = stats.proportional_hazard_test(cph, df, time_transform=["km", "rank", "log", "identity"]) results.print_summary(5) - npt.assert_allclose(results.summary.loc["var1"]["test_statistic"], 0.000346, rtol=1e-3) + npt.assert_allclose(results.summary.loc["var1", "rank"]["test_statistic"], 0.108, rtol=1e-2) def test_proportional_hazard_test_with_strata_weights_and_strata(): @@ -347,6 +347,7 @@ def test_proportional_hazard_test_with_strata_weights_and_strata(): c = coxph(formula=Surv(T, E) ~ var1 + strata(s), data=df, weights=w) cz = cox.zph(c, transform='identity') + cz_km = cox.zph(c, transform='km') """ @@ -361,12 +362,14 @@ def test_proportional_hazard_test_with_strata_weights_and_strata(): df["E"] = True cph = CoxPHFitter() - cph.fit(df, "T", "E", weights_col="w", strata="s", robust=True) + cph.fit(df, "T", "E", weights_col="w", strata="s") results = stats.proportional_hazard_test(cph, df, time_transform="identity") - npt.assert_allclose(results.summary.loc["var1"]["test_statistic"], 0.0283, rtol=1e-3) + results = stats.proportional_hazard_test(cph, df, time_transform="km") + npt.assert_allclose(results.summary.loc["var1"]["test_statistic"], 0.0434, rtol=1e-1) + def test_proportional_hazard_test_with_kmf(): """ diff --git a/lifelines/version.py b/lifelines/version.py index 9f1464ef8..6ecfd8f82 100644 --- a/lifelines/version.py +++ b/lifelines/version.py @@ -1,4 +1,4 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -__version__ = "0.24.13" +__version__ = "0.24.14" From b46455b4cb3cfeb18995bacd54bb0ae471ad2680 Mon Sep 17 00:00:00 2001 From: CamDavidsonPilon Date: Thu, 2 Jul 2020 11:18:53 -0400 Subject: [PATCH 6/6] new test --- CHANGELOG.md | 2 +- docs/Changelog.rst | 2 +- lifelines/tests/test_estimation.py | 11 ++++++----- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1cbefd561..80725dc7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ ## Changelog -#### 0.24.13 - 2020-06-22 +#### 0.24.14 - 2020-07-02 ##### Bug fixes - fixed a bug where using `conditional_after` and `times` in prediction methods would result in a shape error diff --git a/docs/Changelog.rst b/docs/Changelog.rst index e5822db0c..b86d997ba 100644 --- a/docs/Changelog.rst +++ b/docs/Changelog.rst @@ -1,7 +1,7 @@ Changelog --------- -0.24.13 - 2020-06-22 +0.24.14 - 2020-07-02 ^^^^^^^^^^^^^^^^^^^^ Bug fixes diff --git a/lifelines/tests/test_estimation.py b/lifelines/tests/test_estimation.py index 7c2f10827..8dc91187e 100644 --- a/lifelines/tests/test_estimation.py +++ b/lifelines/tests/test_estimation.py @@ -1798,12 +1798,13 @@ def test_alpha_will_vary_the_statistics_in_summary(self, rossi): reg_010 = CoxPHFitter(baseline_estimation_method="spline", n_baseline_knots=2, alpha=0.10).fit(rossi, "week", "arrest") assert reg_005.summary.loc[("beta_", "fin"), "coef lower 95%"] < reg_010.summary.loc[("beta_", "fin"), "coef lower 90%"] + def test_spline_model_can_use_score(self, rossi): + cph_spline = CoxPHFitter(baseline_estimation_method="spline", n_baseline_knots=2) + cph_spline.fit(rossi, "week", "arrest") + cph_spline.score(rossi, scoring_method="log_likelihood") + def test_score_method_returns_same_value_for_unpenalized_models(self, rossi): - regression_models = [ - CoxPHFitter(), - WeibullAFTFitter(), - CoxPHFitter(baseline_estimation_method="spine", n_baseline_knots=2), - ] + regression_models = [CoxPHFitter(), WeibullAFTFitter()] for fitter in regression_models: fitter.fit(rossi, "week", "arrest") npt.assert_almost_equal(fitter.score(rossi, scoring_method="log_likelihood"), fitter.log_likelihood_ / rossi.shape[0])