r - na.fail.default(list(Fe = c(568L, 437L, 599L, 1016L, 670L, 1951L, : 对象中的缺失值
问题描述
我正在尝试使用具有 XRF 光谱的 Fe 浓度运行 PLSR 模型。光谱矩阵包含一些零值。在弹出错误消息之前我使用的代码如下:
#------------------------------------------------------------------------
dataset<-data.frame(cbind(chem_properties$Fe, xrf_spectra))
names(dataset)[1]<-"Fe"
summary(dataset$Fe)
dim(dataset)
plot(dataset$Fe)
#######################################
## Building calibration model
# Dataset partitioning
set.seed(100)
pls_Fe <- createDataPartition(dataset$Fe, p = 0.7, list = FALSE)
training <- dataset[pls_Fe,]
testing <- dataset[-pls_Fe,]
summary(training$Fe)
summary(testing$Fe)
# =================================================
# Model
tc <- trainControl(method = "repeatedcv", number = 10, repeats = 5)
tg <- data.frame(ncomp = seq(2, 15, by =1))
pls_rcv <- train(Fe~.,
data = training,
preProcess = c("center", "scale"),
method = "pls",
tuneGrid = tg,
trControl = tc)
#----------------------------------------------------------------------------------
每当我运行最后一行(即 pls_rcv)时,都会显示此错误消息;
...... na.fail.default(list(Fe = c(568L, 437L, 599L, 1016L, 670L, 1951L, : 对象中的缺失值...... …………
尽管我的问题与之前提出的一些问题相似,但在这些情况下我已经尝试了一些建议的解决方案,但似乎都没有奏效。也许我宁愿做错事。
建议之一是在整个数据框上使用 na.exclude() 。收到您的反馈,我将不胜感激。
解决方案
所以这是答案的第一遍,但没有在数据的子样本上达到峰值,这是我可以给出的要点。
首先,我们可以设置一些假数据并添加一些缺失的案例来解决第一个问题。
# Some fake data
dat <- mtcars
# Now lets add some missing data
dat[sample(x = 1:nrow(dat), size = 5),
sample(x = 1:ncol(dat), size = 5)] <- NA
现在我们查看我们的数据,我们看到我们有一些缺失值:(该函数计算每列缺失的单元格,然后将输出转换为数据框以便于呈现)
as.data.frame(lapply(dat, function(x) sum(is.na(x))))
#> mpg cyl disp hp drat wt qsec vs am gear carb
#> 1 0 5 0 0 5 5 0 5 5 0 0
如果我们知道我们不能有缺失值,那么我们可以使用该complete.cases
函数只保留那些没有任何 NA 的行。
dat_complete <- dat[complete.cases(dat),]
这会删除一些记录(在我的情况下为 5)
nrow(dat) -nrow(dat_complete)
#> [1] 5
另外:如果删除丢失的数据是有问题的(例如,从这些数据中丢弃信息可能会使您的估计产生偏差。也许数据不是完全随机丢失,或者存在已知的仪器故障),有许多插补和联合估计的方法的缺失值。
第二个问题处理不包含所有因素的拆分。
例如,如果我要向我的数据集添加一个因子并生成分区,那么查看我是否在训练数据中捕获了该因子很重要。
# Add factor (note D is a rare letter)
library(caret)
dat_complete$my_factor <- factor(sample(x = letters[1:4],
size = nrow(dat_complete),
prob = c(.7,.2,.15,.05), replace = T))
pls_Fe <- createDataPartition(dat_complete$mpg, p = 0.7, list = FALSE)
training <- dat_complete[pls_Fe,]
testing <- dat_complete[-pls_Fe,]
当我查看我的测试和训练数据时,我发现虽然我的测试数据有一个“D”,但我的训练数据没有。
table(training$my_factor)
#> a b c
#> 14 6 0
table(testing$my_factor)
#> a b c
#> 5 1 1
模型无法在新的因子水平上可靠地预测(当然,一般来说,还有更多方法)。
如何解决这个问题?如果在上下文中有意义,您始终可以将因子转换为数字(增加偏差,但允许您的模型工作)。你可能需要放弃你的分裂(而不是 70% 的训练,做 60%,看看你是否捕获了一些低发生率的样本)。如果预测变量不相关,则将它们从考虑中删除。此外,鉴于这是 PLS,您还可以尝试 one-hot 编码。这会将因子列拆分为 n-1 列,其中 1 或 0 表示因子表示。在完整的数据集上执行此操作(仅当您知道您将始终观察因素时,例如该值只能采用一个类别)。
dumz <- dummyVars(~my_factor, data = dat_complete)
dat_dummies <- cbind(dat_complete, predict(dumz, dat_complete))
dat_dummies <- dat_dummies[,names(dat_dummies) !="my_factor"]
pls_Fe <- createDataPartition(dat_dummies$mpg, p = 0.7, list = FALSE)
training <- dat_dummies[pls_Fe,]
testing <- dat_dummies[-pls_Fe,]
推荐阅读
- mysql - MYSQL 在选择中多次使用派生值
- javascript - 无法获取 cookie 值
- javascript - React 组件在 Redux 商店更新时未收到 props
- java - 有关 NullPointerExceptions 的更多详细信息?
- mongodb - MongoDB - 在排除重复的条件下对特定数组元素求和
- python - 将整数约束置于神秘之中
- javascript - 如何将laravel api与纯html网站连接起来
- mysql - 在存储方法 Laravel-Eloquent 中遇到问题
- python - 将 CSV 中的 UTC 时间戳转换为本地时间 (PST)
- ansible - Ansible:读取属性值的 XML 模块