使用h2o.deeplearning模型对栅格栈执行predict函数时出错
解决h2o.deeplearning预测栅格数据时的类型不兼容错误
Error: Not compatible with requested type: [type=character; target=double].
问题原因
该错误源于栅格数据转换为H2O可处理格式时,部分特征列被识别为字符类型,但模型训练时使用的是数值型(double)特征,导致类型不匹配。具体出现在两个环节:
- 训练数据准备阶段,
terra::extract返回的数据可能存在隐式字符类型列; - 自定义预测函数
dnn_pred处理栅格数据时,未确保输出为栅格可接受的数值类型。
解决方案
1. 确保训练数据特征列均为数值型
在构建训练数据框v时,强制将所有特征列转换为双精度数值型,避免字符类型混入。
2. 修正自定义预测函数
调整dnn_pred函数,将H2O的预测结果转换为R的数值向量,适配terra::predict的要求。
修改后的完整代码
library(terra) library(h2o) library(tidyverse) h2o.init() # 创建预测图层栈 logo <- rast(system.file("external/rlogo.grd", package="raster")) names(logo) # 存在/缺失点数据 p <- matrix(c(48, 48, 48, 53, 50, 46, 54, 70, 84, 85, 74, 84, 95, 85, 66, 42, 26, 4, 19, 17, 7, 14, 26, 29, 39, 45, 51, 56, 46, 38, 31, 22, 34, 60, 70, 73, 63, 46, 43, 28), ncol=2) a <- matrix(c(22, 33, 64, 85, 92, 94, 59, 27, 30, 64, 60, 33, 31, 9, 99, 67, 15, 5, 4, 30, 8, 37, 42, 27, 19, 69, 60, 73, 3, 5, 21, 37, 52, 70, 74, 9, 13, 4, 17, 47), ncol=2) # 提取点对应的栅格值并构建训练数据 xy <- rbind(cbind(1, p), cbind(0, a)) v <- data.frame(cbind(pa=xy[,1], terra::extract(logo, xy[,2:3]))) %>% mutate(pa = as.factor(pa), # 强制所有特征列为双精度数值型 across(-pa, as.double)) str(v) # 导入数据到H2O集群 df <- as.h2o(v) # 拆分数据集为训练、验证、测试集 splits <- h2o.splitFrame(df, c(0.70,0.15), seed=1234) train <- h2o.assign(splits[[1]], "train.hex") valid <- h2o.assign(splits[[2]], "valid.hex") test <- h2o.assign(splits[[3]], "test.hex") # 定义响应变量和特征列 y <- "pa" x <- setdiff(names(train), y) # 训练深度学习模型 dl_model <- h2o.deeplearning(training_frame=train, validation_frame=valid, x=x, y=y, standardize=TRUE, seed=125) # 修正后的预测函数:确保输出为数值向量 dnn_pred <- function(model, data, ...) { # 将数据转换为H2O格式,确保特征列类型匹配 h2o_data <- as.h2o(data) # 获取预测结果的概率或类别,转换为R数值向量 pred <- h2o.predict(model, newdata=h2o_data, ...) # 这里取类别1的概率作为栅格值,可根据需求调整为其他输出 as.vector(pred$p1) } # 对栅格进行预测 p <- predict(logo, model=dl_model, fun=dnn_pred) plot(p)
关键说明
across(-pa, as.double)确保所有特征列都是双精度数值,避免类型混淆;- 自定义函数中
as.vector(pred$p1)将H2O的预测结果转换为R的数值向量,符合terra::predict对输出类型的要求; - 若需要预测类别而非概率,可替换为
as.vector(pred$predict),但需确保类别能转换为数值。
内容的提问来源于stack exchange,提问作者UseR10085
相关产品推荐
相关产品推荐

