Skip to content

Instantly share code, notes, and snippets.

@jgphilpott
Last active November 19, 2022 08:00
Show Gist options
  • Save jgphilpott/d38279e8fac9af31054e10b7363bf17e to your computer and use it in GitHub Desktop.
Save jgphilpott/d38279e8fac9af31054e10b7363bf17e to your computer and use it in GitHub Desktop.
A collection of functions for performing and evaluating polynomial regression in JavaScript.
# Find the best-fit curve for an nth order polynomial.
# Credit: https://stackoverflow.com/a/28301054/1544937
# Requirement: https://github.com/sloisel/numeric/blob/master/src/numeric.js
polyfit = (xArray, yArray, order) ->
matrix = []
if xArray.length <= order
console.warn "Warning: Polyfit may be poorly conditioned."
for value in xArray
powers = []
for power in [0 ... order + 1]
powers.push Math.pow value, power
matrix.push powers
xMatrixT = numeric.transpose matrix
yMatrixT = numeric.transpose [yArray]
dot1 = numeric.dot xMatrixT, matrix
dot2 = numeric.dot xMatrixT, yMatrixT
dotInv = numeric.inv dot1
coefficients = numeric.dot dotInv, dot2
return coefficients
# Evaluate model accuracy.
rSquared = (xArray, yArray, coefficients) ->
yMean = yArray.reduce((a, b) -> a + b) / yArray.length
regressionSquaredError = 0
totalSquaredError = 0
for index in [0 ... xArray.length]
regressionSquaredError += Math.pow yArray[index] - predict(xArray[index], coefficients), 2
totalSquaredError += Math.pow yArray[index] - yMean, 2
return 1 - (regressionSquaredError / totalSquaredError)
# Predict y given x.
predict = (x, coefficients) ->
prediction = 0
for coefficient, index in coefficients
prediction += coefficient * Math.pow x, index
return prediction
// Generated by CoffeeScript 2.7.0
var polyfit, predict, rSquared;
// Find the best-fit curve for an nth order polynomial.
// Credit: https://stackoverflow.com/a/28301054/1544937
// Requirement: https://github.com/sloisel/numeric/blob/master/src/numeric.js
polyfit = function(xArray, yArray, order) {
var coefficients, dot1, dot2, dotInv, i, j, len, matrix, power, powers, ref, value, xMatrixT, yMatrixT;
matrix = [];
if (xArray.length <= order) {
console.warn("Warning: Polyfit may be poorly conditioned.");
}
for (i = 0, len = xArray.length; i < len; i++) {
value = xArray[i];
powers = [];
for (power = j = 0, ref = order + 1; (0 <= ref ? j < ref : j > ref); power = 0 <= ref ? ++j : --j) {
powers.push(Math.pow(value, power));
}
matrix.push(powers);
}
xMatrixT = numeric.transpose(matrix);
yMatrixT = numeric.transpose([yArray]);
dot1 = numeric.dot(xMatrixT, matrix);
dot2 = numeric.dot(xMatrixT, yMatrixT);
dotInv = numeric.inv(dot1);
coefficients = numeric.dot(dotInv, dot2);
return coefficients;
};
// Evaluate model accuracy.
rSquared = function(xArray, yArray, coefficients) {
var i, index, ref, regressionSquaredError, totalSquaredError, yMean;
yMean = yArray.reduce(function(a, b) {
return a + b;
}) / yArray.length;
regressionSquaredError = 0;
totalSquaredError = 0;
for (index = i = 0, ref = xArray.length; (0 <= ref ? i < ref : i > ref); index = 0 <= ref ? ++i : --i) {
regressionSquaredError += Math.pow(yArray[index] - predict(xArray[index], coefficients), 2);
totalSquaredError += Math.pow(yArray[index] - yMean, 2);
}
return 1 - (regressionSquaredError / totalSquaredError);
};
// Predict y given x.
predict = function(x, coefficients) {
var coefficient, i, index, len, prediction;
prediction = 0;
for (index = i = 0, len = coefficients.length; i < len; index = ++i) {
coefficient = coefficients[index];
prediction += coefficient * Math.pow(x, index);
}
return prediction;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment