machine-learning - 如何只拟合数据集的线性部分?
问题描述
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 中的解决方案。
请注意,上面显示的日期只是一个示例,该方法对于任意数据集应该是稳健的,只要它包含线性部分即可。当有多个线性部分时,它也应该显示那些多个线性部分。如果没有线性部分,它应该显示没有找到线性部分。
编辑:一般来说,统计方法可能不适合有力地解决这个问题。我添加了计算机视觉和机器学习标签。也许这些领域的方法中的方法通常更适合稳健地解决这个问题?
解决方案
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)
推荐阅读
- c# - 后台任务的全局异常处理
- android-studio - 除非按住 SHIFT,否则无法使用退格键删除代码
- php - 如何去页面行操作锚页面(post.php?post=3&action=?)
- java - 使用java向同一路由器下的多个主机发送数据包
- docker - 授予对已挂载的 docker 卷的写入权限
- visual-studio - 采用较新版本的 Visual Studio 时需要考虑的事项
- java - 如何为 Room 数据库的 @Entity 的字段编写循环
- c - 关于面包店算法的一些一般问题
- laravel-5.8 - 如何在 laravel 中获取会话移动
- c# - 从控制台应用程序调用动态 CRM Web 服务时如何指定代理详细信息