rgdalパッケージを使用してRの画像分類スクリプトに取り組んでいます。問題のラスターは、トレーニングデータチャネル、検証データチャネル、および26のスペクトルデータチャネルの28のチャネルを持つPCIDSKファイルです。目的は、トレーニングデータチャネルでゼロではない各ピクセルの値と、26バンドの関連するスペクトル値を含むデータフレームにデータを入力することです。
Python / Numpyでは、画像全体のすべてのバンドを多次元配列に簡単にインポートできますが、メモリの制限により、Rの唯一のオプションは、このデータをブロックごとにインポートすることであるようです。これは非常に低速です。
library(rgdal)
raster = "image.pix"
training_band = 2
validation_band = 1
BlockWidth = 500
BlockHeight = 500
# Get some metadata about the whole raster
myinfo = GDALinfo(raster)
ysize = myinfo[[1]]
xsize = myinfo[[2]]
numbands = myinfo[[3]]
# Iterate through the image in blocks and retrieve the training data
column = 0
training_data = NULL
while(column < xsize){
if(column + BlockWidth > xsize){
BlockWidth = xsize - column
}
row = 0
while(row < ysize){
if(row + BlockHeight > ysize){
BlockHeight = ysize - row
}
# Do stuff here
myblock = readGDAL(raster, region.dim = c(BlockHeight,BlockWidth), offset = c(row, column), band = c(training_band,3:numbands), silent = TRUE)
blockdata = matrix(NA, dim(myblock)[1], dim(myblock)[2])
for(i in 1:(dim(myblock)[2])){
bandname = paste("myblock", names(myblock)[i], sep="$")
blockdata[,i]= as.matrix(eval(parse(text=bandname)))
}
blockdata = as.data.frame(blockdata)
blockdata = subset(blockdata, blockdata[,1] > 0)
if (dim(blockdata)[1] > 0){
training_data = rbind(training_data, blockdata)
}
row = row + BlockHeight
}
column = column + BlockWidth
}
remove(blockdata, myblock, BlockHeight, BlockWidth, row, column)
メモリを使い果たすことなく同じことを行うためのより速く/より良い方法はありますか?
このトレーニングデータが収集された後の次のステップは、要求されたツリーの数に応じて、大量のメモリを必要とする分類子(randomForestパッケージ)を作成することです。これは私の2番目の問題につながります。それは、トレーニングデータによってすでに占有されているメモリの量を考えると、500本の木のフォレストを作成することができないということです。
myformula = formula(paste("as.factor(V1) ~ V3:V", dim(training_data)[2], sep=""))
r_tree = randomForest(formula = myformula, data = training_data, ntree = 500, keep.forest=TRUE)
より多くのメモリを割り当てる方法はありますか?私は何かが足りないのですか?ありがとう...
[編集]Janが提案したように、「ラスター」パッケージの使用ははるかに高速です。ただし、私が知る限り、トレーニングデータの収集に関する限り、メモリの問題は解決されません。これは、最終的にはデータフレーム内のメモリ内にある必要があるためです。
library(raster)
library(randomForest)
# Set some user variables
fn = "image.pix"
training_band = 2
validation_band = 1
# Get the training data
myraster = stack(fn)
training_class = subset(myraster, training_band)
training_class[training_class == 0] = NA
training_class = Which(training_class != 0, cells=TRUE)
training_data = extract(myraster, training_class)
training_data = as.data.frame(training_data)
したがって、これははるかに高速です(そして必要なコードは少なくなります)が、分類子を作成するのに十分な空きメモリがないという問題は解決されません...これを達成できる「ラスター」パッケージ関数は見つかりませんでしたか? ?ありがとう...