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

R语言stratified分层抽样出现因子水平抽样比例异常问题

问题根源

你遇到的抽样错位问题,完全是splitstackshape包中stratified()函数的size参数解析规则和你的预期不符导致的,这个函数根本不支持「通过命名小数向量给不同分层设置不同组内抽样比例」的用法,具体规则如下:

  • 当size传入单个小于1的数值时,函数才会在所有分层内统一按该比例抽样,自然保持原有类分布;
  • 当size传入所有元素均≥1的整数型命名向量时,函数才会按名称匹配对应分层,抽取固定整数个样本——这也是你之前传整数时运行正常的原因;
  • 只要传入的命名向量里包含小于1的小数值,就会触发函数的异常解析逻辑:
    1. 如果所有小数加和等于1,函数会把这些值当成「最终抽中样本的组间权重占比」,而非每个组内的抽样比例,再加上因子类列和命名向量的匹配bug,会出现比例完全错位:你给BARBUNYA设置的0.097抽样比例实际被应用到了SEKER类,BARBUNYA类反而被分配了最小的0.038抽样比例,所以每次抽走的该类样本最少,迭代到最后占比异常偏高。
    2. 如果小数加和不等于1(比如你把BARBUNYA的比例改成0.5后,向量总和约1.4),函数会自动把所有小于1的数值向下取整为0,相当于默认该类不抽样,所以哪怕你把比例改成0.5,因为数值仍小于1,实际抽样量和设0.097时几乎没有差别。

正确实现方式

如果你的目的是迭代缩样时保持各类的原始占比不变,根本不需要给每个类单独传比例,每次迭代直接给size传单个保留比例即可,比如每次移除10%样本就设size=0.9,函数会自动在每个类内按90%比例抽样保留,类分布不会偏移。
如果确实需要给不同类设置不同的抽样/移除比例,不要依赖stratified的向量传参,直接按类分组抽样即可,参考代码:

library(dplyr)
# 这里写每个类的保留比例=1-对应移除比例
keep_ratio <- c(
  "BARBUNYA" = 1 - 0.09712732,
  "BOMBAY" = 1 - 0.03835133,
  "CALI" = 1 - 0.11975608,
  "DERMASON" = 1 - 0.26052458,
  "HOROZ" = 1 - 0.14165014,
  "SEKER" = 1 - 0.14892366,
  "SIRA" = 1 - 0.19366689
)

while(nrow(beanclone) > 100) {
  beanclone <- beanclone %>%
    group_by(Class) %>%
    slice_sample(prop = unname(keep_ratio[cur_group()$Class])) %>%
    ungroup()
  print(table(beanclone$Class))
  print(nrow(beanclone))
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 08:51:27