Skip to content

Instantly share code, notes, and snippets.

@gyaikhom
Last active August 29, 2015 14:11
Show Gist options
  • Save gyaikhom/317b0b1bf9860f2ecfb4 to your computer and use it in GitHub Desktop.
Save gyaikhom/317b0b1bf9860f2ecfb4 to your computer and use it in GitHub Desktop.
Implements linear regression
/* Copyright 2014 Gagarine Yaikhom (MIT License)
*
* Implements linear regression.
* (see https://www.khanacademy.org for derivation)
*/
function linear_regression(datapoints) {
var sum_x, sum_y, sum_x_2, sum_xy, mean_x, mean_y,
m, b, n, i, d, result, se_mean, se_line;
result = undefined;
if (datapoints instanceof Array) {
n = datapoints.length;
if (n < 2)
throw RangeError("Not enough data points");
sum_x = sum_y = sum_x_2 = sum_xy = 0;
for (i = 0; i < n; ++i) {
d = datapoints[i];
if (typeof d.x !== "number")
throw TypeError("Supplied x-axis value '" + d.x
+ "' is not a number");
if (typeof d.y !== "number")
throw TypeError("Supplied y-axis value '" + d.y
+ "' is not a number");
sum_x += d.x;
sum_y += d.y;
sum_x_2 += d.x * d.x;
sum_xy += d.x * d.y;
}
mean_x = sum_x / n;
mean_y = sum_y / n;
d = mean_x * mean_x - sum_x_2 / n;
if (d === 0)
throw EvalError("Linear regression is undefined");
m = (mean_x * mean_y - sum_xy / n) / d;
b = mean_y - m * mean_x;
/* coefficient of determination: R^2 */
se_mean = se_line = 0;
for (i = 0; i < n; ++i) {
d = datapoints[i];
se_mean += Math.pow(mean_y - d.y, 2);
se_line += Math.pow(m * d.x + b - d.y, 2);
}
result = {
'm': m,
'b': b,
'R': 1 - se_line / se_mean
};
} else
throw TypeError("Supplied input is not an array");
return result;
}
function print_line(coefficients) {
var str = "y = ";
if (coefficients === undefined)
throw TypeError("Supplied coefficients is undefined");
else {
if (coefficients.m !== 0)
str += coefficients.m + "x";
if (coefficients.b !== 0) {
if (coefficients.m !== 0) {
str += (coefficients.b > 0 ? " + " : " - ");
str += Math.abs(coefficients.b);
} else
str += coefficients.b;
}
if (!isNaN(coefficients.R))
str += ", R^2 = " + coefficients.R;
console.log(str);
}
}
function test() {
var datapoints = [
[
{ 'x': 1, 'y': 1},
{ 'x': 2, 'y': 2},
{ 'x': 3, 'y': 3},
{ 'x': 4, 'y': 4},
{ 'x': 5, 'y': 5},
{ 'x': 6, 'y': 6},
{ 'x': 7, 'y': 7},
{ 'x': 8, 'y': 8},
{ 'x': 9, 'y': 9},
{ 'x':10, 'y':10}
],
[
{ 'x': 1, 'y':20},
{ 'x': 2, 'y':18},
{ 'x': 3, 'y':16},
{ 'x': 4, 'y':14},
{ 'x': 5, 'y':12},
{ 'x': 6, 'y':10},
{ 'x': 7, 'y': 8},
{ 'x': 8, 'y': 6},
{ 'x': 9, 'y': 4},
{ 'x':10, 'y': 2}
],
[
{ 'x': 1, 'y': 2},
{ 'x': 2, 'y': 1},
{ 'x': 4, 'y': 3}
],
[
{ 'x': 1, 'y': 2},
{ 'x': 2, 'y': 2},
{ 'x': 4, 'y': 2}
],
[
{ 'x': "Apple", 'y': "Orange"},
{ 'x': 0, 'y': 4},
{ 'x': 0, 'y': 6},
{ 'x': 0, 'y': 8}
],
[
{ 'x': 0, 'y': 2},
{ 'x': 0, 'y': 4},
{ 'x': 0, 'y': 6},
{ 'x': 0, 'y': 8},
{ 'x': 0, 'y':10}
]];
for (var i = 0, n = datapoints.length; i < n; ++i) {
try {
print_line(linear_regression(datapoints[i]));
} catch (x) {
console.error(x.message);
}
}
}
test();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment