这是使用numeric.js库的uncmin
无约束最小化器作为最小二乘问题(此处为 jsbin )来解决该三次方的真实有效代码:
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 值,并计算平方和。这个函数uncmin
从 numeric.js 传递给一组初始值;uncmin
做艰苦的工作并返回一个对象,其solution
属性包含优化的参数集。
要在没有全局变量的情况下执行此操作(淘气!),您可以拥有一个目标函数工厂:
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;
};
您可以使用它来制造目标函数:
var objective = makeObjective(cubic, data_x, data_y); // then carry on as before
知道如何实际执行此操作将对很多人有很大帮助,所以我很高兴这个问题出现了。
编辑:澄清cubic
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) = a x^3 + b x^2 + c x + d
因此有 4 个参数 ( [0]
to [3]
),并且给定这 4 个参数值,我们有一个f(x)
带有 1 个输入的函数x
。
代码的结构允许您cubic
用相同结构的另一个函数替换;它可能linear
有2个参数:
var linear = function(params, x) {
return params[0]*x + params[1];
};
其余代码将查看 的长度,params
以便了解需要修改多少参数。
请注意,这整段代码试图找到一组参数值,这些参数值产生一条最适合所有数据的曲线;如果您想找到适合某些数据的最后 4 个点的值,您只需将这些值传递到data_x
and中data_y
。