Predict() - 也许我不明白
Posted
技术标签:
【中文标题】Predict() - 也许我不明白【英文标题】:Predict() - Maybe I'm not understanding it 【发布时间】:2012-02-20 04:03:04 【问题描述】:我 posted earlier today 关于使用 predict
函数时遇到的错误。我能够得到纠正,并认为我走在正确的道路上。
我有许多观察结果(实际值),并且我有一些数据点要外推或预测。我使用lm
创建模型,然后尝试使用predict
与将用作预测器输入的实际值。
这段代码在我之前的帖子中都是重复的,但这里是:
df <- read.table(text = '
Quarter Coupon Total
1 "Dec 06" 25027.072 132450574
2 "Dec 07" 76386.820 194154767
3 "Dec 08" 79622.147 221571135
4 "Dec 09" 74114.416 205880072
5 "Dec 10" 70993.058 188666980
6 "Jun 06" 12048.162 139137919
7 "Jun 07" 46889.369 165276325
8 "Jun 08" 84732.537 207074374
9 "Jun 09" 83240.084 221945162
10 "Jun 10" 81970.143 236954249
11 "Mar 06" 3451.248 116811392
12 "Mar 07" 34201.197 155190418
13 "Mar 08" 73232.900 212492488
14 "Mar 09" 70644.948 203663201
15 "Mar 10" 72314.945 203427892
16 "Mar 11" 88708.663 214061240
17 "Sep 06" 15027.252 121285335
18 "Sep 07" 60228.793 195428991
19 "Sep 08" 85507.062 257651399
20 "Sep 09" 77763.365 215048147
21 "Sep 10" 62259.691 168862119', header=TRUE)
str(df)
'data.frame': 21 obs. of 3 variables:
$ Quarter : Factor w/ 24 levels "Dec 06","Dec 07",..: 1 2 3 4 5 7 8 9 10 11 ...
$ Coupon: num 25027 76387 79622 74114 70993 ...
$ Total: num 132450574 194154767 221571135 205880072 188666980 ...
代码:
model <- lm(df$Total ~ df$Coupon, data=df)
> model
Call:
lm(formula = df$Total ~ df$Coupon)
Coefficients:
(Intercept) df$Coupon
107286259 1349
预测代码(基于之前的帮助):
(这些是我想用来获取预测值的预测值)
Quarter = c("Jun 11", "Sep 11", "Dec 11")
Total = c(79037022, 83100656, 104299800)
Coupon = data.frame(Quarter, Total)
Coupon$estimate <- predict(model, newdate = Coupon$Total)
现在,当我运行它时,我收到以下错误消息:
Error in `$<-.data.frame`(`*tmp*`, "estimate", value = c(60980.3823396919, :
replacement has 21 rows, data has 3
我用来构建模型的原始数据框中有 21 个观察值。我现在正在尝试根据模型预测 3 个值。
我要么没有真正理解这个函数,要么我的代码有错误。
我们将不胜感激。
谢谢
【问题讨论】:
您几乎可以肯定需要使用data
参数到 lm
以使其工作,即 model <- lm(Total ~ Coupon, data=df)
。那我建议Coupon$estimate <- predict(model, newdata = Coupon)$Total
@BenBolker 我同意第一部分,但不太确定第二部分。我认为predict(model, newdata = Coupon)
应该是他想要的。
@joran 是的,我认为你是对的。
@BenBolker & @joran 更新了代码以反映 Ben 建议的 data=df
。结果相同。然后我将其更新为 joran 的建议。同样的错误。
您没有按照 Ben 的说明进行更新。注意到您的配方规格有所不同了吗? df$Total
与 Total
相比。你的方式,当你使用predict
时,它会寻找一个名为df$Coupon
的变量,而不仅仅是Coupon
(我认为)。至少,名字不匹配。
【参考方案1】:
首先,你要使用
model <- lm(Total ~ Coupon, data=df)
不是model <-lm(df$Total ~ df$Coupon, data=df)
.
其次,通过说lm(Total ~ Coupon)
,您正在拟合一个使用Total
作为响应变量、Coupon
作为预测变量的模型。也就是说,您的模型采用Total = a + b*Coupon
的形式,其中a
和b
是要估计的系数。请注意,响应位于 ~
的左侧,而预测变量位于右侧。
因此,当您要求 R 为您提供模型的预测值时,您必须提供一组新的 predictor 值,即 Coupon
的新值,而不是 Total
.
第三,根据您对newdata
的规范判断,看起来您实际上是在寻找适合Coupon
作为Total
函数的模型,而不是相反。为此:
model <- lm(Coupon ~ Total, data=df)
new.df <- data.frame(Total=c(79037022, 83100656, 104299800))
predict(model, new.df)
【讨论】:
我认为你的公式倒过来了。此外,new.df
应该包含Coupon
而不是Total
。另外,我对原始问题的回答也很有效;)
@JoshO'Brien:我要关闭 OP 发布的新数据,它指定了 Total
的值。这意味着他实际上是在寻找一个模型来预测Coupon
。
但他总是把Total
放在公式的左上角,就像你在帖子的开头行一样!除非我非常困惑,否则Coupon
应该是预测器。 (并不是说它与您试图理解的概念一样重要)。
我怀疑 OP 可能对响应变量应该在 ~
的哪一侧感到困惑。我会更新我的答案。
@mikebmassey:再次检查我的答案,我刚刚编辑了它。确保您在公式的 LHS 上有 Coupon
,并且您输入的代码与我在答案的最后 3 行中得到的完全一致。【参考方案2】:
谢谢洪,这正是我遇到的问题。您得到的错误表明行数错误,但问题实际上是模型已使用最终参数名称错误的命令进行训练。
这确实是一个关键细节,对于 lm 等来说完全不明显。一些教程参考了像lm(olive$Area@olive$Palmitic)
这样的行 - 以 Olive$Area NOT Area 的变量名结束,因此不能使用 anewdata<-data.frame(Palmitic=2)
创建条目。如果您使用lm(Area@Palmitic,data=olive)
,那么变量名称是正确的并且预测有效。
真正的问题是错误信息根本没有说明问题:
警告消息:“anewdata”有 1 行,但发现变量有 X 行
【讨论】:
谢谢,这是非常重要的一点,我也得到了你提到的错误。将您的答案应用到 Hong 的回复中:如果他的 new.df 中的列未命名为“Total”,这与原始数据框的列名相同,那么他会得到你(和我)得到的错误。因此,确保 newdata 中的列名与原始模型中的预测变量相同非常重要。 将此标记为不是答案。@
-operator 的使用表明您正在处理一个 S4 对象,这与原始问题或答案无关。你错误地将你的困难与一个未指明的家庭作业问题与一个得到充分回答的更简单的问题混为一谈。【参考方案3】:
您在预测代码中使用 newdate 而不是 newdata,验证一次。只需使用Coupon$estimate <- predict(model, Coupon)
它会起作用的。
【讨论】:
【参考方案4】:为避免错误,关于新数据集的重要一点是自变量的名称。它必须与模型中报告的相同。另一种方法是嵌套两个函数而不创建新数据集
model <- lm(Coupon ~ Total, data=df)
predict(model, data.frame(Total=c(79037022, 83100656, 104299800)))
注意模型。接下来的两个命令类似,但是对于预测功能,第一个起作用第二个不起作用。
model <- lm(Coupon ~ Total, data=df) #Ok
model <- lm(df$Coupon ~ df$Total) #Ko
【讨论】:
以上是关于Predict() - 也许我不明白的主要内容,如果未能解决你的问题,请参考以下文章
为啥更改 dict2 内的嵌套 dict 会影响 dict1? [复制]