tidymodels中step_ns()报错:qr.default()存在NA/NaN/Inf问题
解决
step_ns()调用中qr.default()的NA/NaN/Inf报错问题 问题根源
你触发报错的核心原因是:step_ns()(自然样条变换)仅适用于连续型数值变量,但你用all_predictors()把数据集里的所有预测变量都纳入了变换——而bfi中的A1:O5是离散的Likert量表数据(取值为1-5的整数),这类变量在交叉验证的子集折叠中,容易出现方差为0的情况(比如某折叠里某变量所有取值完全相同),导致样条基计算生成奇异矩阵,最终触发QR分解的报错。
解决方案
1. 仅对真正的连续变量应用样条变换
你的数据中只有age是连续变量,修改recipe,只针对age执行样条变换:
bfi_rec = recipe( bfi, vars = bfi %>% select(age, A1:O5) %>% names(), roles = c("outcome", rep("predictor", 25)), ) %>% step_ns(age, deg_free = 3) # 仅对连续变量age应用样条变换
2. (可选)处理离散变量的替代方案
如果非要对离散型预测变量做变换,不建议用样条(不符合统计逻辑),可以选择:
- 对有序离散变量用多项式变换:
step_poly(A1:O5, degree = 2) - 先移除近零方差变量,避免交叉验证中出现奇异矩阵:
bfi_rec = recipe( bfi, vars = bfi %>% select(age, A1:O5) %>% names(), roles = c("outcome", rep("predictor", 25)), ) %>% step_nzv(all_predictors()) # 先移除近零方差变量 step_ns(age, deg_free = 3) # 仅对连续变量做样条
3. 验证变量分布(排查前置步骤)
可以先检查所有预测变量的类型和分布,确认没有极端取值或方差为0的情况:
bfi %>% select(all_predictors()) %>% summary()
修改后的完整可运行代码
library(tidyverse) library(tidymodels) library(psych) # 数据准备 bfi = psych::bfi %>% na.omit() bfi = bfi %>% select(A1:O5, age) # 修正后的recipe bfi_rec = recipe( bfi, vars = bfi %>% select(age, A1:O5) %>% names(), roles = c("outcome", rep("predictor", 25)), ) %>% step_ns(age, deg_free = 3) # 模型与工作流 bfi_model = linear_reg() %>% set_engine("lm") %>% set_mode("regression") bfi_wf = workflow() %>% add_recipe(bfi_rec) %>% add_model(bfi_model) # 交叉验证与重采样 set.seed(1) bfi_folds = vfold_cv(bfi, v = 5) bfi_res = fit_resamples( bfi_wf, bfi_folds, control = control_resamples(save_pred = TRUE) ) # 查看结果 bfi_res %>% collect_metrics() %>% filter(.metric == "rsq")
补充说明
你之前尝试的换公式、换数据集、换引擎等方法无效,是因为问题出在预处理逻辑错误(给离散变量用样条),而非模型或数据集本身的问题——哪怕换数据集,只要对离散变量用step_ns(),依然可能触发同类报错。
内容的提问来源于stack exchange,提问作者CoderGuy123
相关产品推荐
相关产品推荐

