具有不连续数据的分段线性回归

时间:2017-06-27 11:18:37

标签: r linear-regression

我有一个看起来是分段线性的数据集。我想在R中执行分段线性回归。问题是断点处存在不连续性。通过使用this question中的一些代码,我设法获得了一些东西,但我并不满意。

数据集

这是一个虚拟数据集。

equation of the dataset

NB = 100
A1 = 2 # coeff for first part
A2 = 1 # coeff for second part
B1 = 0 # intercept for first part
B2 = 300 # intercept for second part
df = data.frame(n=1:NB)
df$n = sample(500, size=NB, replace=TRUE)
df$noise = sample(20, size=NB, replace=TRUE)-10
my_func <- function(n, noise) {
    if(n < 100) {
        return(A1*n+B1 + noise)
    }
    else {
        return(A2*n+B2 + noise)
    }
}
df$fn = mapply(my_func, df$n, df$noise)

使用segmented

这非常简单,我们只需执行经典线性回归并将其赋予segmented

library(segmented)
library(ggplot2)
model_segmented = segmented(lm(fn~n, data=df), seg.Z = ~ n)
predict_segmented = data.frame(n = df$n, fn = broken.line(model_segmented)$fit)
ggplot(df, aes(x = n, y = fn)) +
    geom_point() + geom_line(data = predict_segmented, color = 'blue')

给出:

plot of the raw data and its linear regression using segmented

显然,segmented期望数据是连续的。情况并非如此,因此回归不正确。

“手动”方法

这种方法比较单调乏味。首先,我们通过尝试所有可能的断点并保持产生最低残差的断点来计算断点。然后,我们在线性回归中添加一个新因子,它告诉预测变量是大于还是小于此断点。

# Computation of the break-point
Break<-sort(unique(df$n))
Break<-Break[2:(length(Break)-1)]
d<-numeric(length(Break))
for (i in 1:length(Break)) {
    model_manual<-lm(fn~(n<Break[i])*n + (n>=Break[i])*n, data=df)
    d[i]<-summary(model_manual)[[6]]
}
breakpoint = Break[which.min(d)]

# Linear regression using this break-point
df$group = df$n >= breakpoint
model_manual<-lm(fn~n*group, data=df)
dat_pred = data.frame(n = df$n, fn = predict(model_manual, df))
ggplot(df, aes(x = n, y = fn)) +
    geom_point() +
    geom_line(data=dat_pred[dat_pred$n < breakpoint,], color = 'blue') +
    geom_line(data=dat_pred[dat_pred$n >= breakpoint,], color = 'blue')

给出:

enter image description here

在这里,回归很棒。

问题

有没有更好的方法来实现这一目标? segmented包可以采用不连续数据,还是有可以执行此操作的包?

我担心的是第二种方法有点长而且不易阅读。

2 个答案:

答案 0 :(得分:0)

strucchange 将使用统计上有效的方法来检测断点。然后,您可以将每个零件与所需的模型相匹配。例如,对于季节性时间序列,您可以将单独的ARIMA模型应用于每个细分。

答案 1 :(得分:0)

花费大量时间进行挖掘之后,我相信chngpt软件包是必经之路。它可以进行连续和不连续的分段回归。链接到这里:https://cran.r-project.org/web/packages/chngpt/vignettes/chngpt-vignette.pdf