在R语言中计算二元分类变量均值及因子型变量分层抽样问题
二元分类变量均值计算与分层交叉验证问题解答
嘿,针对你提出的两个R语言问题,我来一步步帮你解决:
一、计算因子型二元分类变量的均值
你的Class是取值为0和1的因子类型,直接用mean(Class)会出问题——因为R里的因子底层是整数编码的(比如水平"0"对应整数1,水平"1"对应整数2),直接算均值得到的是这些整数的平均值,完全不是你想要的0/1比例。
你可以用这几种方法转换后再计算:
- 方法1:先转字符再转数值
这种方法最稳妥,不管因子水平的顺序如何都能得到正确的0/1数值:mean(as.numeric(as.character(TrimCredit$Class))) - 方法2:利用因子整数编码调整
如果你的因子水平顺序是c("0", "1"),可以直接对整数编码减1,得到真实的0和1:mean(as.integer(TrimCredit$Class) - 1) - 方法3:提前设置因子的数值标签
在创建因子的时候就指定标签为数值,后续计算更方便:TrimCredit$Class <- factor(TrimCredit$Class, levels = c("0", "1"), labels = c(0, 1)) mean(as.numeric(as.character(TrimCredit$Class)))
二、确保分层交叉验证折内类别占比一致
你提到用createFolds时,因子类型的Class好像没法保证折内比例一致,但其实createFolds本身是支持分层抽样的——只要传入因子变量,它会自动按照每个类别的比例来拆分折数。问题出在你验证比例时用了错误的均值计算方式,不是抽样的问题。
修正后的完整代码
library(caret) library(plyr) # 创建10折分层交叉验证的折数 nfold <- 10 folds <- createFolds(TrimCredit$Class, k = nfold, list = FALSE) TrimCredit$fold <- folds # 正确计算每个折中1的占比 ddply(TrimCredit, 'fold', summarise, prop_of_1 = mean(as.numeric(as.character(Class))))
为什么之前的代码看起来“没用”?
你之前的mean(Class)计算的是因子的整数编码均值,比如某折中0和1各占一半,整数编码是1和2,均值就是1.5,这会让你误以为比例不对,但实际上createFolds已经做了正确的分层抽样。转换为0/1数值后再计算,就能看到每个折的1的占比和整体数据基本一致。
更直观的验证方式
如果你想确认每个折的类别数量分布,可以统计每个折里0和1的具体个数:
ddply(TrimCredit, .(fold, Class), summarise, count = length(Class))
这样就能清晰看到每个折内两个类别的数量比例和整体数据匹配,达到了你想要的分层效果。
内容的提问来源于stack exchange,提问作者jmasselli22
相关产品推荐
相关产品推荐

