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

R中调用XGBoost报错:标签长度与输入数据行数不匹配

R环境XGBoost建模标签长度不匹配报错排查

问题场景

首次在R环境中使用XGBoost搭建模型,目的是对比不同数据科学技术的建模效果。本次使用的数据集为数年前构建评分卡/PD(违约概率)模型时的留存数据集,用于验证XGBoost在该数据集上的表现。
初始运行代码如下:

keeps1 <- c("gb_estassval_woe","gb_prof_occ_woe","biztype_woe", "gb_educ_woe", "gb_region_woe", "gb_resstat_woe", "gb_leg_tel_woe", "gb_age_woe", "gb_TimeJob_woe", "gb_gender_woe", "gb_marstat_woe", "gb")
cc_dev1a <-subset(cc_dev_fin,,keeps1)

sparse_matrix <- sparse.model.matrix(gb ~ ., data =cc_dev1a)[,-1]

#gb为1/0二分类目标变量
output_vector = cc_dev1a[,gb ] == "Marked"

str(cc_dev1a)
str(sparse_matrix)
str(output_vector)
head(output_vector)
#校验记录数:output_vector共57483条,sparse_matrix共57157行
#初步猜测行数减少由缺失值导致,但未检测到NA(所有变量均已预处理为证据权重WOE整数值)

bst <- xgboost(data = sparse_matrix, label = output_vector, max_depth = 4,
eta = 1, nthread = 2, nrounds = 10,objective = "binary:logistic")

报错信息

Error in setinfo.xgb.DMatrix(dmat, names(p), p[[1]]) :
The length of labels must equal to the number of rows in the input data

初步排查结果

  • 标签向量output_vector共57483条记录,生成的稀疏矩阵sparse_matrix仅57157行,二者长度不匹配是直接报错原因
  • 初步猜测行数差异由缺失值导致,但常规NA检测未发现异常:所有变量均已预处理为证据权重(Weight of Evidence, WOE)整数值,未检测到NA值

根因说明

  • sparse.model.matrix()默认的缺失值处理规则为na.action = na.omit,会自动剔除所有包含特殊异常值的行,这类异常值包括NaN、Inf、因子变量未定义的空水平,普通is.na()检测无法覆盖全部这类值,因此会出现“没检测到NA但行数减少”的现象。
  • 标签向量直接从未做行剔除的原始数据集提取,没有和稀疏矩阵的保留行做对齐,最终出现长度不匹配。
  • 初始代码存在两处不规范写法,会放大错位风险:一是subset函数多写了一个逗号,未显式声明选择列的参数;二是提取gb列时未给列名加引号,容易被环境中同名变量干扰导致取值错误。

可行解决方案

方案1:关闭自动删行,依托XGBoost原生能力处理缺失值

XGBoost原生支持缺失值自动分裂优化,不需要提前手动删除含缺失的样本,调整sparse.model.matrix的缺失值处理参数保留所有行,同时规范列索引写法,训练前增加行数校验即可:

keeps1 <- c("gb_estassval_woe","gb_prof_occ_woe","biztype_woe", "gb_educ_woe", "gb_region_woe", "gb_resstat_woe", "gb_leg_tel_woe", "gb_age_woe", "gb_TimeJob_woe", "gb_gender_woe", "gb_marstat_woe", "gb")
cc_dev1a <- subset(cc_dev_fin, select = keeps1)

# 设定na.action = na.pass,禁止函数自动剔除样本行
sparse_matrix <- sparse.model.matrix(gb ~ ., data = cc_dev1a, na.action = na.pass)[,-1]

# 列名加引号规范索引,标签转成0/1数值型适配XGBoost要求
output_vector <- as.numeric(cc_dev1a[, "gb"] == "Marked")

# 训练前强制校验行数一致性
stopifnot(nrow(sparse_matrix) == length(output_vector))

bst <- xgboost(
  data = sparse_matrix, 
  label = output_vector, 
  max_depth = 4,
  eta = 1, 
  nthread = 2, 
  nrounds = 10,
  objective = "binary:logistic"
)

方案2:行ID对齐,同步剔除异常样本

如果需要保留sparse.model.matrix的自动剔除逻辑,可通过行ID匹配的方式,同步从标签向量中剔除对应被删的样本,避免行错位:

keeps1 <- c("gb_estassval_woe","gb_prof_occ_woe","biztype_woe", "gb_educ_woe", "gb_region_woe", "gb_resstat_woe", "gb_leg_tel_woe", "gb_age_woe", "gb_TimeJob_woe", "gb_gender_woe", "gb_marstat_woe", "gb")
cc_dev1a <- subset(cc_dev_fin, select = keeps1)
# 给原始数据集增加唯一行ID
cc_dev1a$tmp_row_id <- seq_len(nrow(cc_dev1a))

sparse_matrix <- sparse.model.matrix(gb ~ . - tmp_row_id, data = cc_dev1a)[,-1]
# 提取稀疏矩阵保留的行ID
keep_rows <- as.numeric(rownames(sparse_matrix))
# 按保留的行ID提取对应标签
output_vector <- as.numeric(cc_dev1a[keep_rows, "gb"] == "Marked")

额外排查项

如果调整后仍存在行数差异,运行以下代码全量检测非NA类的特殊异常值:

# 检测每列的NaN、Inf值数量
sapply(cc_dev1a, function(col) sum(is.nan(col) | is.infinite(col)))
# 检测因子列是否存在空字符串水平
sapply(cc_dev1a, function(col) if(is.factor(col)) sum(col == "") else 0)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 18:36:25