Linear Regression Least Squares Fit
Fit a least-squares line to x/y points and return slope, intercept, R-squared and a prediction function with validation.
Code
export interface Point {
x: number;
y: number;
}
export interface RegressionResult {
slope: number;
intercept: number;
rSquared: number;
predict: (x: number) => number;
}
export function linearRegression(points: readonly Point[]): RegressionResult {
if (!Array.isArray(points) || points.length < 2) {
throw new RangeError("points must contain at least two items");
}
for (const point of points) {
if (!Number.isFinite(point.x) || !Number.isFinite(point.y)) {
throw new TypeError("points must contain finite coordinates");
}
}
const count = points.length;
const meanX = points.reduce((total, point) => total + point.x, 0) / count;
const meanY = points.reduce((total, point) => total + point.y, 0) / count;
let numerator = 0;
let denominator = 0;
let total = 0;
for (const point of points) {
const dx = point.x - meanX;
const dy = point.y - meanY;
numerator += dx * dy;
denominator += dx * dx;
total += dy * dy;
}
if (denominator === 0) throw new RangeError("x values must not all be equal");
const slope = numerator / denominator;
const intercept = meanY - slope * meanX;
const rSquared = total === 0 ? 1 : (numerator * numerator) / (denominator * total);
return { slope, intercept, rSquared, predict: (x) => intercept + slope * x };
}Report a problem with this exampleOpens a pre-filled issue on GitHub.