JavaScript中的Cubic回归(最佳拟合线) [英] Cubic Regression (best fit line) in JavaScript
问题描述
我正在努力寻找可以让我做立方回归的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 $的长度c $ c>为了知道需要修改多少个参数。
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 $ c $中的那些值c>。
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屋!