JavaScript中的Cubic回归(最佳拟合线) [英] Cubic Regression (best fit line) in JavaScript

查看:319
本文介绍了JavaScript中的Cubic回归(最佳拟合线)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在努力寻找可以让我做立方回归的JavaScript代码。会自己写,但我对多项式数学的理解是不理想的。

I'm having the worst time trying to find a JavaScript code that could allow me to do cubic regressions. Would write it myself, but my understanding of polynomial math is, well, suboptimal.

所以,这就是我要找的东西。给定一个数组数组的输入,其中内部数组是[x,y],该函数将给出一个带有四个参数的数组形式的输出 - [a,b,c,d],其中a ,b,c和d是等式的参数y = ax ^ 3 + bx ^ 2 + cx + d。

So, here's what I'm looking for. Given an input of an array of arrays, where the internal array would be [x,y], the function would give me an output in the form of an array with four parameters - [a,b,c,d], where a, b, c, and d are parameters of the equation y = ax^3 + bx^2 + cx + d.

示例:
输入是一个这样的数组[[2,5],[5,10],[07,15],[12,20],[20,25],[32,30],[50,35]]。

Example: Input is an array like this [[2,5],[5,10],[07,15],[12,20],[20,25],[32,30],[50,35]].

基本上是表格的表示形式:

Which essentially is the representation of a table:


|    x   |   y    |
|-----------------|
|   02   |   05   |
|   05   |   10   |
|   07   |   15   |
|   12   |   20   |
|   20   |   25   |
|   32   |   30   |
|   50   |   35   |

现在,输出将是[0.000575085,-0.058861065,2.183957502,1.127605507]。这些是三次函数的a,b,c和d参数。

Now, the output would be [0.000575085,-0.058861065,2.183957502,1.127605507]. These are the a, b, c, and d parameters of the cubic function.

(仅供参考,我使用Excel的LINEST函数并在上面运行它得到的输出使用数组函数{1,2,3})的数字集。

(FYI, the output I got by using Excel's LINEST function and running it on the above set of numbers using an array function {1,2,3}).

如何做到这一点?非常感谢任何指导。

How could this be done? Huge thanks in advance for any guidance.

最好,
汤姆

推荐答案

这是使用 numeric.js 库解决该立方体的真实工作代码 uncmin 无约束最小化器作为最小二乘问题( jsbin here ):

Here's a real, working bit of code to solve that cubic using the numeric.js library's uncmin unconstrained minimiser as a least squares problem (jsbin here):

var data_x = [2,5,7,12,20,32,50];
var data_y = [5,10,15,20,25,30,35];

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]);
}

我得到的结果:

 0.0005750849851827991
-0.05886106462847641
 2.1839575020602164
 1.1276055079334206

要解释:我们有一个函数'cubic',它评估一组参数 params 的一般三次函数和一个值 X 。该函数被包装以创建目标函数,该函数接受一组参数并通过目标函数运行我们的数据集中的每个x值并计算平方和。此函数从numeric.js传递给 uncmin ,并带有一组初始值; uncmin 做了很多工作并返回一个解决方案属性包含优化参数集的对象。

To explain: we have a function 'cubic', which evaluates the general cubic function for a set of parameters params and a value x. This function is wrapped to create the objective function, which takes a set of params and runs each x value from our data set through the target function and calculates the sum of the squares. This function is passed to uncmin from numeric.js with a set of initial values; uncmin does the hard work and returns an object whose solution property contains the optimised parameter set.

要做到这一点而没有全局变量(顽皮!),你可以拥有一个目标函数工厂:

To do this without the global variables (naughty!), you can have an objective function factory thus:

var makeObjective = function(targetFunc,xlist,ylist) {
  var objective = function(params) {
    var total = 0.0;
    for(var i=0; i < xlist.length; ++i) {
      var resultThisDatum = targetFunc(params, xlist[i]);
      var delta = resultThisDatum - ylist[i];
      total += (delta*delta);
    }
    return total;
  };
  return objective;
};

您可以用它来制造目标函数:

Which you can use to manufacture objective functions:

var objective = makeObjective(cubic, data_x, data_y); // then carry on as before

知道如何做到这一点实际上会对我们有很大的帮助人们,所以我很高兴这已经出现了。

Knowing how to do this practically would be of great help to a lot of people, so I'm glad this has come up.

编辑:澄清立方

var cubic = function(params,x) {
  return params[0] * x*x*x +
    params[1] * x*x +
    params[2] * x +
    params[3];
};

Cubic被定义为一个函数,它接受一个参数数组 params 和值 x 。给定 params ,我们可以定义一个函数 f(x)。对于一个立方体,即 f(x)= ax ^ 3 + bx ^ 2 + cx + d 所以有4个参数( [0] [3] ),给定这4个参数值我们只有一个函数 f(x) 1输入 x

Cubic is being defined as a function which takes an array of parameters params and a value x. Given params, we can define a function f(x). For a cubic, that is f(x) = a x^3 + b x^2 + c x + d so there are 4 parameters ([0] to [3]), and given those 4 param values we have a single function f(x) with 1 input x.

该代码的结构允许您将 cubic 替换为具有相同结构的另一个函数;它可以是线性,带有2个参数:

The code is structured to allow you to replace cubic with another function of the same structure; it could be linear with 2 parameters:

var linear = function(params, x) {
    return params[0]*x + params[1];
};

其余代码将查看 params 为了知道需要修改多少个参数。

The rest of the code will look at the length of params in order to know how many parameters need modifying.

注意这整段代码试图找到产生曲线的参数值集合最适合所有数据;如果你想找到适合某些数据的最后4个点,你只能传递 data_x data_y

Note that this whole piece of code is trying to find the set of parameter values which produce a curve which best fits all the data; if you wanted to find a fit for the last 4 points of some data, you would pass only those values in data_x and data_y.

这篇关于JavaScript中的Cubic回归(最佳拟合线)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆