16

我以前使用 Math.NET Numerics 库的Fit.Polynomial方法来拟合一组数据的三次多项式,这些数据可以建模为一个参数的函数y=f(x)
现在我想类似地找到一个适合数据的 2 或 3 阶多项式,该数据可以根据多个参数建模为函数y=f(x1, x2, x3, x4)

Math.NET 中是否已经有一个可以计算该多项式的内置函数?
如果没有,您是否看到我可以如何操纵我的数据以将其提交给 Fit.Polynomial?

4

3 回答 3

14

该类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)

于 2014-01-03T09:49:20.657 回答
5

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<double> 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();
    }
于 2015-02-12T16:54:08.320 回答
1

请注意,线性模型中的x也可以是向量x=[x1 x2 ⋯ xk]并且任意函数fi(x)可以接受向量而不是标量。
几乎是您想要的东西。

于 2018-02-07T08:11:20.087 回答