使用多项式拟合算法对数据集中的一部分进行拟合

6
我有一个算法问题。我不知道是否适合在stackoverflow上发布,但因为我使用matlab并且想用它来解决这个问题,所以在这里发布。我的问题是:我有一组数据,除了这一组数据的末尾必须呈现出相当线性之外,我对此并不了解。我想对这些呈线性分布的点进行线性拟合,而不使用不呈线性分布的部分。
(一张图片总是更容易理解):enter image description here 如您所见,我有蓝色数据,这些数据不是线性的,但末尾部分具有线性部分(红色部分)。我想要的是找到一种算法,使我能够知道数据曲线的行为何时结束其线性度。
我不知道我是否清楚?
我已经尝试过从右边选取几个点并对这些点进行线性拟合。然后添加一些点到这几个点并检查这些点是否与线性拟合“足够接近”。然后再次使用添加的点进行线性拟合,以此类推,但我认为这不是最好的解决方案,因为“第一个”点有很多噪音(在图像中未表示)...
你有任何想法、建议或链接吗?
谢谢!

最终它是否总是变得几乎线性?或者你对任何段中最长的直线感兴趣? - Fallen
@Fallen 我不确定它是否总是这样,但我认为在大多数情况下,它会相当线性。你所说的“任何线段中最长的直线”是什么意思? - mwoua
我的意思是,您是否对仅以最后一个数据输入结束的直线段感兴趣? - Fallen
@Fallen 不,我不需要。我只想要适合的部分,不必经过最后一个点。 - mwoua
这些数据看起来是具有额外线性趋势的逻辑回归。 - A. Webb
@A.Webb 这只是一个例子。我的数据不是这样的。这只是为了形象化和清晰明了 :) 这条曲线简单地是 atan(x-b)+a*(x-b)。 - mwoua
4个回答

4
我的要求是找到一种算法,能够让我知道数据曲线的行为何时结束其线性性。线性数据有一个非常好的特性,即具有恒定的斜率。线性部分的二阶导数应该约等于零。使用样条拟合(如果数据有噪声,则需要进行某种平滑处理),得到数据的连续版本,称其为g(x)。当 g''(x) ~ 0 时,即二阶导数很小时,这是一个线性部分。

2
确实如此,而且可以相当高效地完成。您甚至不需要将数据转换为连续的形式。您可以计算离散数据的二阶导数,然后搜索二阶导数在小阈值范围内的区域。这里有另一个SO问题,其中包含使用Python实现此精确算法的代码:https://dev59.com/X2Yr5IYBdhLWcg3waJn7 - darksky
@darksky 非常感谢你。这是我的结果 https://dev59.com/A3TYa4cB1Zd3GeqPvHcN。正如你所看到的,我遇到了另一个问题。如果你有时间,能否帮忙检查一下?:) 谢谢! - mwoua

1

按x轴位置剪裁数据集,然后设置一些线性阈值。

  • 从一端开始
  • 检查图形的下一个预定义部分的Pearson相关系数
  • 如果超过某个阈值,则将包含的x范围添加到您的范围中,否则停止

或者,您可以检查线性是否为多项式拟合的最佳拟合。对于这个,我会:

  • 定义几个一阶到n阶的通用函数,其中n相当小(可能是3)
  • 将数据点添加到线性测试集中
  • 比较n个函数的最小二乘值
  • 如果线性具有最低的最小二乘值,或者与n函数的最小值之间的距离在某个范围内,则继续添加点。否则停止并说该函数在最后一个添加之前是线性的。

这些至少是非常直接的方法,在我的奥卡姆剃刀思维中,它们也具有最低的复杂性(在两种情况下都是n *曲线拟合复杂性,尽管第二种情况具有更大的常数),尽管很可能存在更低复杂度的算法。


我会尝试这个,但它与我之前做的相当相似。无论如何,还是谢谢。 - mwoua
@mwoua 你也可以在非线性部分递归并获取所有线性部分,但我不确定这对你是否有价值。 - Slater Victoroff

1
一种方法是使用二次多项式逼近,从右到左逐渐增加点数,并观察第三个系数。只要它足够小,分布就足够线性。
问题在于很难用数字来确定“足够小”,只能通过实证来确定。
另一种方法可能是比较实际数据的线性逼近。同样地,从右到左添加点并测量逼近标准差。一旦满意,逼近就好了,数据可以被认为是线性的。
这更好一些,因为偏差是一个相当透明的概念。

0
如果您的行为是分段线性的,并且存在突变,您可以尝试使用以下形式的拟合:
E[Y] = b0 + b1 * x + b2 * I + b3 * x * I

其中,I是一个指示函数,当满足某些条件时为1,否则为0。 对于你的例子,条件可以是x > 0。 如果两个线段是平行的,则b2系数将捕捉垂直位移,而b3项是一种“交互”,可以捕捉指示器断点两侧的斜率变化。

如果过渡更加缓慢,就像你画的那样,那么我同意@A.Webb的评论,使用带有趋势的逻辑方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接