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

在R中使用caret/recipes实现YeoJohnson变换遇问题求助

问题:如何让caret和recipes包对所有数值列执行YeoJohnson变换?

在使用caret和recipes包对spam数据集的数值列执行YeoJohnson变换时,出现仅部分变量被转换的情况,而bestNormalize和sklearn的PowerTransformer能正常转换所有列。以下是针对两个包的解决方法:


针对caret包的解决方法

caret的preProcess()函数中,YeoJohnson变换默认会通过Shapiro-Wilk检验判断变量是否需要变换,默认阈值thresh=0.9——当变量的Shapiro-Wilk检验p值大于0.9时,认为变量已足够接近正态分布,会跳过变换。要强制对所有数值列应用变换,只需将thresh设置为0:

library(tidyverse)
library(tidytuesdayR)
library(caret)

spam <- tt_load(2023, week=33)$spam

# 修改preProcess参数,强制所有变量执行YeoJohnson变换
pp_hpc <- caret::preProcess(spam[,1:6], 
                            method = c("center", "scale", "YeoJohnson"),
                            thresh = 0) # 关键参数:设置阈值为0

# 查看预处理结果,此时所有6个变量都会被标记为Yeo-Johnson转换
pp_hpc

# 应用变换
transformed <- predict(pp_hpc, newdata = spam[,1:6])

针对recipes包的解决方法

recipes的step_YeoJohnson()同样默认带有**threshold=0.9**的参数逻辑,即跳过正态性足够的变量。要强制转换所有数值列,只需在步骤中设置threshold=0:

library(recipes)

# 定义配方(即使仅用于转换数据,此结构是合规的)
rec <- recipe(yesno ~ ., data = spam)

# 修改step_YeoJohnson参数,强制所有数值列变换
yj_transform <- step_YeoJohnson(rec, all_numeric(), threshold = 0)
yj_estimates <- prep(yj_transform, verbose = T)

# 查看训练后的配方,此时所有数值变量都会被标记为已执行Yeo-Johnson变换
yj_estimates

# 应用变换
yj_te <- bake(yj_estimates, spam)

核心原因说明

caret和recipes的YeoJohnson实现默认加入了正态性检验的筛选逻辑,目的是避免对已经近似正态的变量做冗余变换。若需要强制转换所有数值列,只需将检验阈值设为0,跳过筛选逻辑即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 06:11:16