파일 크기를 자동으로 늘리지 않고 파일을 병렬로 저장하려면 어떻게해야합니까?


9

정확히 똑같은 두 개의 스크립트가 있습니다.

그러나 한 스크립트는 82.7KB의 3 개의 RData 파일을 생성하고 다른 스크립트는 120KB의 3 개의 RData 파일을 생성합니다.

첫 번째는 병렬이 아닙니다.

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

 })

두 번째는 병렬입니다.

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)

두 번째 스크립트는 무게가 42 % 더 많은 파일을 만듭니다.

파일 크기를 자동으로 늘리지 않고 파일을 병렬로 저장하려면 어떻게해야합니까?


모델의 전체 파일 크기를 줄이려고합니까? 아니면 파일이 더 큰 이유에 대한 기술적 호기심이 있습니까? 찾고있는 더 큰 목표는 무엇입니까?
Roger-123

스레드가 파일을 쓰는 동안 파일에 대한 액세스를 차단해야합니다. 또 다른 방법? 파일이 손상됩니다.
Profesor08

@ Profesor08 파일을 쓰는 동안 파일에 대한 액세스를 차단하는 방법은 무엇입니까?
Dima Ha

@ Roger-123 저장된 파일의 메모리 크기를 줄이려고합니다.
Dima Ha

@DimaHa처럼 뭔가를 구글을 시도 할 수있다 r lang lock file5 초 후 원하는 패키지 찾을 수 cran.r-project.org/web/packages/filelock/filelock.pdf
Profesor08

답변:


2

다른 사람들이 언급했듯이 파일에 저장되는 환경에 대한 소량의 정보가 있거나 파일이 너무 작다는 것을 제외하고는 아마 알지 못할 것입니다.

파일 크기에 관심이있는 경우 모델을 단일 목록으로 저장 한 다음 하나의 파일로 저장하십시오. ddply함수의 결과로 data.frame 만 처리 할 수 ​​있으므로 dlply대신 결과를 목록에 저장하도록 지시해야합니다. 이를 수행하면 60k 인 하나의 파일에만 저장됩니다.

다음은 내가 말하는 것에 대한 예입니다.

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

3

ddply를 사용하여 객체 저장을 병렬화하지 않았으므로 모델 객체를 저장할 때 파일이 저장되는 환경에 대한 정보도 가지고 있기 때문에 파일이 훨씬 커지는 것 같습니다.

따라서 위의 ddply 코드를 사용하면 크기가 다음과 같습니다.

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

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

또는 저장할 오브젝트가 하나뿐이므로 saveRDS (및 ddply?)를 사용하십시오.

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 

파일을 얻는 readRDS대신에 다음 load을 수행 하십시오.

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  

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  

환경 부분으로 인해 객체가 동일하지 않지만 예측 또는 일반적으로 사용하는 다른 측면에서 작동합니다.

identical(predict(m1,data.frame(iris[1:10,])),predict(m2,data.frame(iris[1:10,])))
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.