【问题标题】:Efficient algorithm to fit a linear line along the upper boundary of data only仅沿数据上边界拟合线性线的有效算法
【发布时间】:2014-07-17 09:12:04
【问题描述】:

我目前正在尝试通过 MATLAB 中分散的数据来拟合一条线性线。现在这很容易使用 polyfit 函数,我可以很容易地获得我的 y= mx + c 方程。但是,我现在需要沿着数据的上边界拟合一条线,即前几个数据点。我知道这个描述是模糊的,所以让我们假设我的分散数据将是一个锥形,它的顶点在 y 轴上,它在 +x 和 +y 方向上向外和向上传播。如果你愿意,我需要在“圆锥体的上边缘”设置一条最佳拟合线。

我开发了一种算法,但速度极慢。它涉及首先通过所有数据拟合一条最佳拟合线,删除这条最佳拟合线下方的所有数据点,然后迭代直到只剩下 5% 的初始数据点。然后,最终的最佳拟合线将靠近圆锥的顶部边缘。对于 250 个数据点,这大约需要 5 秒,而我要处理超过一百万个数据点,这个算法效率太低了。

我想我的问题是:有没有一种算法可以更有效地实现我的需求?或者有没有办法让我的代码更加清晰,以消除不必要的复杂性?

这是我在 MATLAB 中的代码:

(例如)

a = [4, 5, 1, 8, 1.6, 3, 8, 9.2]; %To be used as x-axis points
b = [45, 53, 12, 76, 25, 67, 75, 98]; %To be used as y-axis points

while prod(size(a)) > (0.05*prod(size(a))) %Iterative line fitting occurs until there are less than 5% of the data points left

      lobf = polyfit(a,b,1); %Line of Best Fit for current data points

      alen = length(a);

      for aindex = alen:-1:1 %For loop to delete all points below line of best fit

            ValLoBF = lobf(1)*a(aindex) + lobf(2)

            if ValLoBF > b(aindex) %if LoBF is above current point...
                   a(aindex) = []; %delete x coordinate...
                   b(aindex) = []; %and delete its corresponding y coordinate
            end
      end

end

【问题讨论】:

  • 你能上传一张你想适合什么样的线条的图吗?我无法从描述中理解。
  • 哈我已经有了一张图,因为我想让它更清楚。我无法上传图片,因为我没有代表>_
  • 第一次拟合后如何将所有点“旋转”到零,然后删除低于零的任何点(或您决定的某个正值)并将它们旋转回来?通过这种方式,您可以轻松删除大部分数据。 p.s.您可以将图片上传到外部网站并放置链接。
  • 这与简单地消除线下的点有何不同?甚至不需要那样旋转 2 次​​span>
  • 实际上是在寻找Pareto Frontier?

标签: algorithm matlab curve-fitting


【解决方案1】:

首先,您的示例代码似乎无限期运行;)

对您的代码进行一些优化:

a = [4, 5, 1, 8, 1.6, 3, 8, 9.2]; %To be used as x-axis points
b = [45, 53, 12, 76, 25, 67, 75, 98]; %To be used as y-axis points

n_init_a = length(a);

while length(a) > 0.05*n_init_a %Iterative line fitting occurs until there are less     than 5% of the data points left

  lobf = polyfit(a,b,1); % Line of Best Fit for current data points

  % Delete data points below line using logical indexing
  % First create values of the polyfit points using element-wise vector multiplication
  temp = lobf(1)*a + lobf(2); % Containing all polyfit values
  % Using logical indexing to discard all points below
  a(b<temp)=[]; % First destroy a
  b(b<temp)=[]; % Then b, very important!

end

您还应该尝试通过在命令窗口中键入来分析您的代码

profile viewer

并检查计算结果所需的时间最多。我怀疑它是 polyfit,但可能无法加快速度。

【讨论】:

  • 这确实有效!千亿倍的速度!谢谢!
  • 不要忘记目视检查您的输出,看看您是否可以接受合身!当将来不需要它们时,也要尽量避免循环;)
【解决方案2】:

您正在寻找的不是线拟合。您正试图找到点的凸包。

您应该查看函数convhull。找到外壳后,您可以移除所有不靠近它的点,并独立拟合每个部分,以避免数据嘈杂的事实。


或者,您可以将点渲染到某个像素网格上,然后进行某种形态学运算,例如imclose,最后使用霍夫变换完成。也可以看看这个answer

【讨论】:

  • 我尝试从凸包的角度考虑这个问题,但我想:如果给定一个数据点球怎么办?还是一组伪随机数据? convhull 函数还能用吗?
  • 我认为凸包方法无法选择要基于多少点进行拟合,从而导致拟合精度有限。
  • @EJG89,是的,这应该是去除三角形内点的预处理步骤。
  • 您的示例中的凸包将由 4 个点(在左上角)组成,而进行拟合的全部目的是调整变化。通过仅选择凸包点,polyfit 将始终被高估。
  • @EJG89,你应该选择离船体足够近的点,而不仅仅是那些在船体上的点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-17
  • 1970-01-01
  • 2019-03-15
  • 1970-01-01
  • 2019-03-12
  • 2016-06-11
  • 2012-07-28
相关资源
最近更新 更多