R中的稳健单调回归

机器算法验证 r 回归 线性模型 强大的
2022-04-01 17:41:20

我有下表R

df <- structure(list(x = structure(c(12458, 12633, 12692, 12830, 13369, 
13455, 13458, 13515), class = "Date"), y = c(6080, 6949, 7076, 
7818, 0, 0, 10765, 11153)), .Names = c("x", "y"), row.names = c("1", 
"2", "3", "4", "5", "6", "8", "9"), class = "data.frame")

> df
           x     y
1 2004-02-10  6080
2 2004-08-03  6949
3 2004-10-01  7076
4 2005-02-16  7818
5 2006-08-09     0
6 2006-11-03     0
8 2006-11-06 10765
9 2007-01-02 11153

我可以通过以下方式绘制点和 Tukey 的线性拟合(line函数 in R

plot(data=df,  y ~ x)
lines(df$x, line(df$x, df$y)$fitted.values)

产生:

在此处输入图像描述

一切都好。上图显示了能耗值,预计只会增加,所以我很高兴拟合没有通过这两个点(随后将被标记为异常值)。

但是,“只是”删除最后一点并重新绘制

df <- df[-nrow(df),]
plot(data=df,  y ~ x)
lines(df$x, line(df$x, df$
)$fitted.values)

结果完全不同。

在此处输入图像描述

我的需要是在上述两种情况下都有理想的相同结果。R 似乎还没有准备好使用函数进行单调回归,isoreg但除此之外它是分段常数。

编辑:

正如@Glen_b 指出的那样,对于上面使用的回归技术,异常值与样本大小的比率太大(~28%)。但是,我相信可能还有其他需要考虑的事情。如果我在表的开头添加点:

df <- rbind(data.frame(x=c(as.Date("2003-10-01"), as.Date("2003-12-01")), y=c(5253,5853)), df)

并像上面一样重新计算plot(data=df, y ~ x); lines(df$x, line(df$x,df$y)$fitted.values)我得到相同的结果,比率约为 22%

在此处输入图像描述

1个回答

我注意到删除最后一点后,您只有七个值,其中两个(28.6%!)是异常值。许多稳健的方法没有那么高的分解点(例如,Theil 回归在 n=7 时在该点分解,尽管大时达到 29.3%),但如果你必须有如此高的分解点,它可以管理如此多的异常值,您需要选择一些实际上具有更高故障点的方法。n

R中有一些可用;(M 估计)中的rlm函数MASS应该处理这种特殊情况(它对 y 异常值有很高的细分),但它对有影响的异常值没有鲁棒性。

同一个包中的函数lqs应该处理有影响的异常值,或者有许多好的包可以在 CRAN 上进行稳健回归。

您可能会发现 Fox 和 Weisberg 的R 中的稳健回归( pdf ) 是关于几个稳健回归概念的有用资源。

所有这一切都只是处理稳健的线性回归并且忽略了单调性约束,但我想如果您对故障问题进行排序,这将不是一个问题。如果您在执行高细分稳健回归后仍然得到负斜率,但想要一条非递减线,您可以将线设置为斜率为零 - 即选择稳健的位置估计并将线设置为恒定。(如果你想要稳健的非线性但单调回归,你应该特别提到这一点。)


回应编辑:

您似乎将我的 Theil 回归示例解释为对line. 不是; 这只是我遇到的第一个坚固生产线的例子,它在较小的污染比例下发生故障。

正如 whuber 已经解释的那样,我们无法轻易判断line. line崩溃的原因取决于 Tukey 提到并line可能使用的几个可能的稳健估计器中的哪一个。

例如,如果它是“将数据分成三组并且斜率使用连接外部三分之二中位数的线的斜率”的线(有时称为三组阻力线,或中位数线不是 3 的倍数时点如何分配给组。n

请注意,我并不是说实施的三组抗性线line——事实上我认为不是——而是简单地说,无论他们实施的是什么,都line可能有一个故障点,以至于结果线无法处理如果他们处于“正确”的位置,则 8 分中有 2 分是奇数。

事实上,实现的行line有一些奇怪的行为 - 太奇怪了,我想知道它是否可能有错误 - 如果你这样做:

 x = y = 1:9 #all points lie on a line with slope 1
 plot(x,y)
 abline(line(x,y),col=2)

那么这line条线的斜率为 1.2:

在此处输入图像描述

在我脑海中,我不记得 Tukey 的任何台词都有这种行为。


很久以后添加:我前段时间向开发人员报告了这个问题;它在修复之前花了几个版本,但现在line(它确实是 Tukey 的三组线的一种形式)不再有这个错误;在我尝试过的所有情况下,它现在的行为似乎都符合我的预期。