当前位置: 首页 > article >正文

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


http://www.kler.cn/news/294586.html

相关文章:

  • 怎么强制撤销excel工作表保护?
  • 深度学习从入门到精通——yolov1
  • F12抓包06-1:浏览器导出postman测试脚本
  • sicp每日一题[2.1]
  • docker 容器
  • 数据库 | 子查询 | sql执行顺序 | mysql是否运行
  • AI文献综述神器,有这一款就够了!
  • 《JavaEE进阶》----11.<SpringIOCDI【Spring容器+IOC详解+DI介绍】>
  • tcp 流量控制
  • 开发一款通过蓝牙连接控制水电表的微信小程序
  • ubuntu 安装python3 教程
  • 开篇_____何谓安卓机型“工程固件” 与其他固件的区别 作用
  • springboot websocket 服务端
  • 用 Python 编写桌面时钟程序
  • MATLAB绘图基础5:MATLAB数据导入
  • Redis总结,是什么,干什么,怎么利用?
  • element table 表格 span-method 某一列进行相同合并 支持树结构表格
  • 数据结构基础之《(2)—对数器》
  • 海外直播对网速、带宽、安全的要求
  • Docker容器创建时,无法访问镜像源:Could not connect to archive.ubuntu.com:80
  • C语言操作符详解1(含进制转换,原反补码)
  • 消息队列 think-queue tp5.0
  • 使用Docker启动Redis容器并映射端口
  • ChatGPT3.5/4.0新手使用手册,国内中文版使用教程
  • 记录 vue-router 跳转到第一个有权限的菜单的实现方式
  • 【大模型开发】传统向量模型 vs 重排序模型:原理、实现与应用
  • 欺诈文本分类检测(十二):模型导出与部署
  • 八大排序原来也不过如此
  • 【软件逆向】第27课,软件逆向安全工程师之(二)寄存器寻址,每天5分钟学习逆向吧!
  • 【MIT 6.5840/6.824】In Search of an Understandable Consensus Algorithm 学习笔记