R从多元多项式模型预测

时间:2015-12-05 19:35:11

标签: r linear-regression

我在没有标题的数据框(数据)中有3列数据。

第1列和第2列是自变量,第3列是因变量。

我必须在自变量中拟合3阶多项式。

我做了:

dm <- data.matrix(data[,1:2])
pmodel <- lm(data.matrix(data[,3])~poly(dm,degree = 3,raw=TRUE))

现在我如何预测给定的一对独立变量的答案(0.77,0.36)?

我试过了:

predict.lm(pmodel,data.frame(0.77,0.36))

但这会产生一些错误:

'newdata'有1行,但找到的变量有100行

1 个答案:

答案 0 :(得分:2)

好的,有几个问题要处理。我首先尝试模仿你描述的情况,一个没有名字的数据集。实际上,如果它是一个data.frame对象(即data.frame(0.77,0.36) 返回data.frame),它几乎肯定有名字。如果你只是运行创建newdata data.frame的位:

,你可以看到这个
 ## make a matrix without names from iris data
 data <- matrix(unlist(iris[,1:3]),nrow=nrow(iris))

 pmodel <- lm(data[,3]~poly(data[,1:2],degree = 3,raw=TRUE))
 # variable names are ugly
 summary(pmodel)

自动名称很难看,但是它们就在那里:X0.77 X0.36

但是,让我们获取没有名字的数据,看看会发生什么。

 test <- predict.lm(pmodel,data.frame(0.77,0.36))

不使用名称的困难是,predict()无法弄清楚如何将新值映射到数据中的列,除非传递给newdata参数的data.frame中的标签与模型框架。因此,在下面的代码中,您会收到警告,因为newdata没有正确的名称,并且没有正确的长度。

 all.equal(test,fitted(pmodel)) # TRUE

但测试中有什么东西吗?

 df = as.data.frame(data) 
 names(df) #  automatically creates variable names
 names(df) <- c("X","Y","Z") # change 'em if you want

 pmodel2 <- lm(Z~poly(X,Y,degree=3, raw=TRUE),data=df)

发生了什么是predict()忽略了新数据,只返回了模型的拟合值。那么,如何使用带有名称的data.frame呢?

 all.equal(coef(pmodel),coef(pmodel2)) # matches except for names

我们可以检查这是与以前相同的对象:

 nd <- data.frame(X=0.77,Y=0.36)
 predict(pmodel2,newdata=nd)

但是,如果我们再次尝试预测,我们会得到一个不同的错误!

colnames<-
  

*tmp*中的错误( nd <- data.frame(X=c(0.77,0.89),Y=c(0.36,0.4)) predict(pmodel2,newdata=nd) # check against fitted values predict(pmodel2,newdata=df[1:2,]) fitted(pmodel2)[1:2] ,值= apply(z,1L,函数(x)   粘贴(x,:尝试在小于的对象上设置&#39; colnames&#39;   二维

由于超出我的原因但与计算多项式的方式有关,您需要至少2行newdata。

nd <- data.frame(X=rep(0.77,times=2),Y=rep(0.36,times=2))
predict(pmodel2,newdata=nd)[1]

如果你真的需要一个预测,你可以复制它并扔掉一行结果。

 ff <- as.formula(paste("Z~poly(",
                  paste0(names(df)[1:2],collapse=", "),
                  ", degree=3,raw=TRUE)"))

编辑:问题是列数未知,因此使用poly()中列的名称很难自动完成。但!我们可以用名字进行计算。像这样创建公式

  pmodel <- lm(ff, data=df)

然后

{{1}}

可能有更好的方法来做到这一点,但这有效。