Slope and intercept for simple linear regression. Return the slope and intercept of simple linear regression parameters estimated using ordinary least squares. Simple linear regression describes relationship between an independent variable *x* and a dependent variable *y* in terms o
(x, y, /, *, proportional=False)
| 742 | |
| 743 | |
| 744 | def linear_regression(x, y, /, *, proportional=False): |
| 745 | """Slope and intercept for simple linear regression. |
| 746 | |
| 747 | Return the slope and intercept of simple linear regression |
| 748 | parameters estimated using ordinary least squares. Simple linear |
| 749 | regression describes relationship between an independent variable |
| 750 | *x* and a dependent variable *y* in terms of a linear function: |
| 751 | |
| 752 | y = slope * x + intercept + noise |
| 753 | |
| 754 | where *slope* and *intercept* are the regression parameters that are |
| 755 | estimated, and noise represents the variability of the data that was |
| 756 | not explained by the linear regression (it is equal to the |
| 757 | difference between predicted and actual values of the dependent |
| 758 | variable). |
| 759 | |
| 760 | The parameters are returned as a named tuple. |
| 761 | |
| 762 | >>> x = [1, 2, 3, 4, 5] |
| 763 | >>> noise = NormalDist().samples(5, seed=42) |
| 764 | >>> y = [3 * x[i] + 2 + noise[i] for i in range(5)] |
| 765 | >>> linear_regression(x, y) #doctest: +ELLIPSIS |
| 766 | LinearRegression(slope=3.17495..., intercept=1.00925...) |
| 767 | |
| 768 | If *proportional* is true, the independent variable *x* and the |
| 769 | dependent variable *y* are assumed to be directly proportional. |
| 770 | The data is fit to a line passing through the origin. |
| 771 | |
| 772 | Since the *intercept* will always be 0.0, the underlying linear |
| 773 | function simplifies to: |
| 774 | |
| 775 | y = slope * x + noise |
| 776 | |
| 777 | >>> y = [3 * x[i] + noise[i] for i in range(5)] |
| 778 | >>> linear_regression(x, y, proportional=True) #doctest: +ELLIPSIS |
| 779 | LinearRegression(slope=2.90475..., intercept=0.0) |
| 780 | |
| 781 | """ |
| 782 | # https://en.wikipedia.org/wiki/Simple_linear_regression |
| 783 | n = len(x) |
| 784 | if len(y) != n: |
| 785 | raise StatisticsError('linear regression requires that both inputs have same number of data points') |
| 786 | if n < 2: |
| 787 | raise StatisticsError('linear regression requires at least two data points') |
| 788 | |
| 789 | if not proportional: |
| 790 | xbar = fsum(x) / n |
| 791 | ybar = fsum(y) / n |
| 792 | x = [xi - xbar for xi in x] # List because used three times below |
| 793 | y = (yi - ybar for yi in y) # Generator because only used once below |
| 794 | |
| 795 | sxy = sumprod(x, y) + 0.0 # Add zero to coerce result to a float |
| 796 | sxx = sumprod(x, x) |
| 797 | |
| 798 | try: |
| 799 | slope = sxy / sxx # equivalent to: covariance(x, y) / variance(x) |
| 800 | except ZeroDivisionError: |
| 801 | raise StatisticsError('x is constant') |
nothing calls this directly
no test coverage detected