これは、 numeric.jsライブラリのuncmin
制約のないミニマイザーを最小二乗問題 ( jsbin here )として使用して、その 3 次を解くための実際に機能するコードです。
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
と値に対して一般的な 3 次関数を評価します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];
};
params
Cubic は、パラメーターの配列と値を取る関数として定義されていますx
。が与えられればparams
、関数を定義できますf(x)
。キュービックの場合、つまりf(x) = a x^3 + b x^2 + c x + d
4 つのパラメーター ( [0]
to ) があり、これらの 4 つのパラメーター値が与えられると、1 つの input[3]
を持つ単一の関数になります。f(x)
x
cubic
コードは、同じ構造の別の関数に置き換えることができるように構造化されています。それはlinear
2つのパラメータである可能性があります:
var linear = function(params, x) {
return params[0]*x + params[1];
};
params
コードの残りの部分では、変更が必要なパラメーターの数を知るために、 の長さを調べます。
このコード全体が、すべてのデータに最適な曲線を生成するパラメーター値のセットを見つけようとしていることに注意してください。あるデータの最後の 4 点の適合を見つけたい場合は、それらの値のみをdata_x
およびに渡しますdata_y
。