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

使用h2o::h2o.glrm()处理混合数据时遇错误求排查

H2O GLRM混合类型变量降维报错排查与修正

需求说明

使用H2O的h2o.glrm()对包含二元变量(两水平因子)、多水平名义因子、多水平有序因子的混合数据集降维,对应损失函数分别为Logistic、Categorical、Ordinal。

原始代码与报错

初始代码(全因子数据集)

# Load packages
library(tibble)
library(h2o)

# Example data for MRE
my_data <- tibble::tibble(
  var.1 = as.factor(rep(1, 10)),
  var.2 = as.factor(c(NA, 1, 1, -1, -1, -1, 1, 1, 1, 1)),
  var.3 = as.factor(rep(-1, 10)),
  var.4 = as.factor(c(-1, 1, 1, 1, 1, 1, -1, 1, 1, 1)),
  var.5 = as.factor(rep(-1, 10)),
  var.6 = as.factor(c(1, 2, 3, 1, 2, 2, 2, 2, 2, 3)),
  var.7 = as.factor(c(NA, 2, 3, 2, 2, 2, 2, 3, 1, 2)),
  var.8 = as.factor(c(2, 3, 2, 2, 2, 2, 3, 2, 2, 2)),
  var.9 = as.factor(c(1, 2, 3, 4, 1, 2, 3, 4, 1, 3)),
  var.10 = as.factor(c(1, 1, 1, 1, NA, 1, 1, -1, -1, 1))
)

my_data_types <- tibble::tibble(
  var_name = paste("var", 1:10, sep = "."),
  var_type = c(rep("binary", 5),
               rep("ordinal", 3),
               "nominal", "binary")
)

# Initialize h2o cluster
h2o::h2o.init()
h2o::h2o.no_progress()

# Convert data to h2o object
my_data_h2o <- h2o::as.h2o(my_data)

# Define loss function for ordinal and nominal variables
losses <- tibble::tibble(
  index = which(my_data_types$var_type %in% c("ordinal", "nominal")) - 1,
  loss = NA_character_
)

for (i in seq_along(losses$index)) {
  losses$loss[i] <- 
    ifelse(my_data_types$var_type[losses$index[i] + 1] == "ordinal", "Ordinal", 
           ifelse(my_data_types$var_type[losses$index[i] + 1] == "nominal", "Categorical", NA))
}

# Run GLRM
my_glrm <- h2o::h2o.glrm(
  training_frame = my_data_h2o,
  k = 2,
  loss = "Logistic",
  loss_by_col_idx = losses$index,
  loss_by_col = losses$loss,
  regularization_x = "None",
  regularization_y = "None",
  transform = "NONE",
  max_iterations = 2000,
  seed = 12345
)

初始报错

Error in .h2o.doSafeREST(h2oRestApiVersion = h2oRestApiVersion, urlSuffix = page,  : 
  
ERROR MESSAGE:

Illegal argument(s) for GLRM model: GLRM_model_R_1683532209346_20.  Details: ERRR on field: _loss: Logistic is not a numeric loss function

替代代码(二元变量转数值)

# Alternative example data for MRE
my_data_2 <- tibble::tibble(
  var.1 = rep(1, 10),
  var.2 = c(NA, 1, 1, -1, -1, -1, 1, 1, 1, 1),
  var.3 = rep(-1, 10),
  var.4 = c(-1, 1, 1, 1, 1, 1, -1, 1, 1, 1),
  var.5 = rep(-1, 10),
  var.6 = as.factor(c(1, 2, 3, 1, 2, 2, 2, 2, 2, 3)),
  var.7 = as.factor(c(NA, 2, 3, 2, 2, 2, 2, 3, 1, 2)),
  var.8 = as.factor(c(2, 3, 2, 2, 2, 2, 3, 2, 2, 2)),
  var.9 = as.factor(c(1, 2, 3, 4, 1, 2, 3, 4, 1, 3)),
  var.10 = c(1, 1, 1, 1, NA, 1, 1, -1, -1, 1)
)

# Convert data to h2o object
my_data_2_h2o <- h2o::as.h2o(my_data_2)

# Run GLRM
my_glrm_2 <- h2o::h2o.glrm(
  training_frame = my_data_2_h2o,
  k = 2,
  loss = "Logistic",
  loss_by_col_idx = losses$index,
  loss_by_col = losses$loss,
  regularization_x = "None",
  regularization_y = "None",
  transform = "NONE",
  max_iterations = 2000,
  seed = 12345
)

替代代码报错

Error in .h2o.doSafeREST(h2oRestApiVersion = h2oRestApiVersion, urlSuffix = page,  : 
  
ERROR MESSAGE:

Illegal argument(s) for GLRM model: GLRM_model_R_1683532209346_21.  Details: ERRR on field: _loss: Logistic is not a numeric loss function
ERRR on field: _loss_by_col: Loss function Logistic cannot be applied to numeric column 0
ERRR on field: _loss_by_col: Loss function Logistic cannot be applied to numeric column 1
ERRR on field: _loss_by_col: Loss function Logistic cannot be applied to numeric column 6

错误原因

  1. 全局损失参数错误:loss参数是所有未通过loss_by_col指定损失的列的默认损失,H2O要求该参数必须是数值型损失函数(如Quadratic),而Logistic属于分类损失,不能作为全局默认。
  2. 损失函数与列类型不匹配:
    • Logistic损失仅适用于二分类因子列,不能用于数值列,将二元变量转成数值后,无法应用Logistic损失。
    • 初始代码中仅给有序、名义列指定了损失,二元列使用全局的Logistic损失,但全局损失不允许用分类损失,导致冲突。

修正方案

  1. 全局默认损失loss设置为数值型损失(如"Quadratic")。
  2. 所有分类列(二元、有序、名义)都通过loss_by_col_idx和loss_by_col指定对应损失,确保每类变量匹配正确的损失函数:
    • 二元因子列:"Logistic"
    • 有序因子列:"Ordinal"
    • 多水平名义因子列:"Categorical"
  3. 二元变量保留为因子类型,确保H2O识别为二分类列,适配Logistic损失。

修正后可运行代码

library(tibble)
library(h2o)
library(dplyr)

# 初始化H2O集群
h2o.init()
h2o.no_progress()

# 构造混合类型数据集
my_data <- tibble(
  var.1 = as.factor(rep(1, 10)),
  var.2 = as.factor(c(NA, 1, 1, -1, -1, -1, 1, 1, 1, 1)),
  var.3 = as.factor(rep(-1, 10)),
  var.4 = as.factor(c(-1, 1, 1, 1, 1, 1, -1, 1, 1, 1)),
  var.5 = as.factor(rep(-1, 10)),
  var.6 = as.factor(c(1, 2, 3, 1, 2, 2, 2, 2, 2, 3)),
  var.7 = as.factor(c(NA, 2, 3, 2, 2, 2, 2, 3, 1, 2)),
  var.8 = as.factor(c(2, 3, 2, 2, 2, 2, 3, 2, 2, 2)),
  var.9 = as.factor(c(1, 2, 3, 4, 1, 2, 3, 4, 1, 3)),
  var.10 = as.factor(c(1, 1, 1, 1, NA, 1, 1, -1, -1, 1))
)

# 定义变量类型映射
my_data_types <- tibble(
  var_name = paste("var", 1:10, sep = "."),
  var_type = c(rep("binary", 5), rep("ordinal", 3), "nominal", "binary")
)

# 转换为H2O对象
my_data_h2o <- as.h2o(my_data)

# 为所有列映射对应损失函数
loss_mapping <- case_when(
  my_data_types$var_type == "binary" ~ "Logistic",
  my_data_types$var_type == "ordinal" ~ "Ordinal",
  my_data_types$var_type == "nominal" ~ "Categorical"
)

# 提取列索引(H2O列索引从0开始)
col_indices <- seq_along(loss_mapping) - 1

# 运行GLRM
my_glrm <- h2o.glrm(
  training_frame = my_data_h2o,
  k = 2,
  loss = "Quadratic",  # 全局默认数值损失
  loss_by_col_idx = col_indices,
  loss_by_col = loss_mapping,
  regularization_x = "None",
  regularization_y = "None",
  transform = "NONE",
  max_iterations = 2000,
  seed = 12345
)

# 查看降维结果
head(h2o.predict(my_glrm, my_data_h2o))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 08:20:13