I'm trying to calculate a best-fit curve for data using a 3-6 order polynomial. I found this tutorial: Cubic Regression (best fit line) in JavaScript
First, I can't seem to get my outputs to remotely match the curve. jsbin here: http://jsbin.com/qukuqigobu/1/edit?html,js,console,output
var data_x = [500,1000,1500,2000,2500,3000,3500,4000,4500,5000,5500,6000,6500,7000];
var data_y = [50,80,100,160,210,265,340,390,440,470,500,500,495,460];
var cubic = function(params,x) {
return params[0] * x*x*x +
params[1] * x*x +
params[2] * x +
params[3];
};
var objective = function(params) {
var total = 0.0;
for(var i=0; i < data_x.length; ++i) {
var resultThisDatum = cubic(params, data_x[i]);
var delta = resultThisDatum - data_y[i];
total += (delta*delta);
}
return total;
};
var initial = [1,1,1,1];
var minimiser = numeric.uncmin(objective,initial);
console.log("initial:");
for(var j=0; j<initial.length; ++j) {
console.log(initial[j]);
}
console.log("minimiser:");
for(var j=0; j<minimiser.solution.length; ++j) {
console.log(minimiser.solution[j]);
}
My output coefficients are:
1
-17358.001260500238
80977844.06724495
-96625621220.328
However, using LINEST in excel, they are:
-4.68257E-09
4.26789E-05
-0.01
45.39760539
I calculated Y values from the Xs in Excel using this to confirm a good correlation. The minimizer results do not work.
This is the first step, but ideally I'd want to be able to do the same thing for 4th, 5th and 6th order polynomials as well.
Any help would be much appreciated. Thanks.
To perfectly fit a polynomial to data points, an order polynomial is required. To restate slightly differently, any set of points can be modeled by a polynomial of order . It can be shown that such a polynomial exists and that there is only one polynomial that exactly fits those points.
Fit Polynomial to Set of Points In general, for n points, you can fit a polynomial of degree n-1 to exactly pass through the points. p = polyfit(x,y,4); Evaluate the original function and the polynomial fit on a finer grid of points between 0 and 2. x1 = linspace(0,2); y1 = 1./(1+x1); f1 = polyval(p,x1);
We can choose the degree of polynomial based on the relationship between target and predictor. The 1-degree polynomial is a simple linear regression; therefore, the value of degree must be greater than 1. With the increasing degree of the polynomial, the complexity of the model also increases.
Figured it out using Matrix Algebra:
var x = [500,1000,1500,2000,2500,3000,3500,4000,4500,5000,5500,6000,6500,7000];
var y = [50,80,100,160,210,265,340,390,440,470,500,500,495,460];
order = 3;
var xMatrix = [];
var xTemp = [];
var yMatrix = numeric.transpose([y]);
for (j=0;j<x.length;j++)
{
xTemp = [];
for(i=0;i<=order;i++)
{
xTemp.push(1*Math.pow(x[j],i));
}
xMatrix.push(xTemp);
}
var xMatrixT = numeric.transpose(xMatrix);
var dot1 = numeric.dot(xMatrixT,xMatrix);
var dotInv = numeric.inv(dot1);
var dot2 = numeric.dot(xMatrixT,yMatrix);
var solution = numeric.dot(dotInv,dot2);
console.log("Coefficients a + bx^1 + cx^2...")
console.log(solution);
jsbin: http://jsbin.com/yoqiqanofo/1/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With