最小二乘法(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

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部