【问题标题】:Algorithm for scatter plot 'best-fit' line散点图“最佳拟合”线的算法
【发布时间】:2012-10-18 02:48:14
【问题描述】:

我正在用 C# 编写一个小型应用程序,使用 MSChart 控件来绘制 X 和 Y 数据点集的散点图。其中一些可能相当大(数百个数据点)。

想问是否有一种“标准”算法可以在这些点上绘制一条最佳拟合线。我正在考虑将 X 数据点划分为预定义数量的集合,例如 10 或 20,并为每个集合取相应 Y 值和中间 X 值的平均值,依此类推以创建线。这是正确的做法吗?

我搜索了现有的线程,但它们似乎都是关于使用 Matlab 等现有应用程序实现相同的目标。

谢谢,

【问题讨论】:

    标签: c# mschart


    【解决方案1】:

    使用线性最小二乘算法

    public class XYPoint
    {
        public int X;
        public double Y;
    }
    
    class Program
    {
        public static List<XYPoint> GenerateLinearBestFit(List<XYPoint> points, out double a, out double b)
        {
            int numPoints = points.Count;
            double meanX = points.Average(point => point.X);
            double meanY = points.Average(point => point.Y);
    
            double sumXSquared = points.Sum(point => point.X * point.X);
            double sumXY = points.Sum(point => point.X * point.Y);
    
            a = (sumXY / numPoints - meanX * meanY) / (sumXSquared / numPoints - meanX * meanX);
            b = (a * meanX - meanY);
    
            double a1 = a;
            double b1 = b;
    
            return points.Select(point => new XYPoint() { X = point.X, Y = a1 * point.X - b1 }).ToList();
        }
    
        static void Main(string[] args)
        {
            List<XYPoint> points = new List<XYPoint>()
                                       {
                                           new XYPoint() {X = 1, Y = 12},
                                           new XYPoint() {X = 2, Y = 16},
                                           new XYPoint() {X = 3, Y = 34},
                                           new XYPoint() {X = 4, Y = 45},
                                           new XYPoint() {X = 5, Y = 47}
                                       };
    
            double a, b;
    
            List<XYPoint> bestFit = GenerateLinearBestFit(points, out a, out b);
    
            Console.WriteLine("y = {0:#.####}x {1:+#.####;-#.####}", a, -b);
    
            for(int index = 0; index < points.Count; index++)
            {
                Console.WriteLine("X = {0}, Y = {1}, Fit = {2:#.###}", points[index].X, points[index].Y, bestFit[index].Y);
            }
        }
    }
    

    【讨论】:

    • 嘿,这是一个很棒且优雅的解决方案,应该重复使用!我实际上有一个更正:'b = (a * meanX - meanY);'应翻转为'b = (meanY - a * meanX);' , 因为 Y=MX+B 是 B=Y-MX
    【解决方案2】:

    是的。你会想要使用Linear Regression,特别是Simple Linear Regression

    算法本质上是:

    • 假设存在一条最合适的线,y = ax + b
    • 对于每个点,您都希望尽量减少它们与这条线的距离
    • 计算每个点到直线的距离,并对距离求和(通常我们使用距离的平方来更严厉地惩罚离直线较远的点)
    • 找到ab 的值,使用基本微积分最小化所得方程(应该只有一个最小值)

    维基百科页面将为您提供所需的一切。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-06
      • 2014-04-09
      • 1970-01-01
      • 2022-07-10
      • 1970-01-01
      • 2018-07-01
      相关资源
      最近更新 更多