在过去的几天里,我在R中开发了多个PLS模型,用于光谱数据(波段作为解释变量)和各种植被参数(作为单独的响应变量)。总的来说,数据集由56组成。前28个(训练集)已经用于模型校准,现在我想要做的就是预测tesset中剩余的28个观测值的响应值。然而,出于某种原因,R继续为给定数量的组件返回校准集的拟合值,而不是针对独立测试集的预测。简而言之,这就是模型的样子。
# first simulate some data
set.seed(123)
bands=101
data <- data.frame(matrix(runif(56*bands),ncol=bands))
colnames(data) <- paste0(1:bands)
data$height <- rpois(56,10)
data$fbm <- rpois(56,10)
data$nitrogen <- rpois(56,10)
data$carbon <- rpois(56,10)
data$chl <- rpois(56,10)
data$ID <- 1:56
data <- as.data.frame(data)
caldata <- data[1:28,] # define model training set
valdata <- data[29:56,] # define model testing set
# define explanatory variables (x)
spectra <- caldata[,1:101]
# build PLS model using training data only
library(pls)
refl.pls <- plsr(height ~ spectra, data = caldata, ncomp = 10, validation =
"LOO", jackknife = TRUE)
然后确定包含3种组分的模型产生最佳性能而没有过度拟合。因此,使用以下命令来预测测试集中28个观测值的值,使用上述校准的PLS模型,包含3个分量:
predict(refl.pls, ncomp = 3, newdata = valdata)
看似输出很明智,我很快发现所有这些代码生成的是PLS模型的校准/训练数据的拟合值,而不是预测。我发现这是因为下面的代码,其中newdata =被省略,产生相同的结果。
predict(refl.pls, ncomp = 3)
肯定有些事情肯定会出错,虽然我似乎无法找出具体的内容。是否有人能够并且愿意帮助我朝着正确的方向前进?
答案 0 :(得分:0)
我认为问题在于输入数据的性质。查看与示例一起使用的?plsr
和str(yarn)
,plsr
需要一个非常具体的数据框,我觉得这很难处理。输入数据帧应该有一个矩阵作为其元素之一(在您的情况下,是光谱数据)。我认为以下工作正常(注意我改变了训练集的大小,使其不是原始数据的一半,用于故障排除):
library("pls")
set.seed(123)
bands=101
spectra = matrix(runif(56*bands),ncol=bands)
DF <- data.frame(spectra = I(spectra),
height = rpois(56,10),
fbm = rpois(56,10),
nitrogen = rpois(56,10),
carbon = rpois(56,10),
chl = rpois(56,10),
ID = 1:56)
class(DF$spectra) <- "matrix" # just to be certain, it was "AsIs"
str(DF)
DF$train <- rep(FALSE, 56)
DF$train[1:20] <- TRUE
refl.pls <- plsr(height ~ spectra, data = DF, ncomp = 10, validation =
"LOO", jackknife = TRUE, subset = train)
res <- predict(refl.pls, ncomp = 3, newdata = DF[!DF$train,])
请注意,我将光谱数据作为矩阵保存到数据框中,方法是使用等同于I
的{{1}}保护它。可能有更标准的方法来做到这一点,但它的工作原理。正如我所说,对我来说,数据框内的矩阵并不完全直观或易于理解。
至于为什么你的版本不能正常工作,我认为最好的解释是,所有内容都需要在传递给AsIs
的一个数据框中,以使数据源完全明确。