C#语言实现最小二乘法算法

 最小二乘法(Least Squares Method)是一种常用的拟合方法,用于在数据点之间找到最佳的直线(或其他函数)拟合。以下是一个用C#实现简单线性回归(即一元最小二乘法)的示例代码。

1. 最小二乘法简介

对于一组数据点 (x1,y1),(x2,y2),…,(xn,yn)(x_1, y_1), (x_2, y_2), \ldots, (x_n, y_n)(x1​,y1​),(x2​,y2​),…,(xn​,yn​),最小二乘法通过最小化误差平方和来找到最佳拟合直线 y=ax+by = ax + by=ax+b,其中:

  • aaa 是斜率
  • bbb 是截距

误差平方和 SSS 定义为:

S=∑i=1n(yi−(axi+b))2S = \sum_{i=1}^{n} (y_i - (ax_i + b))^2S=∑i=1n​(yi​−(axi​+b))2

通过求导并设导数为零,可以得到斜率 aaa 和截距 bbb 的公式:

a=n∑xiyi−∑xi∑yin∑xi2−(∑xi)2a = \frac{n\sum{x_i y_i} - \sum{x_i}\sum{y_i}}{n\sum{x_i^2} - (\sum{x_i})^2}a=n∑xi2​−(∑xi​)2n∑xi​yi​−∑xi​∑yi​​ b=∑yi−a∑xinb = \frac{\sum{y_i} - a\sum{x_i}}{n}b=n∑yi​−a∑xi​​

2. C#实现代码

using System;
using System.Collections.Generic;
using System.Linq;

namespace LeastSquaresMethod
{
    class Program
    {
        static void Main(string[] args)
        {
            // 示例数据点
            List<DataPoint> dataPoints = new List<DataPoint>
            {
                new DataPoint(1, 2),
                new DataPoint(2, 3),
                new DataPoint(3, 5),
                new DataPoint(4, 4),
                new DataPoint(5, 6)
            };

            // 计算最小二乘法拟合结果
            var result = LeastSquaresFit(dataPoints);

            Console.WriteLine($"拟合直线: y = {result.Slope:F4}x + {result.Intercept:F4}");

            // 可选:计算拟合优度(R²)
            double rSquared = CalculateRSquared(dataPoints, result.Slope, result.Intercept);
            Console.WriteLine($"拟合优度 (R²): {rSquared:F4}");
        }

        // 数据点结构
        public class DataPoint
        {
            public double X { get; set; }
            public double Y { get; set; }

            public DataPoint(double x, double y)
            {
                X = x;
                Y = y;
            }
        }

        // 拟合结果结构
        public class FitResult
        {
            public double Slope { get; set; }
            public double Intercept { get; set; }
        }

        // 最小二乘法拟合函数
        public static FitResult LeastSquaresFit(List<DataPoint> points)
        {
            int n = points.Count;
            double sumX = points.Sum(p => p.X);
            double sumY = points.Sum(p => p.Y);
            double sumXY = points.Sum(p => p.X * p.Y);
            double sumX2 = points.Sum(p => p.X * p.X);

            double denominator = n * sumX2 - sumX * sumX;
            if (denominator == 0)
            {
                throw new InvalidOperationException("无法计算拟合参数,因为分母为零。");
            }

            double slope = (n * sumXY - sumX * sumY) / denominator;
            double intercept = (sumY - slope * sumX) / n;

            return new FitResult { Slope = slope, Intercept = intercept };
        }

        // 计算拟合优度 R²
        public static double CalculateRSquared(List<DataPoint> points, double slope, double intercept)
        {
            double meanY = points.Average(p => p.Y);
            double ssTot = points.Sum(p => Math.Pow(p.Y - meanY, 2));
            double ssRes = points.Sum(p => Math.Pow(p.Y - (slope * p.X + intercept), 2));

            return 1 - (ssRes / ssTot);
        }
    }
}

3. 代码说明

  1. 数据结构:

    • DataPoint 类用于存储单个数据点的 xxx 和 yyy 值。
    • FitResult 类用于存储拟合直线的斜率和截距。
  2. LeastSquaresFit 方法:

    • 计算所需的各类求和,如 ∑x\sum{x}∑x、∑y\sum{y}∑y、∑xy\sum{xy}∑xy 和 ∑x2\sum{x^2}∑x2。
    • 使用最小二乘法公式计算斜率 aaa 和截距 bbb。
    • 返回包含斜率和截距的 FitResult 对象。
  3. CalculateRSquared 方法:

    • 计算拟合优度 R2R^2R2,表示模型对数据的解释程度。
    • R2R^2R2 值越接近1,表示拟合效果越好。
  4. Main 方法:

    • 创建示例数据点。
    • 调用 LeastSquaresFit 方法进行拟合。
    • 输出拟合直线方程。
    • 计算并输出拟合优度 R2R^2R2。

4. 运行结果示例

运行上述代码,可能得到如下输出:

拟合直线: y = 0.8000x + 1.2000
拟合优度 (R²): 0.8205

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C#是一种面向对象的编程语言,它具有强大的功能和广泛的应用领域。最小二乘法是一种常用的数学方法,用于拟合曲线并找到最佳拟合参数。在C#中,可以使用数值计算库或者自己实现最小二乘法算法来进行曲线拟合。 以下是使用C#实现最小二乘法拟合曲线的一般步骤: 1. 收集数据:首先需要收集一组数据点,包括自变量和因变量的取值。 2. 定义模型函数:根据实际情况,选择适当的模型函数来描述数据的关系。例如,可以选择线性函数、多项式函数或者其他非线性函数作为模型。 3. 构建矩阵方程:将数据点代入模型函数,得到一个矩阵方程。该方程可以表示为 Y = X * β,其中 Y 是因变量的向量,X 是自变量的矩阵,β 是待求的参数向量。 4. 求解参数:通过最小二乘法,可以求解出参数向量 β 的最佳估计值。这可以通过求解正规方程(Normal Equation)或者使用矩阵分解方法(如QR分解)来实现。 5. 拟合曲线:使用求解得到的参数向量,将自变量代入模型函数,得到拟合曲线的预测值。 下面是一个简单的C#代码示例,演示如何使用最小二乘法拟合一条直线: ```csharp using System; using MathNet.Numerics.LinearAlgebra; class Program { static void Main() { // 收集数据 double[] xData = { 1, 2, 3, 4, 5 }; double[] yData = { 2, 4, 6, 8, 10 }; // 构建矩阵方程 Matrix<double> X = Matrix<double>.Build.DenseOfColumnArrays(xData); Matrix<double> Y = Matrix<double>.Build.DenseOfColumnArrays(yData); // 求解参数 Vector<double> beta = X.TransposeAndMultiply(X).Inverse() * X.TransposeAndMultiply(Y); // 输出参数估计值 Console.WriteLine("参数估计值:"); Console.WriteLine("beta0 = " + beta[0]); Console.WriteLine("beta1 = " + beta[1]); // 拟合曲线 Console.WriteLine("拟合曲线:"); for (int i = 0; i < xData.Length; i++) { double yPredict = beta[0] + beta[1] * xData[i]; Console.WriteLine("x = " + xData[i] + ", y = " + yPredict); } } } ``` 这段代码使用了MathNet.Numerics库来进行矩阵运算。首先,定义了一组数据点,然后构建了矩阵方程,使用最小二乘法求解参数估计值,最后输出了参数估计值和拟合曲线的预测值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值