Como posso salvar arquivos em paralelo sem aumentar automaticamente o tamanho do arquivo?

9

Eu tenho 2 scripts que fazem exatamente o mesmo.

Mas um script está produzindo 3 arquivos RData com peso de 82,7 KB e o outro script criando 3 arquivos RData com peso de 120 KB.

o primeiro é sem paralelo:

library("plyr")
ddply(.data = iris,
      .variables = "Species",
      ##.parallel=TRUE,##Without parallel
      .fun = function(SpeciesData){

      #Create Simple Model -------------------------------------------------------------  
      Model <- lm(formula = "Sepal.Length~Sepal.Width+Petal.Length+Petal.Width",data = SpeciesData)

      #Save The Model -------------------------------------------------------------               
       save(Model,
            compress = FALSE,
            file = gsub(x =  "Species.RData",
                        pattern = "Species",
                        replacement = unique(SpeciesData$Species)))

 })

O segundo é com paralelo:

library("plyr")
doSNOW::registerDoSNOW(cl<-snow::makeCluster(3))
ddply(.data = iris,
      .variables = "Species",
      .parallel=TRUE,##With parallel
      .fun = function(SpeciesData){

      #Create Simple Model -------------------------------------------------------------  
      Model <- lm(formula = "Sepal.Length~Sepal.Width+Petal.Length+Petal.Width",data = SpeciesData)

      #Save The Model -------------------------------------------------------------               
       save(Model,
            compress = FALSE,
            file = gsub(x =  "Species.RData",
                        pattern = "Species",
                        replacement = unique(SpeciesData$Species)))

 })
snow::stopCluster(cl)

o segundo script cria arquivos que pesam 42% mais.

Como posso salvar arquivos em paralelo sem aumentar automaticamente o tamanho do arquivo?

Dima Ha
fonte
Você está olhando para reduzir o tamanho geral dos arquivos dos modelos ou é uma curiosidade mais técnica sobre o motivo dos arquivos serem maiores? Qual é o objetivo maior que você está procurando?
Roger-123
Você precisa bloquear o acesso ao arquivo enquanto ele está gravando pelo thread. Outra maneira? arquivo será quebrado.
Profesor08
@ Profesor08 Como bloquear o acesso ao arquivo enquanto ele está gravando?
Dima Ha
@ Roger-123 Tento reduzir o tamanho da memória dos arquivos salvos.
Dima Ha
O @DimaHa pode tentar algo do Google r lang lock filee, após 5 segundos, você encontrará o pacote desejado cran.r-project.org/web/packages/filelock/filelock.pdf
Profesor08

Respostas:

2

Como outros mencionados, pode haver uma pequena quantidade de informações sobre o ambiente que está sendo salva nos arquivos ou similar que você provavelmente não notaria, exceto que os arquivos são muito pequenos.

Se você está interessado apenas no tamanho do arquivo, tente salvar os modelos em uma única lista e salve-os em um arquivo. ddplysó pode manipular um data.frame como resultado da função, portanto, temos que usá dlply-lo para que ele armazene os resultados em uma lista. Isso foi salvo em apenas um arquivo com 60k.

Aqui está um exemplo do que estou falando:

library("plyr")
doSNOW::registerDoSNOW(cl<-snow::makeCluster(3))
models<-dlply(.data = iris,
      .variables = "Species",
      .parallel=TRUE,##With parallel
      .fun = function(SpeciesData){

        #Create Simple Model -------------------------------------------------------------  
        lm(formula = Sepal.Length~Sepal.Width+Petal.Length+Petal.Width, data = SpeciesData)
      })
snow::stopCluster(cl)

save(models, compress= FALSE, file= 'combined_models')
Roger-123
fonte
3

Eu não usei o ddply para paralelizar objetos salvos, portanto, acho que o arquivo fica muito maior porque, quando você salva o objeto de modelo, ele também carrega algumas informações sobre o ambiente em que é salvo.

Então, usando o código ddply acima, os tamanhos que tenho são:

sapply(dir(pattern="RData"),file.size)
setosa.RData versicolor.RData  virginica.RData 
       36002            36002            36002 

Existem duas opções, uma é usar o purrr / furrr:

library(furrr)
library(purrr)

func = function(SpeciesData){
  Model <- lm(formula = "Sepal.Length~Sepal.Width+Petal.Length+Petal.Width",data = SpeciesData)
  save(Model,
       compress = FALSE,
       file = gsub(x =  "Species.RData",
                   pattern = "Species",
                   replacement = unique(SpeciesData$Species)))
}

split(iris,iris$Species) %>% future_map(func)

sapply(dir(pattern="RData"),file.size)
    setosa.RData versicolor.RData  virginica.RData 
           25426            27156            27156

Ou use saveRDS (e ddply?), Pois você só tem um objeto para salvar:

ddply(.data = iris,
      .variables = "Species",
      .parallel=TRUE,##With parallel
      .fun = function(SpeciesData){
        Model <- lm(formula = "Sepal.Length~Sepal.Width+Petal.Length+Petal.Width",data = SpeciesData)
        saveRDS(Model,
             gsub(x =  "Species.rds",
                         pattern = "Species",
                         replacement = unique(SpeciesData$Species)))

      })

sapply(dir(pattern="rds"),file.size)
    setosa.rds versicolor.rds  virginica.rds 
          6389           6300           6277 

Você fará em readRDSvez de loadobter o arquivo:

m1 = readRDS("setosa.rds")
m1
Call:
lm(formula = "Sepal.Length~Sepal.Width+Petal.Length+Petal.Width", 
    data = SpeciesData)

Coefficients:
 (Intercept)   Sepal.Width  Petal.Length   Petal.Width  
      2.3519        0.6548        0.2376        0.2521  

Podemos observar os coeficientes em comparação com o objeto rda:

m2 = get(load("setosa.RData"))
m2

Call:
lm(formula = "Sepal.Length~Sepal.Width+Petal.Length+Petal.Width", 
    data = SpeciesData)

Coefficients:
 (Intercept)   Sepal.Width  Petal.Length   Petal.Width  
      2.3519        0.6548        0.2376        0.2521  

Os objetos não são idênticos por causa das partes do ambiente, mas em termos de previsão ou outras coisas para as quais normalmente o usamos, ele funciona:

identical(predict(m1,data.frame(iris[1:10,])),predict(m2,data.frame(iris[1:10,])))
StupidWolf
fonte