使用线性回归的两个不同预测之间的意外差异
Unexpected discrepancy between two different predictions using linear regression
我正在使用 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)
您不能只反转线性回归(即 date ~ 1+rate
与 rate ~ 1 +date
)并期望得到相同的答案(例如,请参阅 this question on CrossValidated). As far as I know there is no simple way to use predict.lm
on the inverse-regression to get the answer you are looking for. You need to fit rate as a function of date and use some algebra to get the predicted date. Below I show a simple calculation that works for your specific question; the answers to this question and this 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)
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 的回答进行逆向预测。
我正在使用 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)
您不能只反转线性回归(即 date ~ 1+rate
与 rate ~ 1 +date
)并期望得到相同的答案(例如,请参阅 this question on CrossValidated). As far as I know there is no simple way to use predict.lm
on the inverse-regression to get the answer you are looking for. You need to fit rate as a function of date and use some algebra to get the predicted date. Below I show a simple calculation that works for your specific question; the answers to this question and this 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)
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 的回答进行逆向预测。