piecewise-regression
Advanced tools
+4
-6
@@ -6,3 +6,3 @@ ========================================================== | ||
| :Author: Charlie Pilgrim | ||
| :Version: 1.2.1 | ||
| :Version: 1.3.0 | ||
| :Github: https://github.com/chasmani/piecewise-regression | ||
@@ -51,3 +51,3 @@ :Documentation: https://piecewise-regression.readthedocs.io/en/master/index.html | ||
| The package is tested on Python 3.7, 3.8 and 3.9. | ||
| The package is tested on Python 3.7, 3.8, 3.9 and 3.10. | ||
@@ -116,6 +116,4 @@ Getting started | ||
| Davies test for existence of at least 1 breakpoint: p=5.13032e-295 (e.g. p<0.05 means reject null hypothesis of no breakpoints at 5% significance) | ||
| This includes estimates for all the model variables, along with confidence intervals. NOTE: The Davies hypothesis test for the existence of at least one breakpoint is not reported, and is under development and testing. | ||
| This includes estimates for all the model variables, along with confidence intervals. The Davies test is a hypothesis test for the existence of at least one breakpoint, against the null hypothesis of no breakpoints. | ||
| 3. Optional: Plotting the data and model results: :: | ||
@@ -202,3 +200,3 @@ | ||
| There are also a series of simulation tests that check the estimates have realistic confidence intervals, and the Davies test gives realistic p-values. These can be found in the folder "tests-manual". | ||
| There are also a series of simulation tests that check the estimates have realistic confidence intervals. These can be found in the folder "tests-manual". | ||
@@ -205,0 +203,0 @@ Requirements |
| Metadata-Version: 2.1 | ||
| Name: piecewise-regression | ||
| Version: 1.2.1 | ||
| Version: 1.3.0 | ||
| Summary: piecewise (segmented) regression in python | ||
@@ -9,3 +9,2 @@ Home-page: https://github.com/chasmani/piecewise-regression | ||
| License: MIT | ||
| Platform: UNKNOWN | ||
| Classifier: License :: OSI Approved :: MIT License | ||
@@ -16,2 +15,3 @@ Classifier: Programming Language :: Python :: 3 | ||
| Classifier: Programming Language :: Python :: 3.9 | ||
| Classifier: Programming Language :: Python :: 3.10 | ||
| Description-Content-Type: text/markdown | ||
@@ -21,2 +21,1 @@ License-File: LICENSE.txt | ||
| piecewise-regression provides tools for fitting continuous straight line models to data with breakpoint(s) where the gradient changes. For docs and more information, visit the Github repo at https://github.com/chasmani/piecewise-regression. | ||
@@ -7,3 +7,2 @@ LICENSE.txt | ||
| piecewise_regression/data_validation.py | ||
| piecewise_regression/davies.py | ||
| piecewise_regression/main.py | ||
@@ -10,0 +9,0 @@ piecewise_regression/model_selection.py |
| from .main import Fit, Muggeo | ||
| from .model_selection import ModelSelection | ||
| from .davies import davies_test | ||
| __all__ = ['Fit', 'Muggeo', 'ModelSelection', 'davies_test'] | ||
| __all__ = ['Fit', 'Muggeo', 'ModelSelection'] |
@@ -10,3 +10,2 @@ | ||
| try: | ||
| import piecewise_regression.davies as davies | ||
| import piecewise_regression.r_squared_calc as r_squared_calc | ||
@@ -21,3 +20,2 @@ from piecewise_regression.data_validation import ( | ||
| except ImportError: | ||
| import davies | ||
| import r_squared_calc | ||
@@ -716,4 +714,2 @@ from data_validation import ( | ||
| self.davies = davies.davies_test(self.xx, self.yy) | ||
| def get_results(self): | ||
@@ -724,5 +720,3 @@ """ | ||
| """ | ||
| results = { | ||
| "davies": self.davies, | ||
| } | ||
| results = {} | ||
@@ -1119,10 +1113,4 @@ if self.best_muggeo: | ||
| davies_result = ( | ||
| "Davies test for existence of at least " | ||
| "1 breakpoint: p={:.6} (e.g. p<0.05 means reject null " | ||
| "hypothesis of no breakpoints " | ||
| " at 5% significance)".format(self.davies)) | ||
| summary = header + overview + table + "\n\n" | ||
| summary = header + overview + table + davies_result + "\n\n" | ||
| print(summary) | ||
@@ -1129,0 +1117,0 @@ |
+2
-3
| Metadata-Version: 2.1 | ||
| Name: piecewise-regression | ||
| Version: 1.2.1 | ||
| Version: 1.3.0 | ||
| Summary: piecewise (segmented) regression in python | ||
@@ -9,3 +9,2 @@ Home-page: https://github.com/chasmani/piecewise-regression | ||
| License: MIT | ||
| Platform: UNKNOWN | ||
| Classifier: License :: OSI Approved :: MIT License | ||
@@ -16,2 +15,3 @@ Classifier: Programming Language :: Python :: 3 | ||
| Classifier: Programming Language :: Python :: 3.9 | ||
| Classifier: Programming Language :: Python :: 3.10 | ||
| Description-Content-Type: text/markdown | ||
@@ -21,2 +21,1 @@ License-File: LICENSE.txt | ||
| piecewise-regression provides tools for fitting continuous straight line models to data with breakpoint(s) where the gradient changes. For docs and more information, visit the Github repo at https://github.com/chasmani/piecewise-regression. | ||
+2
-1
@@ -6,3 +6,3 @@ import setuptools | ||
| name="piecewise-regression", | ||
| version="1.2.1", | ||
| version="1.3.0", | ||
| description="piecewise (segmented) regression in python", | ||
@@ -27,2 +27,3 @@ long_description= "piecewise-regression provides tools for fitting " | ||
| "Programming Language :: Python :: 3.9", | ||
| "Programming Language :: Python :: 3.10", | ||
| ], | ||
@@ -29,0 +30,0 @@ packages=setuptools.find_packages(), |
@@ -352,3 +352,2 @@ from piecewise_regression.main import Fit, Muggeo | ||
| summary = fit.summary() | ||
| self.assertIn('Davies', summary) | ||
| self.assertIn('Model Parameters', summary) | ||
@@ -355,0 +354,0 @@ self.assertIn('Degrees of Freedom', summary) |
| import numpy as np | ||
| import scipy | ||
| import math | ||
| def get_test_statistic(xx_davies, yy_davies, theta): | ||
| """ | ||
| Compute a test statistic for the Davies test for the p-value of existence | ||
| of a breakpoint. Based on Davies(1987) "Hypothesis Testing when a nuisance | ||
| parameter is present only under the alternative". | ||
| All the variables in this function are as named and described in that | ||
| paper. | ||
| :param xx_davies: Data series in x-axis (same axis as the breakpoints). | ||
| :type xx_davies: list of floats | ||
| :param yy_davies: Data series in y-axis. | ||
| :type yy_davies: list of floats | ||
| :param theta: A test value from within the range of data in xx | ||
| :type theta: float | ||
| """ | ||
| n = len(xx_davies) | ||
| s_0 = 0 | ||
| s_1 = 0 | ||
| s_2 = 0 | ||
| s_3 = 0 | ||
| s_4 = 0 | ||
| for x in xx_davies: | ||
| s_0 += x**2 | ||
| if x > theta: | ||
| s_1 += x * (x - theta) | ||
| s_3 += x - theta | ||
| elif x < theta: | ||
| s_2 += x * (x - theta) | ||
| s_4 += x - theta | ||
| a_hat = np.sum(yy_davies) / n | ||
| b_hat = np.sum(xx_davies * yy_davies) / s_0 | ||
| V = s_1 * s_2 / s_0 + s_3 * s_4 / n | ||
| S = 0 | ||
| for i in range(n): | ||
| if xx_davies[i] > theta: | ||
| S += (yy_davies[i] - a_hat - b_hat * xx_davies[i]) * \ | ||
| (xx_davies[i] - theta) | ||
| S = S / (np.sqrt(np.abs(V))) | ||
| return S | ||
| def davies_test(xx, yy, k=10, alternative="two_sided"): | ||
| """ | ||
| Significance test for the existence of a breakpoint | ||
| Null hypothesis is that there is no breakpoint, or that the change in | ||
| gradient is zero. | ||
| Alternative hypothesis is that there is a breakpoint, with a non-zero | ||
| change in gradient. | ||
| The change is gradient is a function of the breakpoint position. | ||
| The breakpoint posiition is a nuisannce parameter that only exists in the | ||
| alternative hypothesis. | ||
| Based on Davies (1987), "Hypothesis Testing when a nuisance parameter is | ||
| present only under the alternative". | ||
| :param xx: Data series in x-axis (same axis as the breakpoints). | ||
| :type xx: list of floats | ||
| :param yy: Data series in y-axis. | ||
| :type yy: list of floats | ||
| :param k: A control parameter that determines the number of points to | ||
| consider within the xx range. | ||
| :type k: int | ||
| :param alternative: Whether to consider a two-sided hypothesis test, | ||
| or a one sided test with change of gradient greater or less than zero. | ||
| For existence of a breakpoint, use "two-sided". | ||
| :type alternative: str. One of "two_sided", "less", "greater" | ||
| """ | ||
| # Centre the x values - makes no difference to existence of a breakpoint | ||
| # The Davies test has this as an assumption | ||
| xx_davies = xx - np.mean(xx) | ||
| yy_davies = yy | ||
| # As in Muggeo's R package "segmented", cut from second to second to last | ||
| # data point | ||
| # Need more data in the xx than in [L,U] for the test to work | ||
| L = xx_davies[1] | ||
| U = xx_davies[-2] | ||
| # More thetas is better | ||
| thetas = np.linspace(L, U, k) | ||
| # For each value of theta, compute a test statistic | ||
| test_stats = [] | ||
| for theta in thetas: | ||
| test_stat = get_test_statistic(xx_davies, yy_davies, theta) | ||
| test_stats.append(test_stat) | ||
| if alternative == "two_sided": | ||
| # Two sided test, M as defined by Davies | ||
| M = np.max(np.abs(test_stats)) | ||
| elif alternative == "less": | ||
| M = np.abs(np.min(test_stats)) | ||
| elif alternative == "greater": | ||
| M = np.max(test_stats) | ||
| # Use formulas from Davies | ||
| V = 0 | ||
| for i in range(len(thetas) - 1): | ||
| V += np.abs(test_stats[i + 1] - test_stats[i]) | ||
| p = scipy.stats.norm.cdf(-M) + V * np.exp(-.5 * M ** | ||
| 2) * 1 / (np.sqrt(8 * math.pi)) | ||
| if alternative == "two_sided": | ||
| return p * 2 | ||
| else: | ||
| return p |
Alert delta unavailable
Currently unable to show alert delta for PyPI packages.
104595
-4.08%24
-4%1953
-5.29%