Я использую glmnet и glmnetcr, чтобы соответствовать моделям порядковой регрессии.
К сожалению, моя матрица модели составляет ~ 640000 * 5000. Это больше, чем можно сохранить в 32-битном целом числе, и я сталкиваюсь ста же проблема, которую описали другие: R ограничение размера вектора: «длинные векторы (аргумент 5) не поддерживаются в .C»
Если я использую только половину данных, я могу запуститьэто на моем локальном сервере с большим количеством памяти и без проблем.
Я попытался реализовать «решение» в вышеприведенном посте с помощью пакета dotCall64.Я заменил вызовы .Fortran на .C64 и указал тип данных для каждой переменной.Однако каждый раз, когда я запускаю свой код, я либо получаю бессмысленные лямбда-значения (9.9e35), либо сбои, такие как:
* перехвачено segfault * адрес 0x1511aaeb0, причина 'память не отображена'
Какой я получу и точный адрес меняется каждый раз, поэтому я предполагаю, что я что-то не так делаю при реализации этого решения.
Здесь приведен код функции lognet () (функция, которая в конечном итоге вызывается glmnetcr и glmnet и передает переменную в код fortran)
Исходный код в lognet ()
.Fortran("lognet", parm = alpha, nobs, nvars, nc, as.double(x),
y, offset, jd, vp, cl, ne, nx, nlam, flmin, ulam, thresh,
isd, intr, maxit, kopt, lmu = integer(1), a0 = double(nlam *
nc), ca = double(nx * nlam * nc), ia = integer(nx),
nin = integer(nlam), nulldev = double(1), dev = double(nlam),
alm = double(nlam), nlp = integer(1), jerr = integer(1),
PACKAGE = "glmnet")
Модифицированный код в lognet ()
.C64("lognet", SIGNATURE = c("double","int", "int", "int", "int64",
"double","double","int", "double","double"
"int", "int", "int", "double","double",
"double","int", "int", "int", "int",
"int", "double","double","int", "int",
"double","double","double","int", "int"),
parm = alpha, nobs, nvars, nc, as.double(x),
y, offset, jd, vp, cl, ne, nx, nlam, flmin, ulam, thresh,
isd, intr, maxit, kopt, lmu = integer(1), a0 = double(nlam * nc), ca = double(nx * nlam * nc), ia = integer(nx),
nin = integer(nlam), nulldev = double(1), dev = double(nlam),
alm = double(nlam), nlp = integer(1), jerr = integer(1),
PACKAGE = "glmnet")
Пример игрушки (данные намного меньше, чем фактические)
library(glmnetcr)
library(dotCall64)
x1 <- cbind(c(0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1),c(0,0,0,1,0,1,1,1,0,0,0,0,0,1,1,1),c(0,0,1,0,1,0,1,1,0,0,0,0,1,0,1,1),c(0,1,0,0,1,1,0,1,0,0,0,0,1,1,0,1),c(0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1),c(0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1),c(0,0,0,0,1,0,0,1,0,0,0,0,1,0,0,1))
y1 <- c(0,0,0,1,1,1,2,2,0,1,0,1,1,2,1,2)
testA <- glmnetcr(x=x1,y=y1,method = "forward", nlambda=10,lambda.min.ratio=0.001, alpha =1,maxit = 500,standardize=FALSE)
Запуск с использованием исходного кода lognet () приводит кНет проблем.Запуск его с измененным кодом lognet () приводит к нечетным оценкам лямбда-значений и / или ошибкам сегмента (кажется случайным, что происходит).Мое первое предположение состоит в том, что у меня неправильно введена одна из переменных, но я все дважды просмотрел и не вижу проблемы.Другой вариант заключается в том, что базовый код Fortran не может обрабатывать 64-битные целые числа.Я знаю ноль фортранов и даже не знаю, как начать решать проблему, если это так.