【问题标题】:Unexpected discrepancy between two different predictions using linear regression使用线性回归的两个不同预测之间的意外差异
【发布时间】:2016-06-06 13:29:29
【问题描述】:

我正在使用ggplot2 绘制一些时间序列数据以及线性回归线。我有兴趣确定回归线何时会达到 82%。对图表的视觉检查表明这将在 2017 年 11 月 15 日左右发生。但是当我使用 R 的 predict.lm() 函数时,我得到了不同的答案:2017 年 8 月 12 日。这两种方法不应该给我相同的答案吗?最后,我想用一个显示截取日期的文本标签来注释图表。

require(ggplot2)
temp <- "End.Date    Save.Rate
1       2015-05-31     0.67
2       2015-07-31     0.67
3       2015-09-30     0.69
4       2015-11-30     0.71
5       2016-01-30     0.70
6       2016-03-31     0.72"

df <- read.table(text = temp, header = TRUE)
df$End.Date <- as.POSIXct(df$End.Date, origin="1970-01-01", tzone="America/New_York")

save.rate.lm = lm(End.Date ~ Save.Rate, data=df)
newdata <- data.frame(Save.Rate = 0.82)
temp <- predict.lm(save.rate.lm, newdata)
predicted.date <- as.POSIXct(as.data.frame(temp)[1,], origin="1970-01-01",
                             tzone="America/New_York")
print(predicted.date)

x.lims <- c(as.POSIXct(NA), as.POSIXct("2017-12-31", origin="1970-01-01",
                                       tzone="America/New_York"))
p <- ggplot(df, aes(x=End.Date, y=Save.Rate)) +
  geom_point() +
  stat_smooth(method='lm', fill=NA, fullrange=TRUE) + 
  theme(axis.text.x=element_text(angle = -45, hjust = 0)) +
  scale_y_continuous(labels = percent) +
  scale_x_datetime(breaks = date_breaks('month'), labels = date_format('%b-%Y'),
                   limits=x.lims) +
  geom_hline(yintercept=0.82)
print(p)

【问题讨论】:

    标签: r ggplot2 linear-regression


    【解决方案1】:

    您不能只反转线性回归(即date ~ 1+raterate ~ 1 +date)并期望得到相同的答案(例如,请参阅this question on CrossValidated)。据我所知,没有简单的方法可以在逆回归上使用predict.lm 来获得您正在寻找的答案。您需要将比率拟合为日期的函数并使用一些代数来获得预测日期。下面我展示了一个适用于您的特定问题的简单计算; this questionthis question 的答案给你一些额外的罐头解决方案......

    fit2 = lm(Save.Rate ~ End.Date, data=df)
    ## y = a + bx
    ## x* = (y-a)/b
    cc <- coef(fit2)
    pred.date <- as.POSIXct((0.82-cc[1])/cc[2],origin="1970-01-01",
                                 tzone="America/New_York")
    ##               (Intercept) 
    ## "2017-11-19 17:26:28 EST" 
    

    图片:

    p+geom_vline(xintercept=as.numeric(pred.date),lty=2)
    

    【讨论】:

    • 感谢您的回答。我很好奇是否有办法使用predict.lm() 完成相同(正确)的结果,就像我在原始代码示例中尝试做的那样。
    • @AlexC。 : 不这么认为。
    • 逆向预测是分析化学中的一项常见任务。因此,有chemCal::inverse.predict。它不是矢量化的,也不会保留属性(例如日期时间类),但它会计算标准误差和置信区间。
    【解决方案2】:

    Ben Bolker 解释了为什么你的方法行不通。

    但是,您可以使用 coord_flip 翻转 ggplot2 中的轴,并在 x 方向(而不是通常的 y 方向)使用带有误差项的回归:

    p <- ggplot(df, aes(y=End.Date, x=Save.Rate)) +
      geom_point() +
      stat_smooth(method='lm', fill=NA, fullrange=TRUE) + 
      theme(axis.text.x=element_text(angle = -45, hjust = 0)) +
      scale_y_datetime(breaks = date_breaks('month'), labels = date_format('%b-%Y'),
                       limits=x.lims) +
      geom_vline(xintercept=0.82) +
      geom_hline(yintercept = as.numeric(predicted.date)) + #to illustrate it works
      coord_flip()
    print(p)
    

    但是,不建议这样做,因为您的时间值的不确定性很可能远小于您的 Save.Rate 值的不确定性。因此,您可能应该按照您的情节进行回归Save.Rate ~ End.Date,并按照 Ben 的回答进行逆向预测。

    【讨论】:

      猜你喜欢
      • 2020-10-12
      • 2017-09-17
      • 1970-01-01
      • 2023-01-31
      • 1970-01-01
      • 2023-02-11
      • 1970-01-01
      • 2020-11-14
      相关资源
      最近更新 更多