簡體   English   中英

是否有 R 循環函數 (data.table) 可以在不超過內存限制的情況下運行 100 多個 `gam` 結果?

[英]Is there a R loop function (data.table) to run over 100s of `gam` results without exceeding the memory limit?

使用gam空間插值

陳述

我希望使用廣義加性模型 (GAM) 獲得許多空間插值輸出。 預測單個污染地圖沒有問題,但是,我需要100多張地圖。 如果可能的話,我想自動化實現並在不超過內存限制的情況下獲得結果。


使用 GAM 的空間插值過程( mgcv包)

只是為了讓您知道,這里是獲取插值地圖的基本步驟。

  • 獲取污染監測站的X、Y坐標
  • 獲取每個站點的污染數據
  • 將污染數據添加到包含 X、Y 坐標的數據框中
  • 為每個污染列運行gam(pollution ~ s(X,Y, k=20))
  • 創建一個空數據框, minmax X、Y 坐標作為空間范圍
  • 使用predictgam結果預測空間范圍
  • 在所有污染領域運行相同的工作


我將展示一個關於我如何接近它的實踐示例。


樣本數據

舉個例子,我創建了一個如下所示的數據集。 df ,您會意識到我有X Y和 3 個污染變量。

library(data.table)
library(mgcv)

X <- c(197745.8,200443.8,200427.6,208213.4,203691.1,208303.0,202546.4,202407.9,202564.8,194095.5,194508.0,195183.8,185432.5,
       190249.0,190927.0,197490.1,193551.5,204204.4,199508.4,210201.4,212088.3,191886.5,201045.2,187321.7,205987.0)
Y <- c(451633.1,452496.8,448949.5,449753.3,449282.2,453928.5,452923.2,456347.9,461614.8,456729.3,453019.7,450039.7,449472.0,
       444348.1,447274.4,442390.0,443101.2,446446.5,445008.5,446765.2,449508.5,439225.3,460915.6,447392.0,461985.3)
poll1 <- c(34,29,29,33,33,38,35,30,41,43,35,34,41,41,40,36,35,27,53,40,37,32,28,36,33)
poll2 <- c(27,27,34,30,38,36,36,35,37,39,35,33,41,42,40,34,38,31,43,46,38,32,29,33,34)
poll3 <- c(26,30,27,30,37,41,36,36,35,35,35,33,41,36,38,35,34,24,40,43,36,33,30,32,36)

df <- data.table(X, Y, poll1, poll2, poll3)


我是如何工作的

1. 硬編碼

如果您查看下面的代碼,您會意識到我將相同的作業復制並粘貼到所有變量中。 這將很難實現很多變量。

# Run gam
gam1 <- gam(poll1 ~ s(X,Y, k=20), data = df)
gam2 <- gam(poll2 ~ s(X,Y, k=20), data = df)
gam3 <- gam(poll3 ~ s(X,Y, k=20), data = df)
         # "there are over 5000 variables that needs looping


# Create an empty surface for prediction
GAM_poll <- data.frame(expand.grid(X = seq(min(df$X), max(df$X), length=200),
                                   Y = seq(min(df$Y), max(df$Y), length=200)))


# Predict gam results to the empty surface
GAM_poll$gam1 <- predict(gam1, GAM_poll, type = "response")
GAM_poll$gam2 <- predict(gam2, GAM_poll, type = "response")
GAM_poll$gam3 <- predict(gam3, GAM_poll, type = "response")


2. 使用for循環

相反,我列了一個列表並嘗試循環所有變量以獲得結果。 本身當然沒有問題,但是迭代多個變量會占用所有內存(這是我所經歷的)。

# Run gam using list and for loop
myList <- list()

for(i in 3:length(df)){
  myList[[i-2]] <- gam(df[[i]] ~ s(X,Y, k=20), data = df)
}


# Create an empty surface for prediction
GAM_poll <- data.frame(expand.grid(X = seq(min(df$X), max(df$X), length=200),
                                   Y = seq(min(df$Y), max(df$Y), length=200)))


# Predict gam results to the empty surface
myResult <- list()

for(j in 1:length(myList)){
myResult[[j]] <- predict(myList[[j]], GAM_poll, type = "response")
}

尋求幫助

  • 有沒有更好的方法來獲得多個變量的gam結果?
  • 有沒有辦法在實現過程中不超過內存限制?

你能幫我data.tablepurrr用戶嗎?

我創建的解決方案只將最新的預測保留在內存中,並將其他預測保存到磁盤,然后再用下一個解決方案覆蓋它。 這些文件以名為 results 的文件夾中模型的列名命名。 我也融化了 data.table,主要是因為我認為這樣代碼更清晰一些。

library(data.table)
library(mgcv)

X <- c(197745.8,200443.8,200427.6,208213.4,203691.1,208303.0,202546.4,202407.9,202564.8,194095.5,194508.0,195183.8,185432.5,
       190249.0,190927.0,197490.1,193551.5,204204.4,199508.4,210201.4,212088.3,191886.5,201045.2,187321.7,205987.0)
Y <- c(451633.1,452496.8,448949.5,449753.3,449282.2,453928.5,452923.2,456347.9,461614.8,456729.3,453019.7,450039.7,449472.0,
       444348.1,447274.4,442390.0,443101.2,446446.5,445008.5,446765.2,449508.5,439225.3,460915.6,447392.0,461985.3)
poll1 <- c(34,29,29,33,33,38,35,30,41,43,35,34,41,41,40,36,35,27,53,40,37,32,28,36,33)
poll2 <- c(27,27,34,30,38,36,36,35,37,39,35,33,41,42,40,34,38,31,43,46,38,32,29,33,34)
poll3 <- c(26,30,27,30,37,41,36,36,35,35,35,33,41,36,38,35,34,24,40,43,36,33,30,32,36)

df <- data.table(X, Y, poll1, poll2, poll3)


# melt the data.table
df <- melt.data.table(df, id.vars = c('X', 'Y'))

dir.create('results')
gam1 <- list()
for(i in unique(df$variable)){

  gam1[[i]] <- gam(value ~ s(X,Y, k=20), data = df[variable == i])

  GAM_poll <- data.table(expand.grid(X = seq(min(df$X), max(df$X), length=200),
                                     Y = seq(min(df$Y), max(df$Y), length=200)))


  GAM_poll[, 'prediction' := predict(gam1[[i]], GAM_poll, type = "response")]

  write.csv(GAM_poll$prediction, paste('results/model_', i, '.csv'), row.names = FALSE)

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM