Почему PLM создает массивные объекты и не может их открыть

Я работаю над большой (но не огромной) базой данных, состоящей из 1,1 миллиона наблюдений и 41 переменной. Данные расположены в виде несбалансированной панели. Используя эти переменные, я определил три разные модели и запускаю каждую из них как 1) фиксированные эффекты, 2) случайные эффекты и 3) объединенную регрессию МНК.

Исходный файл .RData, содержащий только базу данных, весит около 15 Мб. .RData, содержащий базу данных и результаты регрессии (всего 9 регрессий), весит около 650 МБ. Я понимаю, что (из базовой документации)

An object of class c("plm","panelmodel").

A "plm" object has the following elements :

coefficients   the vector of coefficients,
vcov           the covariance matrix of the coefficients,
residuals      the vector of residuals,
df.residual    degrees of freedom of the residuals,
formula        an object of class ’pFormula’ describing the model,
model          a data.frame of class ’pdata.frame’ containing the variables usedfor the estimation: the response is in first position and the two indexes in the last positions,
ercomp         an object of class ’ercomp’ providing the estimation of the components of the
errors         (for random effects models only),
call           the call

даже в этом случае я не могу понять, почему эти файлы должны быть такими огромными. Чтобы не перегружать память при работе с объектами plm, я сохранил их в трех разных файлах (каждый из которых теперь весит около 200 Мб). Я позвонил summary час назад, чтобы посмотреть результаты модели с фиксированными эффектами, но мне пока не прислали никаких результатов. Теперь мой вопрос довольно прост. Вы считаете это нормальным поведением? Можно ли что-то сделать, чтобы уменьшить размер объектов plm и ускорить получение результатов?

Вот некоторые вещи, которые вы, возможно, захотите узнать:

  • База данных, которую я использую, имеет формат data.table.
  • formula в регрессиях предварительно собраны и включены в вызовы plm, которым предшествует as.formula(), как было предложено здесь. Пример:

form<-y~x1+x2+x3+...+xn

mod.fe<-plm(as.formula(form), regr, effect="individual", model="within", index=c("id", "year"))

Пожалуйста, дайте мне знать, если есть какая-либо другая информация, которую я могу предоставить, и что вам может понадобиться ответить на вопрос.

ИЗМЕНИТЬ

Мне удалось создать небольшую базу данных с характеристиками, аналогичными той, над которой я работаю. Вот:

structure(list(id = c(1L, 1L, 2L, 2L, 2L, 2L, 3L, 3L, 4L, 4L, 
5L, 5L, 6L, 6L, 7L, 7L, 7L, 7L, 8L, 8L, 8L, 8L, 9L, 9L, 9L, 9L, 
10L, 10L, 11L, 11L), year = structure(c(1L, 2L, 1L, 2L, 3L, 4L, 
1L, 2L, 1L, 2L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 
1L, 2L, 3L, 4L, 3L, 4L, 1L, 2L), .Label = c("2000", "2001", "2002", 
"2003"), class = "factor"), study = c(3.37354618925767, 4.18364332422208, 
5.32950777181536, 4.17953161588198, 5.48742905242849, 5.73832470512922, 
6.57578135165349, 5.69461161284364, 6.3787594194582, 4.7853001128225, 
7.98380973690105, 8.9438362106853, 9.07456498336519, 7.01064830413663, 
10.6198257478947, 9.943871260471, 9.84420449329467, 8.52924761610073, 
3.52184994489138, 4.4179415601997, 5.35867955152904, 3.897212272657, 
5.38767161155937, 4.9461949594171, 3.62294044317139, 4.58500543670032, 
7.10002537198388, 6.76317574845754, 6.83547640374641, 6.74663831986349
), ethnic = structure(c(1L, 1L, 2L, 2L, 2L, 2L, 3L, 3L, 1L, 1L, 
2L, 2L, 3L, 3L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 
1L, 1L, 2L, 2L), .Label = c("hispanic", "black", "chinese"), class = "factor"), 
    sport = c(0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
    1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0), health = structure(c(1L, 
    1L, 2L, 2L, 2L, 2L, 3L, 3L, 4L, 4L, 1L, 1L, 2L, 2L, 3L, 3L, 
    3L, 3L, 4L, 4L, 4L, 4L, 1L, 1L, 1L, 1L, 2L, 2L, 3L, 3L), .Label = c("none", 
    "drink", "both", "smoke"), class = "factor"), gradec = c(2.72806403942929, 
    3.10067738633308, 4.04728186632456, 2.19701362539883, 1.73115878111307, 
    5.35879931359977, 5.79613840739381, 5.07050219214859, 4.26224490644077, 
    3.53554192927934, 6.10515669475491, 7.18032957183198, 6.73191149590581, 
    6.49512764543435, 6.4783689354808, 6.19974636196512, 5.54014977312232, 
    6.72545652880344, 1.00223129492982, 1.08994269214495, 3.06702680106689, 
    1.70103126320561, 4.82973481729635, 3.14010240687364, 3.8068435242348, 
    5.01254268106181, 5.66497772013949, 4.16303452633342, 4.2751229553617, 
    3.05652055248093), event = c(1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 
    0), evm3 = c(0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0), evm2 = c(0, 
    0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 1, 0, 0, 1, 1, 0, 0, 0, 0), evm1 = c(0, 1, 0, 1, 1, 1, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 
    1, 0, 0, 0, 0), evp1 = c(0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1), 
    evp2 = c(0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1), evp3 = c(0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 1, 0), ndm3 = c(1, 1, 1, 1, 1, 0, 1, 
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 
    1, 1, 1, 1), ndm2 = c(1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 
    1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1), ndm1 = c(1, 
    0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 
    0, 0, 1, 0, 0, 0, 1, 0, 1, 0), ndp1 = c(0, 1, 0, 0, 0, 1, 
    0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 
    1, 0, 1, 0, 0), ndp2 = c(1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 
    1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0), 
    ndp3 = c(1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 
    1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1)), .Names = c("id", 
"year", "study", "ethnic", "sport", "health", "gradec", "event", 
"evm3", "evm2", "evm1", "evp1", "evp2", "evp3", "ndm3", "ndm2", 
"ndm1", "ndp1", "ndp2", "ndp3"), class = "data.frame", row.names = c(NA, 
30L))

Формула и вызов plm, которые я использовал:

form<-gradec~year+study+ethnic+sport+health+event+evm3+evm2+evm1+evp1+evp2+evp3+ndm3+ndm2+ndm1+ndp1+ndp2+ndp3

plm.f<-plm(as.formula(form), data, effect="individual", model="within", index=c("id", "year"))

Используя object.size(), предложенный @BenBolker, я обнаружил, что вызов сгенерировал объект plm весом 64,5 КБ, в то время как исходный фрейм данных имеет размер 6,9 КБ, что означает, что результаты примерно в 10 раз больше, чем входная матрица. Затем я установил параметры, предложенные @zx8754 ниже, но, к сожалению, они не дали никакого эффекта. Когда я наконец позвонил summary(plm.f), я получил сообщение об ошибке:

Error in crossprod(t(X), beta) : non-conformable arguments

который я в конечном итоге получил также с моей большой базой данных, но только после нескольких часов вычислений. Здесь предполагается, что проблема может быть связана с матрица коэффициентов сингулярна. Однако при тестировании на сингулярность с is.matrix.singular() в пакете matrixcalc оказалось, что это не так.

Еще пара вещей, которые вы, возможно, захотите знать:

  • year, ethnic и health — факторы
  • Переменные в формуле более или менее понятны, за исключением последних. event - предполагаемое травматическое событие, произошедшее в определенное время. Он кодируется 1 в случае события в определенном году и 0 в противном случае. Переменная evm1 равна 1, если одно из этих событий произошло в предыдущем году (минус 1), и 0 в противном случае. Точно так же evp1 равно 1, если событие произойдет в следующем году (плюс 1), и 0 в противном случае. Переменные ndm. и ndp. работают таким же образом, но они кодируются 1, когда это расстояние не наблюдается (поскольку период времени для определенного человека слишком короток) и 0 в противном случае. Наличие столь глубоко связанных переменных вызывает подозрение в совершенной коллинеарности. Однако, как было сказано выше, проверка показала, что матрица несингулярна.

Позвольте мне еще раз сказать, что я был бы очень благодарен, если бы кто-то мог ответить на вопрос.


person Riccardo    schedule 09.01.2014    source источник
comment
Поскольку plm, glm, lm и т. д. хранят данные, которые используются для расчета, в результирующем объекте. Это может иметь значение: stackoverflow.com/questions/13387603/   -  person zx8754    schedule 09.01.2014
comment
Стоит также отметить, что файл RData находится на диске в сжатом формате, поэтому после загрузки он будет больше. Что такое print(object.size(...),units="Mb") применительно к вашей необработанной базе данных?   -  person Ben Bolker    schedule 09.01.2014
comment
Спасибо вам обоим. @BenBolker Я попробовал предложенный вами тест, и оказалось, что база данных составляет 309,7 МБ, а объект plm - 1062,0 МБ. Разве это не странно? @ zx8754 zx8754 спасибо, что показали это. Я попробую с x=FALSE и y=FALSE. Я думаю, что не могу использовать model=FALSE, потому что model — это опция plm, которая позволяет мне выбрать тип преобразования, который я хочу применить. Я сделаю тест, чтобы вы знали, как это происходит.   -  person Riccardo    schedule 09.01.2014
comment
На самом деле это не ответ, поэтому я публикую его как комментарий. У меня похожие проблемы — plmtwoways) и lm (с манекенами) требуется более 50 ГБ (32 ГБ ОЗУ + 20 ГБ подкачки) памяти для набора данных из 200 тыс. строк и 4 переменных + индивидуальные и временные эффекты, 11 МБ памяти. . В итоге я просто использовал gretl, который оценивает модель менее чем за секунду и использует менее 100 МБ ОЗУ. . Stata также легко оценивает модель (результаты Gretl и Stata выглядят одинаково), но для этого вам нужна не совсем дешевая лицензия.   -  person Peter    schedule 16.01.2014


Ответы (1)


О сообщении об ошибке Error in crossprod(t(X), beta) : non-conformable arguments:

Вероятно, это связано с сингулярностью в матрице модели, как и предполагалось. Пожалуйста, имейте в виду, что модельная матрица для моделей с фиксированными эффектами представляет собой преобразованные данные (преобразованный фрейм данных).

Таким образом, вам нужно будет проверить сингулярность преобразованных данных. Преобразование с фиксированными эффектами может привести к линейной зависимости (сингулярности), даже если исходные данные не являются линейно зависимыми! В пакете plm есть неплохая документация по этой проблеме в ?detect_lin_dep, которую я частично повторю здесь (только один пример):

### Example 1 ###
# prepare the data
data(Cigar)
Cigar[ , "fact1"] <- c(0,1)
Cigar[ , "fact2"] <- c(1,0)
Cigar.p <- pdata.frame(Cigar)

# setup a pFormula and a model frame
pform <- pFormula(price ~ 0 + cpi + fact1 + fact2)
mf <- model.frame(pform, data = Cigar.p)

# no linear dependence in the pooling model's model matrix
# (with intercept in the formula, there would be linear depedence)
detect_lin_dep(model.matrix(pform, data = mf, model = "pooling"))

# linear dependence present in the FE transformed model matrix
modmat_FE <- model.matrix(pform, data = mf, model = "within")
detect_lin_dep(modmat_FE)
mod_FE <- plm(pform, data = Cigar.p, model = "within")
detect_lin_dep(mod_FE) 
alias(mod_FE) # => fact1 == -1*fact2
plm(pform, data = mf, model = "within")$aliased # "fact2" indicated as aliased

Таким образом, вы должны запустить свою функцию для обнаружения линейной зависимости от преобразованных данных модели, которую вы получаете model.matrix(you_model). Вы можете использовать функции, предоставляемые plm: detect_lin_dep, alias или любую функцию, которая работает с матрицей.

Вы также можете посмотреть на свой объект модели plm: your_model$aliased, чтобы увидеть, не были ли отброшены некоторые переменные при оценке.

person Helix123    schedule 23.11.2016