UNPKG

locutus

Version:

Locutus other languages' standard libraries to JavaScript for fun and educational purposes

54 lines (53 loc) 2.59 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.linear_regression = linear_regression; const _statistics_ts_1 = require("../_helpers/_statistics.js"); function linear_regression(x, y, proportional = false) { // discuss at: https://locutus.io/python/statistics/linear_regression/ // parity verified: Python 3.12 // original by: Kevin van Zonneveld (https://kvz.io) // note 1: Returns ordinary least-squares slope and intercept, mirroring Python's named tuple as a plain object. // example 1: linear_regression([1, 2, 3], [2, 4, 6]) // returns 1: {slope: 2, intercept: 0} // example 2: linear_regression([1, 2, 3], [1, 2, 2]) // returns 2: {slope: 0.5, intercept: 0.6666666666666667} // example 3: linear_regression([1, 2, 3], [2, 4, 6], true) // returns 3: {slope: 2, intercept: 0} const xValues = (0, _statistics_ts_1.assertStatisticsArray)(x, 'linear_regression').map((value) => (0, _statistics_ts_1.toStatisticNumber)(value, 'linear_regression')); const yValues = (0, _statistics_ts_1.assertStatisticsArray)(y, 'linear_regression').map((value) => (0, _statistics_ts_1.toStatisticNumber)(value, 'linear_regression')); const n = xValues.length; if (yValues.length !== n) { throw new Error('linear regression requires that both inputs have same number of data points'); } if (n < 2) { throw new Error('linear regression requires at least two data points'); } if (proportional) { const sxy = (0, _statistics_ts_1.sumProducts)(xValues, yValues) + 0; const sxx = (0, _statistics_ts_1.sumProducts)(xValues, xValues); if (sxx === 0) { throw new Error('x is constant'); } return { slope: sxy / sxx, intercept: 0 }; } const xbar = (0, _statistics_ts_1.statisticsMeanFromSequence)({ values: xValues, integral: xValues.every(Number.isInteger), }); const ybar = (0, _statistics_ts_1.statisticsMeanFromSequence)({ values: yValues, integral: yValues.every(Number.isInteger), }); const centeredX = xValues.map((value) => value - xbar); const centeredY = yValues.map((value) => value - ybar); const sxy = (0, _statistics_ts_1.sumProducts)(centeredX, centeredY) + 0; const sxx = (0, _statistics_ts_1.sumProducts)(centeredX, centeredX); if (sxx === 0) { throw new Error('x is constant'); } const slope = sxy / sxx; return { slope, intercept: ybar - slope * xbar, }; }