C#中的非线性回归 [英] Non-linear regression in C#

查看:33
本文介绍了C#中的非线性回归的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种基于 2D 数据集生成非线性(最好是二次)曲线的方法,用于预测目的.现在我正在使用我自己的普通最小二乘法 (OLS) 实现来产生线性趋势,但我的趋势更适合曲线模型.我正在分析的数据是随时间推移的系统负载.

I'm looking for a way to produce a non-linear (preferably quadratic) curve, based on a 2D data set, for predictive purposes. Right now I'm using my own implementation of ordinary least squares (OLS) to produce a linear trend, but my trends are much more suited to a curve model. The data I'm analysing is system load over time.

这是我用来产生线性系数的方程:

Here's the equation that I'm using to produce my linear coefficients:

我看过 Math.NET Numerics 和其他一些库,但它们要么提供插值而不是回归(这对我来说没有用),或者代码在某些方面不起作用.

I've had a look at Math.NET Numerics and a few other libs, but they either provide interpolation instead of regression (which is of no use to me), or the code just doesn't work in some way.

有谁知道任何免费的开源库或代码示例可以生成这样一条曲线的系数?

Anyone know of any free open source libs or code samples that can produce the coefficients for such a curve?

推荐答案

我使用了MathNet.Iridium 发布,因为它与 .NET 3.5 和 VS2008 兼容.该方法基于 Vandermonde 矩阵.然后我创建了一个类来保存我的多项式回归

I used the MathNet.Iridium release because it is compatible with .NET 3.5 and VS2008. The method is based on the Vandermonde matrix. Then I created a class to hold my polynomial regression

using MathNet.Numerics.LinearAlgebra;

public class PolynomialRegression
{
    Vector x_data, y_data, coef;
    int order;

    public PolynomialRegression(Vector x_data, Vector y_data, int order)
    {
        if (x_data.Length != y_data.Length)
        {
            throw new IndexOutOfRangeException();
        }
        this.x_data = x_data;
        this.y_data = y_data;
        this.order = order;
        int N = x_data.Length;
        Matrix A = new Matrix(N, order + 1);
        for (int i = 0; i < N; i++)
        {
            A.SetRowVector( VandermondeRow(x_data[i]) , i);
        }

        // Least Squares of |y=A(x)*c| 
        //  tr(A)*y = tr(A)*A*c
        //  inv(tr(A)*A)*tr(A)*y = c
        Matrix At = Matrix.Transpose(A);
        Matrix y2 = new Matrix(y_data, N);
        coef = (At * A).Solve(At * y2).GetColumnVector(0);
    }

    Vector VandermondeRow(double x)
    {
        double[] row = new double[order + 1];
        for (int i = 0; i <= order; i++)
        {
            row[i] = Math.Pow(x, i);
        }
        return new Vector(row);
    }

    public double Fit(double x)
    {
        return Vector.ScalarProduct( VandermondeRow(x) , coef);
    }

    public int Order { get { return order; } }
    public Vector Coefficients { get { return coef; } }
    public Vector XData { get { return x_data; } }
    public Vector YData { get { return y_data; } }
}

然后我像这样使用它:

using MathNet.Numerics.LinearAlgebra;

class Program
{
    static void Main(string[] args)
    {
        Vector x_data = new Vector(new double[] { 0, 1, 2, 3, 4 });
        Vector y_data = new Vector(new double[] { 1.0, 1.4, 1.6, 1.3, 0.9 });

        var poly = new PolynomialRegression(x_data, y_data, 2);

        Console.WriteLine("{0,6}{1,9}", "x", "y");
        for (int i = 0; i < 10; i++)
        {
            double x = (i * 0.5);
            double y = poly.Fit(x);

            Console.WriteLine("{0,6:F2}{1,9:F4}", x, y);
        }
    }
}

计算[1,0.57,-0.15]的系数与输出:

    x        y
 0.00   1.0000
 0.50   1.2475
 1.00   1.4200
 1.50   1.5175
 2.00   1.5400
 2.50   1.4875
 3.00   1.3600
 3.50   1.1575
 4.00   0.8800
 4.50   0.5275

哪个匹配 二次 结果来自 Wolfram Alpha.

Which matches the quadratic results from Wolfram Alpha.

编辑 1为了达到合适的效果,请尝试对 x_datay_data 进行以下初始化:

Edit 1 To get to the fit you want try the following initialization for x_data and y_data:

Matrix points = new Matrix( new double[,] {  {  1, 82.96 }, 
               {  2, 86.23 }, {  3, 87.09 }, {  4, 84.28 }, 
               {  5, 83.69 }, {  6, 89.18 }, {  7, 85.71 }, 
               {  8, 85.05 }, {  9, 85.58 }, { 10, 86.95 }, 
               { 11, 87.95 }, { 12, 89.44 }, { 13, 93.47 } } );
Vector x_data = points.GetColumnVector(0);
Vector y_data = points.GetColumnVector(1);

产生以下系数(从最低到最高)

which produces the following coefficients (from lowest power to highest)

Coef=[85.892,-0.5542,0.074990]
     x        y
  0.00  85.8920
  1.00  85.4127
  2.00  85.0835
  3.00  84.9043
  4.00  84.8750
  5.00  84.9957
  6.00  85.2664
  7.00  85.6871
  8.00  86.2577
  9.00  86.9783
 10.00  87.8490
 11.00  88.8695
 12.00  90.0401
 13.00  91.3607
 14.00  92.8312

这篇关于C#中的非线性回归的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆