如何使用 MathNet 库进行非线性回归?

问题描述 投票:0回答:1

我正在尝试使用 MathNet 库来计算基于非线性回归的曲线拟合。

using System;
using System.Linq;
using MathNet.Numerics;
using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.Optimization;

class NonLinearRegressionExample
{
    static void Main()
    {
        // Example data points
        double[] xdata = new double[] { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0 };
        double[] ydata = new double[] { 1.0, 2.7, 5.8, 6.6, 7.5, 9.9 };

        // Define the model function
        Func<Vector<double>, double, double> modelFunc = (parameters, x) =>
            parameters[0] * Math.Exp(parameters[1] * x);

        // Objective function: sum of squared residuals
        Func<Vector<double>, double> objectiveFunction = (parameters) =>
        {
            double sumOfSquares = 0;
            for (int i = 0; i < xdata.Length; i++)
            {
                double error = ydata[i] - modelFunc(parameters, xdata[i]);
                sumOfSquares += error * error;
            }
            return sumOfSquares;
        };

        // Gradient of the objective function (if it's not provided, you'll need to implement this)
        Func<Vector<double>, Vector<double>> gradientFunction = (parameters) =>
        {
            // You'll need to implement the gradient here
            throw new NotImplementedException("Gradient function is not implemented.");
        };

        // Initial guess for parameters a and b
        var initialGuess = Vector<double>.Build.DenseOfArray(new double[] { 1.0, 0.1 });

        // Create the objective function without a gradient
        var objective = ObjectiveFunction.Value(objectiveFunction) as IObjectiveModel;
        

        // Use a Levenberg-Marquardt optimizer for minimization
        var optimizer = new LevenbergMarquardtMinimizer();

        // Minimize the objective function starting from the initial guess
        var result = optimizer.FindMinimum(objective, initialGuess);

        // Output the results
        if (result.MinimizingPoint.Count == 2)
        {
            Console.WriteLine("Fitted parameters:");
            Console.WriteLine($"a = {result.MinimizingPoint[0]}");
            Console.WriteLine($"b = {result.MinimizingPoint[1]}");
        }
    }
}

但是,我遇到以下异常:

System.ArgumentNullException: 'Value cannot be null.
Parameter name: objective'

我该如何修复它?

c# curve-fitting non-linear-regression mathnet-numerics
1个回答
0
投票

我给你写了一条评论,因为你的异常是错误的函数/模型(ObjectiveFunction.Value 返回一个带有接口 IObjectiveFunction 的对象)。最小化器需要了解您的模型才能最小化函数参数。我使用 Levenberg Marquardt 最小化器将您的数据放入下面的一段工作代码中,经过 18 次迭代后它似乎在我的系统上收敛。

using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.LinearAlgebra.Double;
using MathNet.Numerics.Optimization;

// example data
var xData = new DenseVector(new double[] { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0 });
var yData = new DenseVector(new double[] { 1.0, 2.7, 5.8, 6.6, 7.5, 9.9 });

Vector<double> Model(Vector<double> parameters, Vector<double> x)
{
    var y = CreateVector.Dense<double>(x.Count);    
    for (int i = 0; i < x.Count; i++)
    {    
        y[i] = parameters[0] * Math.Exp(parameters[1] * x[i]);
    }
    return y;        
}

var start = new DenseVector(new double[] { 1.0, 0.1 });
var objective = ObjectiveFunction.NonlinearModel(Model, xData, yData);
var solver = new LevenbergMarquardtMinimizer(maximumIterations: 10000);
var result = solver.FindMinimum(objective, start);
© www.soinside.com 2019 - 2024. All rights reserved.