【问题标题】:Algorithm to detect a linear part of a data set检测数据集线性部分的算法
【发布时间】:2018-07-02 12:20:45
【问题描述】:

我希望我是在正确的地方问这个问题,但我的问题如下:我有一组数据(两个列表 x 和 y),我没有太多关于这个集合的其他信息(没有函数,或者像这样的任何东西)。我的目标是找到线性数据的子集(下图中以黄色突出显示的部分)。

正如您在绘制数据后在图像上看到的那样,我们可以看到它在一段时间内变为线性。我想自动检测那个子集。因为我没有它背后的功能,所以我真的迷路了!

有人知道如何做到这一点吗?我可以实现的算法或数学方法? (我使用 python 顺便说一句)

【问题讨论】:

  • 坡度必须是线性的吗? (未知函数是否必须是 y = ax + b)
  • 是的,数据集包含一个线性子集,满足y = ax + b 类型的函数
  • 您可以查看RANSAC 之类的内容来提取感兴趣区域的线性模型(只要大多数点都在其中),然后选择您符合条件的点“ inliers”具有一些合理的阈值。
  • 该部分是完全线性的,还是带有一些噪音的线性?另外,如果有多个线性段怎么办?
  • 您不只是想在一定的误差范围内找到数据的二阶导数为 0 的位置吗?

标签: python algorithm


【解决方案1】:

您可以从使用 x 和 y 值确定两个点的斜率开始。

说点 1 和 2,斜率 = 2。 然后计算点 2 和 3 的斜率。 如果后者的斜率与前者不同,那么您就知道它不是线性的。

只需对整个数据集进行 for 循环,并将当前值与下一个值进行比较即可得到斜率。

from decimal import Decimal
def linear_equation(p1,p2):
    #points are arrays like p=(x,y)
    m=slope(p1,p2) #slope 
    c=(p2[1]-(m*p2[0])) #y-intercept of line
    return 'y='+str(m)+ 'x' +'+' +str(c)

def slope(p1,p2):
    return Decimal((p2[1]-p1[1]))/Decimal(p2[0]-p1[0])

points =[[0,0],[1,1],[2,2],[3,4],[4,5],[5,6],[7,30],[8,35],[9,39]]


for p in range(0,len(points)-2):
    #if the slopes of points (a,b) and (b,c) are the same then print the equation
    #you could really omit the if statment if you just want to calculate the
    #equations for each set of points and do the comparasons later.
    #change the for condition to -1 instead of -2 if this is the case.
    if slope(points[p],points[p+1]) == slope(points[p+1],points[p+2]):
        print(str(lin_equ(points[p],points[p+1])))
    else:
        print("Non-Linear")

输出:

y=1x+0

非线性

非线性

y=1x+1

非线性

非线性

非线性

【讨论】:

  • 但是即使它们具有相同的斜率,这并不意味着它们也是线性的,因为它们可以有不同的 y 截距(y = ax + b 中的参数 b)
  • 提供的图表不是线性的,因此您无法将其拟合为斜率截距形式。 Y 截距实际上与确定某事物是否是线性的无关。它只是确定线性方程的起点。你的不是(它有曲线)。你只需要循环并比较每个线段的斜率,并且连续匹配的斜率是线性的。 @AnotherBrick
猜你喜欢
  • 1970-01-01
  • 2021-10-27
  • 2014-03-24
  • 1970-01-01
  • 2013-09-17
  • 2020-04-23
  • 2011-08-20
  • 2014-07-07
  • 2020-11-18
相关资源
最近更新 更多