Bagaimana saya bisa menyimpan file secara paralel tanpa secara otomatis meningkatkan ukuran file?

9

Saya memiliki 2 skrip yang melakukan hal yang persis sama.

Tetapi satu skrip menghasilkan 3 file RData yang berbobot 82,7 KB, dan skrip lainnya membuat 3 file RData yang berbobot 120 KB.

yang pertama tanpa paralel:

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)))

 })

Yang kedua adalah dengan paralel:

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)

skrip kedua membuat file yang beratnya 42% lebih banyak.

Bagaimana saya bisa menyimpan file secara paralel tanpa secara otomatis meningkatkan ukuran file?

Dima Ha
sumber
Apakah Anda ingin mengurangi ukuran file keseluruhan model atau apakah ini rasa ingin tahu yang lebih teknis tentang mengapa file lebih besar? Apa tujuan yang lebih besar yang Anda cari?
Roger-123
Anda harus memblokir akses ke file, ketika sedang ditulis oleh utas. Cara lain? file akan rusak.
Profesor08
@ Profesor08 Bagaimana saya memblokir akses ke file ketika sedang menulis?
Dima Ha
@ Roger-123 Saya mencoba mengurangi ukuran memori dari file yang disimpan.
Dima Ha
@DimaHa mungkin mencoba untuk google sesuatu seperti r lang lock filedan setelah 5 detik Anda akan menemukan paket yang diinginkan cran.r-project.org/web/packages/filelock/filelock.pdf
Profesor08

Jawaban:

2

Seperti yang disebutkan lainnya, mungkin ada sejumlah kecil informasi tentang lingkungan yang disimpan dalam file atau serupa yang Anda mungkin tidak akan melihat kecuali bahwa file tersebut sangat kecil.

Jika Anda hanya tertarik pada ukuran file, cobalah menyimpan model ke dalam satu daftar dan kemudian simpan ke dalam satu file. ddplyhanya dapat menangani data.frame sebagai hasil dari fungsi, jadi kita harus menggunakannya dlplysebagai gantinya untuk menyimpan hasil dalam daftar. Melakukan ini disimpan hanya ke satu file yang 60k.

Berikut ini contoh dari apa yang saya bicarakan:

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
sumber
3

Saya belum pernah menggunakan ddply untuk memparalelkan objek penyimpanan, jadi saya kira file menjadi jauh lebih besar karena ketika Anda menyimpan objek model, ia juga membawa beberapa informasi tentang lingkungan tempat penyimpanannya.

Jadi menggunakan kode ddply Anda di atas, ukuran yang saya miliki adalah:

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

Ada dua opsi, satu adalah menggunakan 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

Atau menggunakan saveRDS (dan ddply?) Karena Anda hanya memiliki satu objek untuk disimpan:

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 

Anda akan melakukan readRDSalih - alih loadmendapatkan file:

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  

Kita dapat melihat koefisien dibandingkan dengan objek 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  

Objek tidak identik karena bagian lingkungan, tetapi dalam hal prediksi atau hal-hal lain yang biasa kita gunakan untuk itu, ia bekerja:

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