Как устранить ошибки целочисленного переполнения при оценке R

Я пытаюсь оценить модель с помощью speedglm в R. Набор данных большой (~69,88 млн строк и 38 столбцов). Умножение количества строк и столбцов дает ~ 2,7 миллиарда, что выходит за пределы целочисленного ограничения. Я не могу предоставить данные, но следующие примеры воссоздают проблему.

library(speedglm)

# large example that works 
require(biglm)
n <- 500000
k <- 500
y <- rgamma(n, 1.5, 1)
x <- round(matrix(rnorm(n*k), n, k), digits = 3)
colnames(x) <- paste("s", 1:k, sep = "")
da <- data.frame(y, x)
fo <- as.formula(paste("y~", paste(paste("s", 1:k, sep = ""), collapse = "+")))   
working.example <- speedglm(fo, data = da, family = Gamma(log))

# repeat with large enough size to break 
k <- 5000       # 10 times larger than above
x <- round(matrix(rnorm(n*k), n, k), digits = 3)
colnames(x) <- paste("s", 1:k, sep = "")
da <- data.frame(y, x)
fo <- as.formula(paste("y~", paste(paste("s", 1:k, sep = ""), collapse = "+")))   
failed.example <- speedglm(fo, data = da, family = Gamma(log))

# attempting to resolve error with chunksize
attempted.fixed.example <- speedglm(fo, data = da, family = Gamma(log), chunksize = 10^6)

Это вызывает ошибку и предупреждение о переполнении целого числа.

Error in if (!replace && is.null(prob) && n > 1e+07 && size <= n/2) .Internal(sample2(n,  :  
  missing value where TRUE/FALSE needed
In addition: Warning message:
In nrow(X) * ncol(X) : NAs produced by integer overflow 

Я понимаю предупреждение, но не понимаю ошибки. В этом случае они кажутся связанными, поскольку появляются вместе после каждой попытки.

Удаление столбцов позволяет завершить оценку. Кажется, не имеет значения, какие столбцы удаляются; удаление взаимодействующих или не взаимодействующих переменных приведет к завершению оценки. Опция chunksize была добавлена ​​после первоначального получения ошибки, но не помогла.

Мои вопросы: (1) что вызывает первую ошибку? (2) есть ли способ оценить модели, используя такие данные, что количество строк по количеству столбцов превышает целочисленный предел? (3) есть ли лучшее na.action для использования в этом случае?

Спасибо,

JP.

Работает: R версия 3.3.3 (2017-03-06)

Фактический код ниже:

dft_var <- c("cltvV0", "cltvV60", "cltvV120", "VCFLBRQ", "ageV0", 
             "ageV1", "ageV8", "ageV80", "FICOV300", "FICOV650", 
             "FICOV900", "SingleHouse", "Apt", "Mobile", "Duplex", 
             "Row", "Modular", "Rural", "FirstTimeBuyer", 
             "FirstTimeBuyerMissing", "brwtotinMissing", "IncomeRatio", 
             "VintageBefore2001", "NFLD", "yoy.fcpwti:province_n") 
logit1 <- speedglm(formula = paste("DefaultFlag ~ ", 
                                   paste(dft_var, collapse = "+"), 
                                   sep = ""), 
                   family = binomial(logit), 
                   na.action = na.exclude, 
                   data = default.data,
                   chunksize = 1*10^7)

person James    schedule 06.06.2017    source источник


Ответы (2)


Обновление:

Основываясь на моем расследовании ниже, @James понял, что проблемы можно избежать, предоставив значение, отличное от NULL, для параметра sparse в вызове функции speedglm, поскольку это предотвращает внутренний вызов функции is.sparse.

Используя приведенный выше пример, теперь должно работать следующее:

speedglm(fo, data = da, family = Gamma(log), sparse = FALSE)

Мой первоначальный ответ:

И предупреждение, и ошибка происходят из одной и той же строки в функции is.sparse в пакете speedglm.

Строка:

sample(X,round((nrow(X)*ncol(X)*camp),digits=0),replace=FALSE)

Предупреждение возникает из-за использования nrow(X)*ncol(X) для большой матрицы. Функции nrow и ncol возвращают integer значений, которые могут переполняться. вот иллюстрация.

nr = 1000000L
nc = 1000000L
nr*nc
# [1] NA
# Warning message:
# In nr * nc : NAs produced by integer overflow

Ошибка возникает из-за того, что функция sample путается, когда X — большая матрица, а size = NA. Вот иллюстрация:

sample(matrix(1,3000,1000000), NA, replace=FALSE)
# Error in if (useHash) .Internal(sample2(n, size)) else .Internal(sample(n,  : 
# missing value where TRUE/FALSE needed
person Andrey Shabalin    schedule 06.06.2017
comment
Спасибо за ответ @Andrey. Кажется, я понимаю проблему, но не знаю, как ее решить. Вы хотите сказать, что если я обойду команду sample в speedglm, она должна работать? - person James; 06.06.2017
comment
Думаю, пора обратить на это внимание авторов пакета. Они должны попытаться избежать ограничений R и заставить его работать с большими данными, такими как ваши. - person Andrey Shabalin; 07.06.2017
comment
С другой стороны, исправить это может быть так же просто, как заменить nrow(X)*ncol(X) на length(X). Я не знаю, столкнетесь ли вы с какими-либо проблемами, как только это будет решено. - person Andrey Shabalin; 07.06.2017
comment
Я только что отправил электронное письмо сопровождающему пакета, указав ему на эту ветку. Я представил ответ ниже, который решает проблему. Не уверен, что это правильный этикет, поэтому, если хотите, я могу отредактировать ваш ответ с ответом и принять его. - person James; 07.06.2017
comment
Я обновил свой ответ, чтобы включить ваши выводы. Буду признателен, если вы примете это. Думаю, стоит сохранить и ваш ответ, так как он подтверждает ваш вклад в решение проблемы. - person Andrey Shabalin; 07.06.2017

Благодаря руководству @Andrey я смог решить проблему. Проблема заключалась в примере функции в проверке is.sparse. Чтобы обойти это, я установил sparse=FALSE в параметрах для speedglm (это должно работать и для sparse=TRUE, хотя я не пробовал). Это потому, что speedglm вызывает is.sparse через speedglm.wfit следующим образом:

if (is.null(sparse))
    sparse <- is.sparse(x = x, sparsellim, camp)

Таким образом, установка sparse позволяет избежать функции is.sparse.

Используя приведенный выше пример, теперь должно работать следующее:

speedglm(fo, data = da, family = Gamma(log), sparse = FALSE)
person James    schedule 07.06.2017