使用 class.ind() 的多级因子的整数溢出?
Integer overflow from many-leveled factor with class.ind()?
我正在尝试将 "big" 因子转换为 R 中的一组指标(即虚拟、二进制、标志)变量:
FLN <- data.frame(nnet::class.ind(FinelineNumber))
其中 FinelineNumber
是来自 Kaggle.com 当前沃尔玛竞赛的 5,000 级因子(如果您想重现此错误,数据为 public)。
我不断收到这个令人担忧的警告:
In n * (unclass(cl) - 1L) : NAs produced by integer overflow
系统可用的内存基本上是无限的。我不确定是什么问题。
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 的免费空间就可以了...
我正在尝试将 "big" 因子转换为 R 中的一组指标(即虚拟、二进制、标志)变量:
FLN <- data.frame(nnet::class.ind(FinelineNumber))
其中 FinelineNumber
是来自 Kaggle.com 当前沃尔玛竞赛的 5,000 级因子(如果您想重现此错误,数据为 public)。
我不断收到这个令人担忧的警告:
In n * (unclass(cl) - 1L) : NAs produced by integer overflow
系统可用的内存基本上是无限的。我不确定是什么问题。
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 的免费空间就可以了...