
C#线性回归算法的实现
文章目录
- C#线性回归算法的实现
- 前言
- 示例代码
- 实现思路
- 测试结果
- 结束语
 
前言
-  什么是线性回归呢? 
 简单来说,线性回归是一种用于建立两个变量之间线性关系的统计方法。在我们的软件开发中,线性回归可以应用于数据分析、预测和优化等领域。
-  什么情况下会用到线性回归呢? 
 线性回归可以用于探索数据之间的关系,可以用于预测未来的趋势。通过少量的数据点就能得到一个可以代表整个数据集的模型。换句话说,只需要采集少量的数据点,就可以拟合出整个数据集。
示例代码
现在让我们来看一下示例代码:
    /// <summary>
    /// 线性回归类,用于计算一组二维坐标点的线性回归方程(y = kx + b)
    /// </summary>
    public class LinearRegression
    {
        /// <summary>
        /// 直线斜率
        /// </summary>
        public double Slope { get; }
        /// <summary>
        /// 直线截距
        /// </summary>
        public double Intercept { get; }
        /// <summary>
        /// 构造线性回归对象
        /// </summary>
        /// <param name="data">一组坐标点</param>
        /// <exception cref="ArgumentException">当数据为空或数据点个数少于2个时抛出异常</exception>
        public LinearRegression(PointF[] data)
        {
            if (data == null || data.Length < 2)
            {
                throw new ArgumentException("Data can not be null or the number of data points must be at least 2.");
            }
            double sumX = 0;
            double sumY = 0;
            double sumXY = 0;
            double sumX2 = 0;
            int n = data.Length;
            foreach (PointF point in data)
            {
                sumX += point.X;
                sumY += point.Y;
                sumXY += point.X * point.Y;
                sumX2 += point.X * point.X;
            }
            double avgX = sumX / n;
            double avgY = sumY / n;
            Slope = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX);
            Intercept = avgY - Slope * avgX;
        }
        /// <summary>
        /// 根据 x 坐标计算对应的 y 坐标
        /// </summary>
        /// <param name="x">x 坐标</param>
        /// <returns>y 坐标</returns>
        public double GetY(double x)
        {
            return Slope * x + Intercept;
        }
        /// <summary>
        /// 根据 y 坐标计算对应的 x 坐标
        /// </summary>
        /// <param name="y">y 坐标</param>
        /// <returns>x 坐标</returns>
        public double GetX(double y)
        {
            return (y - Intercept) / Slope;
        }
    }
我们定义了一个名为LinearRegression的类。这个类有两个公共属性,分别代表线性回归的斜率和截距。我们还定义了一个构造函数,它接受一个PointF类型的数组作为输入,用于计算斜率和截距。
此外还定义了两个方法,分别用于根据x坐标计算对应的y坐标和根据y坐标计算对应的x坐标。
实现思路
线性回归算法的思路是这样的:
- 对于输入的数据点数组,我们首先计算出它们的平均值。
- 计算每个数据点与平均值的差值,并将这些差值乘以对应的x和y坐标。
- 我们将这些乘积相加并除以对应的坐标的平方和,即可得到斜率。
- 通过平均值和斜率的计算结果得出截距。
下面,让我们来看一下重要的代码段:
double sumX = 0;
double sumY = 0;
double sumXY = 0;
double sumX2 = 0;
int n = data.Length;
foreach (PointF point in data)
{
    sumX += point.X;
    sumY += point.Y;
    sumXY += point.X * point.Y;
    sumX2 += point.X * point.X;
}
double avgX = sumX / n;
double avgY = sumY / n;
Slope = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX);
Intercept = avgY - Slope * avgX;
通过foreach循环遍历每一个数据点,并计算出所有需要的变量。接着,我们计算出斜率和截距,并将其分别赋值给类的属性。最后,我们就可以使用GetY和GetX方法来计算任意坐标对应的值了。
测试结果
编写测试代码如下:
    [TestClass]
    public class LinearRegressionTests
    {
        [TestMethod]
        public void TestLinearRegression()
        {
            // 构造测试数据
            PointF[] data = new PointF[5]
            {
                new PointF(1, 1),
                new PointF(2, 3),
                new PointF(3, 5),
                new PointF(4, 7),
                new PointF(5, 9)
            };
            // 构造线性回归对象
            LinearRegression lr = new LinearRegression(data);
            // 验证直线斜率和截距是否正确
            Assert.AreEqual(2, lr.Slope, 0.0001);
            Assert.AreEqual(-1, lr.Intercept, 0.0001);
            // 验证 GetY 方法是否正确计算 y 值
            Assert.AreEqual(1, lr.GetY(1), 0.0001);
            Assert.AreEqual(3, lr.GetY(2), 0.0001);
            Assert.AreEqual(5, lr.GetY(3), 0.0001);
            Assert.AreEqual(7, lr.GetY(4), 0.0001);
            Assert.AreEqual(9, lr.GetY(5), 0.0001);
            // 验证 GetX 方法是否正确计算 x 值
            Assert.AreEqual(1, lr.GetX(1), 0.0001);
            Assert.AreEqual(2, lr.GetX(3), 0.0001);
            Assert.AreEqual(3, lr.GetX(5), 0.0001);
            Assert.AreEqual(4, lr.GetX(7), 0.0001);
            Assert.AreEqual(5, lr.GetX(9), 0.0001);
        }
    }
测试结果:
 
结束语
通过本章的代码可以轻松实现线性回归算法。如果您觉得本文对您有所帮助,请不要吝啬您的点赞和评论,提供宝贵的反馈和建议,让更多的读者受益。



















