首页 > 解决方案 > 如何只拟合数据集的线性部分?

问题描述

p=(-50:50)^2
y=c(p, 2500+10*(1:99), p+1000)
plot(seq_along(y), y+100*rnorm(length(y)))

假设我有一个像上面这样的数据集,其中只有一部分数据是线性的。R 中的普通线性回归lm()不能智能地找出适合线性拟合的区域(本例中为 100 到 200)。

如何找出数据的哪一部分是线性的并只在这个数据集子集中执行拟合?欢迎使用 R 和 python 中的解决方案。

在此处输入图像描述

请注意,上面显示的日期只是一个示例,该方法对于任意数据集应该是稳健的,只要它包含线性部分即可。当有多个线性部分时,它也应该显示那些多个线性部分。如果没有线性部分,它应该显示没有找到线性部分。

编辑:一般来说,统计方法可能不适合有力地解决这个问题。我添加了计算机视觉和机器学习标签。也许这些领域的方法中的方法通常更适合稳健地解决这个问题?

标签: machine-learningcomputer-visionlinear-regressioncurve-fitting

解决方案


dpseg在 dpseg 包中尝试。我们将最小长度限制为 50 以避免偶然发生的短线性拉伸。还有其他可用的调整参数。有关更多信息,请参阅?dpseg包装随附的插图。

为了使输入可重现,我们需要set.seed在最后的注释中使用并完成此操作。

library(dpseg)
segs <- dpseg(x = x, y = y, minl = 50); segs
## ... this output is shown just before the image ...
subset(segs$segments, var < 20000)
##    x1  x2 start end intercept    slope        r2      var
## 3 116 203   116 203  1458.242 10.15865 0.8613225 10844.35

plot(segs)

给出以下内容,我们看到上面输出的第三段具有最小的方差。

> segs

calculating recursion for 301 datapoints

dynamic programming-based segmentation of 301 xy data points:

   x1  x2 start end  intercept     slope        r2      var
1   1  50     1  50   2165.902 -51.13574 0.9212552 47495.24
2  50 116    50 116  -2928.772  50.00892 0.9521128 47756.06
3 116 203   116 203   1458.242  10.15865 0.8613225 10844.35
4 203 252   203 252  12533.408 -47.39630 0.9189915 42079.16
5 252 301   252 301 -12405.806  51.67657 0.9261061 45278.70

Parameters: type: var; minl: 50; maxl: 301; P: 0; jumps: 0 

截屏

笔记

set.seed(123)
p <- (-50:50)^2
y <- c(p, 2500+10*(1:99), p+1000)
y <- y+100*rnorm(length(y))
x <- seq_along(y)

推荐阅读