使用class.ind()从多级因子溢出整数?

时间:2015-12-18 20:05:56

标签: r integer-overflow categorical-data r-factor nnet

我试图改变一个"大"将因子分解为R中的一组指标(即虚拟,二元,标志)变量:

FLN <- data.frame(nnet::class.ind(FinelineNumber))

其中FinelineNumber是来自Kaggle.com当前沃尔玛竞赛的5000级因素(如果您想重现此错误,则数据是公开的。)

我一直收到这个看起来很有意思的警告:

In n * (unclass(cl) - 1L) : NAs produced by integer overflow

系统可用的内存基本上是无限的。我不确定问题是什么。

1 个答案:

答案 0 :(得分:6)

nnet::class.ind的源代码是:

function (cl)     {
    n <- length(cl)
    cl <- as.factor(cl)
    x <- matrix(0, n, length(levels(cl)))
    x[(1L:n) + n * (unclass(cl) - 1L)] <- 1
    dimnames(x) <- list(names(cl), levels(cl))
    x
}

.Machine$integer.max是2147483647.如果n*(nlevels - 1L)大于此值,则会产生错误。解决n

imax <- .Machine$integer.max
nlevels <- 5000
imax/(nlevels-1L)
## [1] 429582.6

如果您有429583或更多行(对于数据挖掘上下文而言不是特别大),您将遇到此问题。如上所述,如果您的建模框架可以处理稀疏矩阵,那么您可以使用Matrix::sparse.model.matrix(或Matrix::fac2sparse)更好地 。或者,你必须重写class.ind以避免这个瓶颈(即按行和列而不是绝对位置进行索引)[@joran注释上面的R通过双精度值索引大向量,所以你或许可以通过黑客攻击

来逃脱
x[(1:n) + n * (unclass(cl) - 1)] <- 1

可能会在这里或那里投下一个明确的as.numeric()来迫使强制加倍......]

即使您能够完成此步骤,您最终也会获得5000 * 650000矩阵 - 看起来这将是12Gb。

 print(650*object.size(matrix(1L,5000,1000)),units="Gb")

我想如果你有100Gb免费可以,那就好......