web-dev-qa-db-ja.com

複数のパラメーターの関数でMath.NETのFit.Polynomialメソッドを使用する

以前、Math.NET Numericsライブラリの Fit.Polynomial メソッドを使用して、1つのパラメーターy=f(x)の関数としてモデル化できるデータのセットに3次多項式を当てはめました。
次に、複数のパラメータy=f(x1, x2, x3, x4)に応じて関数としてモデル化できるデータに適合する2次または3次の多項式を同様に見つけたいと思います。

その多項式を計算できるMath.NETの組み込み関数はすでにありますか?
そうでない場合、Fit.Polynomialに送信するためにデータをどのように操作できるかわかりますか?

16
wip

Fitクラスは、ほとんどのシナリオで十分なファサードにすぎませんが、常にアルゴリズムを直接使用して、必要なものを正確に取得できます。

Fit.Polynomial:高次の多項式曲線フィッティングは、数値的には少し問題があるため、最後にパラメーターを調整/調整するための特殊なアルゴリズムとルーチンが開発されました。ただし、Math.NET Numericsは今のところQR分解を使用しているだけです(ただし、ある時点で実装を置き換える予定です)。

public static double[] Polynomial(double[] x, double[] y, int order)
{
    var design = Matrix<double>.Build.Dense(x.Length, order + 1, (i, j) => Math.Pow(x[i], j));
    return MultipleRegression.QR(design, Vector<double>.Build.Dense(y)).ToArray();
}

一方、Fit.MultiDimはデフォルトで正規方程式を使用します。これは、QR分解よりはるかに高速ですが、数値的にロバストではありません。このため、この方法では精度が低下します。

public static double[] MultiDim(double[][] x, double[] y)
{
    return MultipleRegression.NormalEquations(x, y);
}

あなたのケースでは、MultipleRegressionクラスをQR(十分な場合)またはSvd(さらに堅牢性が必要な場合;非常に遅い)で直接使用しようとします遅すぎる場合は、ネイティブプロバイダーの使用を検討してください)):

var x1 = new double[] { ... };
var x2 = new double[] { ... };
var y = new double[] { ... };

var design = Matrix<double>.Build.DenseOfRowArrays(
    Generate.Map2(x1,x2,(x1, x2) => new double[] { x1*x1, x1, x2*x2, x2, 1d }));
double[] p = MultipleRegression.QR(design, Vector<double>.Build.Dense(y)).ToArray();

(Math.NET Numerics v3.0.0-alpha7を使用)

14

RosettaCode は、多項式回帰のためのこのソリューションを提案します(- Math.Net を使用):

    public static double[] Polyfit(double[] x, double[] y, int degree)
    {
        // Vandermonde matrix
        var v = new DenseMatrix(x.Length, degree + 1);
        for (int i = 0; i < v.RowCount; i++)
            for (int j = 0; j <= degree; j++) v[i, j] = Math.Pow(x[i], j);
        var yv = new DenseVector(y).ToColumnMatrix();
        QR qr = v.QR();
        // Math.Net doesn't have an "economy" QR, so:
        // cut R short to square upper triangle, then recompute Q
        var r = qr.R.SubMatrix(0, degree + 1, 0, degree + 1);
        var q = v.Multiply(r.Inverse());
        var p = r.Inverse().Multiply(q.TransposeThisAndMultiply(yv));
        return p.Column(0).ToArray();
    }
4
Matthieu

線形モデルのxは、ベクトルx = [x1 x2⋯xk]および任意の関数fi(x)は、スカラーの代わりにベクトルを受け入れることができます。
ここ はあなたが望むものに近いものです。

1
GntS