Экономия места при сохранении встроенного игрового объекта (mgcv :: gam and scam :: scam) - PullRequest
0 голосов
/ 10 января 2019

Я оцениваю очень простую модель для большого набора данных. Формула выглядит как

 scam::scam(formula = ratio ~ s(rate,bs="mpi"))

Эти модели затем используются для генерации прогнозов для новых данных. Меня не волнует больше ничего о модели.

Моя проблема в том, что возвращаемый объект огромен (несколько ГБ), что приводит к проблемам в нисходящем направлении.

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

Есть ли способ сохранить только небольшой объект, содержащий минимум, необходимый для прогнозирования на новых данных? Это не должно быть больше, чем несколько килобайт.

Огромное спасибо!

edit1 : вот воспроизводимый пример, показывающий мое понимание ответа Гэвина:

library(mgcv)
data(iris)
library(tidyverse)
mydb <- iris %>% filter(Species == "setosa")

dim(mydb) # 50 records
model <-  mgcv::gam(formula = Sepal.Length ~ s(Sepal.Width,bs="cs"), 
                     data  = mydb)

print(object.size(model), units = "KB") # 78 KB

distinct_mydb <- mydb %>% distinct(Sepal.Width) # 16 distinct values for the independent variables
Xp <- predict(model, newdata= distinct_mydb, type = "lpmatrix")
coefs <- coef(model)
dim(Xp) # 16 records and 10 columns (one for each of the 10 knots of the spline?)
preds1 <- Xp %*% coefs %>% t()  
preds2 <- predict(model, newdata= distinct_mydb)  # preds 1 and preds2 are identical

print(object.size(Xp), units = "KB")   # 3.4 Kb
print(object.size(coefs), units = "KB") # 1.1 Kb

В этом решении я бы сохранил «Xp» (3,4 КБ) и «coefs» (1,1 КБ) в сумме 4,5 КБ вместо сохранения «модели», которая занимает 78 КБ

Что я не уверен, так это то, как я могу использовать Xp и coefs на следующей неделе, чтобы предсказать Sepal. Длина цветка с невиданным ранее Sepal. Ширина 2,5?

edit2 : Является ли ответом просто сгенерировать сетку из всех возможных Sepal.Width (с округлением до некоторого десятичного знака) и просто left_join в эту таблицу с любыми будущими данными?

fake_db <- data.frame(Sepal.Width = seq(0,max(mydb$Sepal.Width), by = 0.1))
fake_db$predicted_Sepal.Length = predict(model, newdata =  fake_db)
print(object.size(fake_db), units = "KB") # 4.3 Kb

1 Ответ

0 голосов
/ 10 января 2019

Посмотрите на ?mgav:::predict.gam и информацию для аргумента type и, в частности, "lpmatrix".

Например, вам нужен только вектор коэффициентов и вывод из

predict(model, newdata, type = "lpmatrix")`

, где newdata - это гораздо меньшее подмножество ваших исходных данных, но охватывающее диапазоны ковариат.

Эта опция "lpmatrix" предназначена для использования ниже или ниже R. Общая идея заключается в том, что если "lpmatrix" как Xp, то Xp %*% coef(model) дает соответствующие значения. Но так как вы можете уменьшить размер Xp с помощью newdata, вы можете уменьшить размерность объекта, необходимого для предсказания.

...