ml-regression-simple-linear
Advanced tools
Comparing version 2.0.3 to 2.0.4
221
lib/index.js
@@ -1,86 +0,145 @@ | ||
'use strict'; | ||
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } | ||
var BaseRegression = require('ml-regression-base'); | ||
var BaseRegression__default = _interopDefault(BaseRegression); | ||
class SimpleLinearRegression extends BaseRegression__default { | ||
constructor(x, y) { | ||
super(); | ||
if (x === true) { | ||
this.slope = y.slope; | ||
this.intercept = y.intercept; | ||
this.coefficients = [y.intercept, y.slope]; | ||
} else { | ||
BaseRegression.checkArrayLength(x, y); | ||
regress(this, x, y); | ||
"use strict"; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
var desc = Object.getOwnPropertyDescriptor(m, k); | ||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
desc = { enumerable: true, get: function() { return m[k]; } }; | ||
} | ||
} | ||
toJSON() { | ||
return { | ||
name: 'simpleLinearRegression', | ||
slope: this.slope, | ||
intercept: this.intercept, | ||
}; | ||
} | ||
_predict(x) { | ||
return this.slope * x + this.intercept; | ||
} | ||
computeX(y) { | ||
return (y - this.intercept) / this.slope; | ||
} | ||
toString(precision) { | ||
let result = 'f(x) = '; | ||
if (this.slope !== 0) { | ||
const xFactor = BaseRegression.maybeToPrecision(this.slope, precision); | ||
result += `${xFactor === '1' ? '' : `${xFactor} * `}x`; | ||
if (this.intercept !== 0) { | ||
const absIntercept = Math.abs(this.intercept); | ||
const operator = absIntercept === this.intercept ? '+' : '-'; | ||
result += ` ${operator} ${BaseRegression.maybeToPrecision(absIntercept, precision)}`; | ||
} | ||
} else { | ||
result += BaseRegression.maybeToPrecision(this.intercept, precision); | ||
} | ||
Object.defineProperty(o, k2, desc); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | ||
Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
}) : function(o, v) { | ||
o["default"] = v; | ||
}); | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
} | ||
toLaTeX(precision) { | ||
return this.toString(precision); | ||
} | ||
static load(json) { | ||
if (json.name !== 'simpleLinearRegression') { | ||
throw new TypeError('not a SLR model'); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const ml_regression_base_1 = __importStar(require("ml-regression-base")); | ||
/** | ||
* Class representing simple linear regression. | ||
* The regression uses OLS to calculate intercept and slope. | ||
*/ | ||
class SimpleLinearRegression extends ml_regression_base_1.default { | ||
/** | ||
* @param x - explanatory variable | ||
* @param y - response variable | ||
*/ | ||
constructor(x, y) { | ||
super(); | ||
// @ts-expect-error internal use of the constructor, from `this.load` | ||
if (x === true) { | ||
// @ts-expect-error internal use of the constructor, from `this.load` | ||
const yObj = y; | ||
this.slope = yObj.slope; | ||
this.intercept = yObj.intercept; | ||
this.coefficients = [yObj.intercept, yObj.slope]; | ||
} | ||
else { | ||
(0, ml_regression_base_1.checkArrayLength)(x, y); | ||
const result = regress(x, y); | ||
this.slope = result.slope; | ||
this.intercept = result.intercept; | ||
this.coefficients = [result.intercept, result.slope]; | ||
} | ||
} | ||
return new SimpleLinearRegression(true, json); | ||
} | ||
/** | ||
* Get the parameters and model name in JSON format | ||
* @returns | ||
*/ | ||
toJSON() { | ||
return { | ||
name: 'simpleLinearRegression', | ||
slope: this.slope, | ||
intercept: this.intercept, | ||
}; | ||
} | ||
_predict(x) { | ||
return this.slope * x + this.intercept; | ||
} | ||
/** | ||
* Finds x for the given y value. | ||
* @param y - response variable value | ||
* @returns - x value | ||
*/ | ||
computeX(y) { | ||
return (y - this.intercept) / this.slope; | ||
} | ||
/** | ||
* Strings the linear function in the form 'f(x) = ax + b' | ||
* @param precision - number of significant figures. | ||
* @returns | ||
*/ | ||
toString(precision) { | ||
let result = 'f(x) = '; | ||
if (this.slope !== 0) { | ||
const xFactor = (0, ml_regression_base_1.maybeToPrecision)(this.slope, precision); | ||
result += `${xFactor === '1' ? '' : `${xFactor} * `}x`; | ||
if (this.intercept !== 0) { | ||
const absIntercept = Math.abs(this.intercept); | ||
const operator = absIntercept === this.intercept ? '+' : '-'; | ||
result += ` ${operator} ${(0, ml_regression_base_1.maybeToPrecision)(absIntercept, precision)}`; | ||
} | ||
} | ||
else { | ||
result += (0, ml_regression_base_1.maybeToPrecision)(this.intercept, precision); | ||
} | ||
return result; | ||
} | ||
/** | ||
* Strings the linear function in the form 'f(x) = ax + b' | ||
* @param precision - number of significant figures. | ||
* @returns | ||
*/ | ||
toLaTeX(precision) { | ||
return this.toString(precision); | ||
} | ||
/** | ||
* Class instance from a JSON Object. | ||
* @param json | ||
* @returns | ||
*/ | ||
static load(json) { | ||
if (json.name !== 'simpleLinearRegression') { | ||
throw new TypeError('not a SLR model'); | ||
} | ||
// @ts-expect-error internal use of the constructor | ||
return new SimpleLinearRegression(true, json); | ||
} | ||
} | ||
function regress(slr, x, y) { | ||
const n = x.length; | ||
let xSum = 0; | ||
let ySum = 0; | ||
let xSquared = 0; | ||
let xY = 0; | ||
for (let i = 0; i < n; i++) { | ||
xSum += x[i]; | ||
ySum += y[i]; | ||
xSquared += x[i] * x[i]; | ||
xY += x[i] * y[i]; | ||
} | ||
const numerator = n * xY - xSum * ySum; | ||
slr.slope = numerator / (n * xSquared - xSum * xSum); | ||
slr.intercept = (1 / n) * ySum - slr.slope * (1 / n) * xSum; | ||
slr.coefficients = [slr.intercept, slr.slope]; | ||
exports.default = SimpleLinearRegression; | ||
/** | ||
* Internal function. | ||
* It determines the parameters (slope, intercept) of the line that best fit the `x,y` vector-data (simple linear regression). | ||
* @param x - explanatory variable | ||
* @param y - response variable | ||
* @returns - slope and intercept of the best fit line | ||
*/ | ||
function regress(x, y) { | ||
const n = x.length; | ||
let xSum = 0; | ||
let ySum = 0; | ||
let xSquared = 0; | ||
let xY = 0; | ||
for (let i = 0; i < n; i++) { | ||
xSum += x[i]; | ||
ySum += y[i]; | ||
xSquared += x[i] * x[i]; | ||
xY += x[i] * y[i]; | ||
} | ||
const numerator = n * xY - xSum * ySum; | ||
const slope = numerator / (n * xSquared - xSum * xSum); | ||
return { | ||
slope, | ||
intercept: (1 / n) * ySum - slope * (1 / n) * xSum, | ||
}; | ||
} | ||
module.exports = SimpleLinearRegression; | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "ml-regression-simple-linear", | ||
"version": "2.0.3", | ||
"version": "2.0.4", | ||
"description": "Simple Linear Regression", | ||
"main": "lib/index.js", | ||
"module": "src/index.js", | ||
"types": "regression-simple-linear.d.ts", | ||
"main": "./lib/index.js", | ||
"module": "./lib-esm/index.js", | ||
"types": "./lib/index.d.ts", | ||
"sideEffects": false, | ||
"files": [ | ||
"regression-simple-linear.d.ts", | ||
"lib", | ||
"lib-esm", | ||
"src" | ||
], | ||
"scripts": { | ||
"compile": "rollup -c", | ||
"check-types": "tsc --noEmit", | ||
"clean": "rimraf lib lib-esm", | ||
"eslint": "eslint src", | ||
"eslint-fix": "npm run eslint -- --fix", | ||
"prepublishOnly": "npm run compile", | ||
"test": "npm run test-coverage && npm run eslint", | ||
"test-only": "jest", | ||
"test-coverage": "jest --coverage" | ||
"prepack": "npm run tsc", | ||
"prettier": "prettier --check src", | ||
"prettier-write": "prettier --write src", | ||
"test": "npm run test-only && npm run eslint && npm run prettier && npm run check-types", | ||
"test-only": "vitest --coverage --run", | ||
"tsc": "npm run clean && npm run tsc-cjs && npm run tsc-esm", | ||
"tsc-cjs": "tsc --project tsconfig.cjs.json", | ||
"tsc-esm": "tsc --project tsconfig.esm.json" | ||
}, | ||
@@ -27,3 +32,7 @@ "repository": { | ||
}, | ||
"keywords": [], | ||
"keywords": [ | ||
"linear regression", | ||
"least squares", | ||
"linear fit" | ||
], | ||
"author": "Michaël Zasso", | ||
@@ -35,17 +44,15 @@ "license": "MIT", | ||
"homepage": "https://github.com/mljs/regression-simple-linear#readme", | ||
"jest": { | ||
"testEnvironment": "node" | ||
}, | ||
"devDependencies": { | ||
"@babel/plugin-transform-modules-commonjs": "^7.4.4", | ||
"eslint": "^5.16.0", | ||
"eslint-config-cheminfo": "^1.20.1", | ||
"eslint-plugin-import": "^2.17.2", | ||
"eslint-plugin-jest": "^22.5.1", | ||
"jest": "^24.7.1", | ||
"rollup": "^1.10.1" | ||
"@vitest/coverage-v8": "^0.34.1", | ||
"eslint": "^8.47.0", | ||
"eslint-config-cheminfo-typescript": "^12.0.4", | ||
"prettier": "^3.0.1", | ||
"rimraf": "^5.0.1", | ||
"typescript": "^5.1.6", | ||
"vitest": "^0.34.1" | ||
}, | ||
"dependencies": { | ||
"ml-regression-base": "^2.0.1" | ||
"cheminfo-types": "^1.7.2", | ||
"ml-regression-base": "^3.0.0" | ||
} | ||
} |
# regression-simple-linear | ||
[![NPM version][npm-image]][npm-url] | ||
[![build status][travis-image]][travis-url] | ||
[![npm download][download-image]][download-url] | ||
[![NPM version][npm-image]][npm-url] | ||
[![build status][ci-image]][ci-url] | ||
[![npm download][download-image]][download-url] | ||
[![codecov][codecov-image]][codecov-url] | ||
@@ -23,5 +24,5 @@ Simple Linear Regression. | ||
regression.slope // 2 | ||
regression.intercept // -1 | ||
regression.coefficients // [-1, 2] | ||
regression.slope; // 2 | ||
regression.intercept; // -1 | ||
regression.coefficients; // [-1, 2] | ||
@@ -39,3 +40,3 @@ regression.predict(3); // 5 | ||
const loaded = SimpleLinearRegression.load(json); | ||
loaded.predict(5) // 9 | ||
loaded.predict(5); // 9 | ||
``` | ||
@@ -45,9 +46,11 @@ | ||
[MIT](./LICENSE) | ||
[MIT](./LICENSE) | ||
[npm-image]: https://img.shields.io/npm/v/ml-regression-simple-linear.svg?style=flat-square | ||
[npm-url]: https://npmjs.org/package/ml-regression-simple-linear | ||
[travis-image]: https://img.shields.io/travis/mljs/regression-simple-linear/master.svg?style=flat-square | ||
[travis-url]: https://travis-ci.org/mljs/regression-simple-linear | ||
[ci-image]: https://github.com/mljs/regression-simple-linear/workflows/Node.js%20CI/badge.svg?branch=master | ||
[ci-url]: https://github.com/mljs/regression-simple-linear/actions?query=workflow%3A%22Node.js+CI%22 | ||
[download-image]: https://img.shields.io/npm/dm/ml-regression-simple-linear.svg?style=flat-square | ||
[download-url]: https://npmjs.org/package/ml-regression-simple-linear | ||
[codecov-image]: https://img.shields.io/codecov/c/github/mljs/regression-simple-linear.svg | ||
[codecov-url]: https://codecov.io/gh/mljs/regression-simple-linear |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
30937
13
591
54
2
2
+ Addedcheminfo-types@^1.7.2
+ Addedcheminfo-types@1.8.1(transitive)
+ Addedml-regression-base@3.0.0(transitive)
- Removedml-regression-base@2.1.6(transitive)
Updatedml-regression-base@^3.0.0