通过分段线性函数查找数据中的变化点


10

问候,

我正在进行研究,这将有助于确定观察到的空间的大小以及自从发生大爆炸以来经过的时间。希望您能提供帮助!

我有符合分段线性函数的数据,我要在该函数上执行两个线性回归。斜率和截距在某个点发生变化,我需要(编写一个程序)找到该点。

有什么想法吗?


3
交叉发布有什么政策?在math.stackexchange.com上提出了完全相同的问题:math.stackexchange.com/questions/15214/…– mpiktas
2010年

在这种情况下,做简单的非线性最小二乘怎么办?我是否缺少明显的东西?
grg s 2010年

我要说的是,目标函数相对于更改点参数的导数非常不平滑
Andre Holzner 2012年

斜率将发生很大变化,以至于非线性最小二乘将变得不简洁和准确。我们知道的是,我们有两个或更多个线性模型,因此我们应该提取这两个模型。
HelloWorld

Answers:


1

mcp软件包可以做到这一点。说你的数据是

首先,让我们模拟一些数据:

df = data.frame(x = 1:100,
                y = c(rnorm(40, 10 + (1:40)*0.5),
                      rnorm(60, 10 + 40*0.5 -8 + (1:60)*0.2)))

现在,让我们看看是否可以使用以下命令恢复到40(和参数值)的更改点mcp

model = list(
  y ~ 1 + x,  # linear segment
  ~ 1 + x  # another linear segment
)
library(mcp)
fit = mcp(model, df)

绘制它。灰线是从拟合中随机抽取的,表明它捕获了趋势。蓝色曲线是估计的更改点位置:

在此处输入图片说明

让我们看看各个参数的估计。int_是截距,x_是x的斜率,cp_是变化点:

summary(fit)

Population-level parameters:
    name  mean lower upper Rhat n.eff
    cp_1 40.48 40.02 41.00    1  2888
   int_1 11.12  9.11 13.17    1   778
   int_2 21.72 20.09 23.49    1   717
 sigma_1  3.23  2.76  3.69    1  5343
     x_1  0.46  0.36  0.54    1   724
     x_2  0.21  0.16  0.26    1   754

免责声明:我是的开发者mcp


8

R包strucchange可能会帮助您。看一下小插图,它很好地概述了如何解决类似的问题。


6

如果分数不是太大,则可以尝试所有可能性。假设这些点是X一世=X一世ÿ一世 哪里 一世=1个ñ。比,你可能会循环Ĵ2ñ-2 并同时适合两行 {X1个XĴ}{XĴ+1个Xñ}。最后,您选择Ĵ 对于这两条线,其残差平方和之和为最小。


我已根据您的简单但有效的建议发布了答案。
HelloWorld

5

这是一个(离线)变更点检测问题。我们之前的讨论提供了对期刊文章和R代码的引用。首先看一下Barry和Hartigan的 “产品分区模型”,因为它可以处理坡度的变化并具有有效的实现方式。


3

同样,分段式软件包在过去也帮助我解决了类似的问题。


不幸的是,包需要一个起点作为断点。
HelloWorld

同样,segmented不能对段之间的截距变化进行建模,只能模拟第一个段的截距。
JonasLindeløv

2

我以mbq的答案为基础,即寻找所有可能性。此外,我这样做:

  • 检查两个分段模型的显着性,以确保系数显着
  • 检查完整模型的残差平方和之差
  • 目视确认我的模型(确保它不是废话)

为什么要检查其重要性?这是因为,如果分段模型中的任何一个拟合数据都非常差,那么具有最小SSE的点就毫无意义。对于两个高度相关的变量,可能会发生这种情况,而没有明确的斜率变化的断点。

让我们通过一个简单的测试案例来检查这种简单的方法:

x <- c(-50:50)
y <- abs(x)
plot(x,y,pch=19)

在此处输入图片说明

断点显然为零。使用以下R脚本:

f <- function(x, y)
{
    d <- data.frame(x=x, y=y)
    d <- d[order(x),]
    r <- data.frame(k=rep(0,length(x)-4), sums=rep(0,length(x)-4))

    plm <- function(i)
    {
        d1 <- head(d,i)
        d2 <- tail(d,-i)

        # Make sure we've divided the region perfectly        
        stopifnot(nrow(d1)+nrow(d2) == nrow(d))

        m1 <- lm(y~x, data=d1)
        m2 <- lm(y~x, data=d2)

        r <- list(m1, m2)
        r
    }

    lapply(2:(nrow(d)-3), function(i)
    {
        r$k[i-2] <<- d[i,]$x

        # Fit two piecewise linear models
        m <- plm(i)

        # Add up the sum of squares for residuals
        r$sums[i-2] <<- sum((m[[1]]$residuals)^2) + sum((m[[2]]$residuals)^2)
    })

    b <- r[which.min(r$sums),]    
    b
}

适合所有可能组合的分段线性模型:

f(x,y)
   k sums
   0    0

如果我们检查两个最优模型的系数,它们将非常重要。他们的R2也将很高。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.