UBL::SmoteClassif()输入对Fortran向量长度的影响及行数上限计算
UBL::SmoteClassif() 最大处理行数计算规则与错误解析
错误根源
触发long vectors (argument 10) are not supported in .Fortran错误的核心原因是:SmoteClassif对需要过采样的类处理时,会在该类的样本子集内部调用neighbors函数,而该函数依赖的Fortran底层代码不支持长度超过2^31 - 1(约21.47亿)的向量。当需要过采样的类的样本数n_cls满足n_cls² > 2^31 - 1时,Fortran代码生成的两两距离向量长度会超出限制,导致报错。
最大处理行数推导公式
核心限制
对于任何需要过采样的类(即C.perc[类名] > 1的类),其样本数必须满足:
n_cls ≤ floor(sqrt(2^31 - 1)) = 46340
注:sqrt(2^31 - 1)≈46340.95,取整数部分为46340,此时46340² = 2147395600,小于2^31 - 1 = 2147483647。
数据集最大总行数计算
整个数据集的最大行数由两部分组成:
总行数_max = sum(每个需要过采样类的最大样本数) + sum(无需过采样类的样本数)
其中,每个需要过采样类的最大样本数为46340;无需过采样类(C.perc[类名] = 1)的样本数没有限制(因为不会对其调用触发错误的Fortran代码)。
问题案例验证
报错数据集(186274行,186列)
需要过采样的类中,Class_7的样本数为84307,远大于46340,84307² ≈7.108e9,远超2^31 -1的限制,因此触发错误。
正常运行数据集(357038行,147列)
需要过采样的类中,最大样本数为Class_1的31878,31878²≈1.016e9,小于2^31-1,因此可以正常运行。
核心逻辑验证
以下是UBL包源码中的关键逻辑片段:
- SmoteClassif对每个需要过采样的类,提取该类的样本子集传入
smote函数:
# smoteClassif.R 核心逻辑 for (i in 1:length(whichClasses)) { clsInd <- which(tt == whichClasses[i]) perc <- C.perc[[whichClasses[i]]] if (perc > 1) { newExs <- smote(X = dat[clsInd, ], N = perc - 1, k = k, dist = dist, p = p) # ... } }
smote函数在子集内部调用neighbors计算近邻,此时dat是类子集,样本数为该类的样本量:
# smote.R 核心逻辑 smote <- function(X, N, k, dist, p) { n <- nrow(X) for (i in 1:n) { neig <- neighbors(tgt = i, dat = X, dist = dist, p = p, k = k) # ... } }
内容的提问来源于stack exchange,提问作者Kevin
相关产品推荐
相关产品推荐

