R 从多元多项式模型预测
R predicting from multivariate polynomial models
我在数据框(数据)中有 3 列数据,没有 headers。
第一列和第二列是自变量,第三列是因变量。
我必须在自变量中拟合一个 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 行
OK,有几个问题要处理。我首先尝试模仿您描述的情况,一个没有名字的数据集。事实上,如果它是一个 data.frame 对象(即 class(data)
returns data.frame),它几乎肯定有名字。如果您只是 运行 创建新数据的位 data.frame:
就可以看到这一点
data.frame(0.77,0.36)
自动名称很难看,但它们就在那里:X0.77 X0.36
但是让我们获取没有名称的数据,看看会发生什么。
## 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)
不使用名称的困难在于 predict() 无法弄清楚如何将新值映射到数据中的列,除非您传递给 newdata 参数的 data.frame 中的标签与某些内容匹配在模型框架中。所以在下面的代码中你会得到一个警告,因为新数据没有正确的名称,也没有正确的长度。
test <- predict.lm(pmodel,data.frame(0.77,0.36))
但是测试里面有东西?
all.equal(test,fitted(pmodel)) # TRUE
发生的事情是 predict() 忽略了新数据,只返回了模型的拟合值。那么,使用带名称的 data.frame 怎么样?
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)
我们可以检查这是否与之前的对象相同:
all.equal(coef(pmodel),coef(pmodel2)) # matches except for names
但是,如果我们再次尝试预测,我们会得到一个不同的错误!
nd <- data.frame(X=0.77,Y=0.36)
predict(pmodel2,newdata=nd)
Error in colnames<-
(*tmp*
, value = apply(z, 1L, function(x)
paste(x, : attempt to set 'colnames' on an object with less than
two dimensions
出于我无法理解但与多项式计算方式相关的原因,您至少需要 2 行新数据。
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]
如果你真的只需要一个预测,你可以复制它并丢弃结果的一行。
nd <- data.frame(X=rep(0.77,times=2),Y=rep(0.36,times=2))
predict(pmodel2,newdata=nd)[1]
编辑:问题是列数未知,因此很难自动使用 poly() 中的列名。但!我们可以用名字做计算。像这样创建公式
ff <- as.formula(paste("Z~poly(",
paste0(names(df)[1:2],collapse=", "),
", degree=3,raw=TRUE)"))
然后是
pmodel <- lm(ff, data=df)
可能有更好的方法来做到这一点,但这很有效。
我在数据框(数据)中有 3 列数据,没有 headers。
第一列和第二列是自变量,第三列是因变量。
我必须在自变量中拟合一个 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 行
OK,有几个问题要处理。我首先尝试模仿您描述的情况,一个没有名字的数据集。事实上,如果它是一个 data.frame 对象(即 class(data)
returns data.frame),它几乎肯定有名字。如果您只是 运行 创建新数据的位 data.frame:
data.frame(0.77,0.36)
自动名称很难看,但它们就在那里:X0.77 X0.36
但是让我们获取没有名称的数据,看看会发生什么。
## 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)
不使用名称的困难在于 predict() 无法弄清楚如何将新值映射到数据中的列,除非您传递给 newdata 参数的 data.frame 中的标签与某些内容匹配在模型框架中。所以在下面的代码中你会得到一个警告,因为新数据没有正确的名称,也没有正确的长度。
test <- predict.lm(pmodel,data.frame(0.77,0.36))
但是测试里面有东西?
all.equal(test,fitted(pmodel)) # TRUE
发生的事情是 predict() 忽略了新数据,只返回了模型的拟合值。那么,使用带名称的 data.frame 怎么样?
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)
我们可以检查这是否与之前的对象相同:
all.equal(coef(pmodel),coef(pmodel2)) # matches except for names
但是,如果我们再次尝试预测,我们会得到一个不同的错误!
nd <- data.frame(X=0.77,Y=0.36)
predict(pmodel2,newdata=nd)
Error in
colnames<-
(*tmp*
, value = apply(z, 1L, function(x) paste(x, : attempt to set 'colnames' on an object with less than two dimensions
出于我无法理解但与多项式计算方式相关的原因,您至少需要 2 行新数据。
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]
如果你真的只需要一个预测,你可以复制它并丢弃结果的一行。
nd <- data.frame(X=rep(0.77,times=2),Y=rep(0.36,times=2))
predict(pmodel2,newdata=nd)[1]
编辑:问题是列数未知,因此很难自动使用 poly() 中的列名。但!我们可以用名字做计算。像这样创建公式
ff <- as.formula(paste("Z~poly(",
paste0(names(df)[1:2],collapse=", "),
", degree=3,raw=TRUE)"))
然后是
pmodel <- lm(ff, data=df)
可能有更好的方法来做到这一点,但这很有效。