2

三次回帰を実行できる JavaScript コードを探すのに苦労しています。自分で書きますが、多項式の数学に関する私の理解は、まあ、最適ではありません。

だから、ここに私が探しているものがあります。内部配列が[x、y]である配列の配列の入力が与えられると、関数は[a、b、c、d]の4つのパラメーターを持つ配列の形式で出力を提供します。 、b、c、および d は、式 y = ax^3 + bx^2 + cx + d のパラメーターです。

例: 入力は次のような配列です [[2,5],[5,10],[07,15],[12,20],[20,25],[32,30],[50,35] ]。

これは本質的にテーブルの表現です:

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

これで、出力は [0.000575085,-0.058861065,2.183957502,1.127605507] になります。これらは、3 次関数の a、b、c、および d パラメーターです。

(参考までに、Excel の LINEST 関数を使用し、配列関数 {1,2,3} を使用して上記の数値セットで実行して得た出力)。

これはどのように行うことができますか?ご指導いただきありがとうございます。

ベスト、トム

4

2 に答える 2

4

これは、 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];
};

paramsCubic は、パラメーターの配列と値を取る関数として定義されていますx。が与えられればparams、関数を定義できますf(x)。キュービックの場合、つまりf(x) = a x^3 + b x^2 + c x + d4 つのパラメーター ( [0]to ) があり、これらの 4 つのパラメーター値が与えられると、1 つの input[3]を持つ単一の関数になります。f(x)x

cubicコードは、同じ構造の別の関数に置き換えることができるように構造化されています。それはlinear2つのパラメータである可能性があります:

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

paramsコードの残りの部分では、変更が必要なパラメーターの数を知るために、 の長さを調べます。

このコード全体が、すべてのデータに最適な曲線を生成するパラメーター値のセットを見つけようとしていることに注意してください。あるデータの最後の 4 点の適合を見つけたい場合は、それらの値のみをdata_xおよびに渡しますdata_y

于 2014-03-14T16:11:25.833 に答える
3

これを最小二乗問題として定式化します。Mをのように形成されたn ×4 行列とします。

x_1^3  x_1^2  x_1  1
x_2^3  x_2^2  x_2  1
  ⋮       ⋮      ⋮
x_n^3  x_n^2  x_n  1

次に、4×4 行列A = M T ⋅<i>M と 4×1 列ベクトルb = M T ⋅<i>y を計算し、線形連立方程式 = bを解きます。結果のベクトルξには、係数aからdが含まれます。

上記の説明により、数学的に何が起こっているのかを簡単に理解できます。ただし、実装の場合、特にnが非常に大きい場合、上記のアプローチは実行できない場合があります。そのような場合、Mを明示的に構築せずに、 Abを直接構築できます。たとえば、A 1,2 = . したがって、すべてのiを反復処理して、対応する値を対応する行列とベクトルのエントリに追加できます。sum(x_i^3 * x_i^2 for all i)

于 2014-03-11T09:17:19.190 に答える