You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

caret::train()构建含交互项线性模型调用predict.lm()报错如何解决

2021年11月9日更新

该问题实际是caret::包的特性导致的。此前的方案仅能完成常规估计,因为可以让S3自动匹配predict()的对应实现,但如果要为线性模型计算95%预测区间,必须调用predict.lm()版本的预测函数。使用lm()直接构建的模型调用该函数无异常,但使用caret::train()构建的模型调用时会抛出如下错误:

Error in eval(predvars, data, env) : 
  object 'Sepal.Length:Sepal.Width' not found

以下是可复现该问题的最小示例:

##Loading Packages and Data##
library(caret)
data(iris)

####Model with an Interaction Term####
##Building a model Using lm()##
mod.lm<-lm(Petal.Length~Petal.Width+Sepal.Length*Sepal.Width, data=iris)
print(mod.lm)#Notice the interaction term is not quoted
class(mod.lm)

##Building a model using caret::train()##
trCtrl<-trainControl(method="LOOCV", savePredictions = TRUE)
mod.caret<-train(Petal.Length~Petal.Width+Sepal.Length*Sepal.Width, data=iris, method="lm", trControl=trCtrl)
print(mod.caret$finalModel)#Notice the interaction term is now quoted
class(mod.caret$finalModel)#Notice this is also of class lm

##Getting Prediction Intervals##
PI95.lm<-predict.lm(mod.lm, iris, interval="prediction") #No Error
PI95.caret<-predict.lm(mod.caret$finalModel, iris, interval="prediction")#This will throw an error##

####Model with only additive terms Term####
##Building a model Using lm()##
mod.lm.add<-lm(Petal.Length~Petal.Width+Sepal.Length+Sepal.Width, data=iris)
print(mod.lm.add)#Notice the interaction term is not quoted
class(mod.lm.add)

##Building a model using caret::train()##
trCtrl<-trainControl(method="LOOCV", savePredictions = TRUE)
mod.caret.add<-train(Petal.Length~Petal.Width+Sepal.Length+Sepal.Width, data=iris, method="lm", trControl=trCtrl)
print(mod.caret.add$finalModel)#Notice there are now no quotes
class(mod.caret.add$finalModel)#Notice this is also of class lm

##Getting Prediction Intervals##
PI95.lm.add<-predict.lm(mod.lm.add, iris, interval="prediction") #No Error
PI95.caret.add<-predict.lm(mod.caret.add$finalModel, iris, interval="prediction")#No more error because interaction term is gone
原帖内容

我使用caret::包构建并交叉验证线性模型,用于从预测变量的rasterstack中预测属性值。实际数据中需要使用交互项并进行幂次变换,模型训练过程正常,在训练数据构成的dataframe上调用自定义的链接函数也正常,但调用raster::predict()时会抛出如下错误:

Error in eval(predvars, data, env) : object 'X3:X4' not found 

该错误表明函数尝试在rasterstack中查找名为'X3:X4'的图层,而非自动对rasterstack中独立存在的X3和X4变量计算交互项。下方是我构造的可复现问题的示例代码:

##Loading Necessary Packages##   
library(caret)#For modeling and crossvalidation
library(raster)#To handle raster data
library(snow)#For Parallel processing

set.seed(88)#For Reproducibility

##Creating some fake data for model training##
X1<-runif(100, 20, 50)
X2<-runif(100, 100, 220)
X3<-runif(100, 80, 150)
X4<-runif(100, 1000, 15000)
Y<-rnorm(100, 2000, 50)

df<-data.frame(X1=X1, X2=X2, X3=X3, X4=X4, Y=Y)

##Creating a fake model##
trCtrl<-trainControl(method="LOOCV", savePredictions = TRUE)
mod<-train(Y^0.33~X1+X2+X3*X4, data=df, method="lm", trControl=trCtrl)

##Creating rasters with fake predictor data##
WGS84<-crs("+init=epsg:4326")
RAST<-raster(xmn=-122.0, xmx=-121.5, ymn = 45.0, ymx=45.5, crs=WGS84, ncol=100, nrow=100)
R1<-RAST
values(R1)<-runif(10000, 20, 50)
R2<-RAST
values(R2)<-runif(10000, 100, 220)
R3<-RAST
values(R3)<-runif(10000, 80, 150)
R4<-RAST
values(R4)<-runif(10000, 1000, 15000)

##Combining into a single raster stack and renaming with the same predictor variable names as the training dataset##
PRED<-stack(R1, R2, R3, R4)
names(PRED)<-c("X1", "X2", "X3", "X4")

##Creating a linking function to undo the power transformation in the model##
linkfun<-function(mod, x){
  out<-predict(mod, x)^(1/0.33)
  return(out)
}

##Starting Parallel Processing##
beginCluster()

##Attempting to predict a new raster of the response variable from the fake model##
raster::predict(PRED, mod$finalModel, fun=linkfun, filename=paste(tempdir(), "/Example.tif", sep=""), datatype="FLT4S", format="GTiff")

内容的提问来源于stack exchange,提问作者Sean McKenzie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 03:54:03