1

私は最近、遺伝的プログラミングに使用する言語として R の実験を始めました。R の仕組みとそのコーディングのベスト プラクティスについて、ゆっくりと、しかし確実に学んでいます。それでも、私は障害物にぶつかりました。これが私の状況です。約 700 行のデータセットがあり、各行には 400 ほどの列があります。列の数と同じ数のパラメーターを持つ関数がパラメーターとして評価 (フィットネス スコアリング) 関数に送信されるように、すべての設定を行いました。データセットの行ごとに移動し、行の各列の値を評価される関数に渡したいと思います。最初の問題は、パラメーターを個別に関数に渡す方法を考え出すことでした。「別々に」とは、関数が長さ 400 のベクトルではなく、400 個のパラメーターを想定していることを意味します。これを行うには、次を使用しました。

do.call(function,as.list(parameters))

parameters は、データセット内の行の値に追加される月変数 (1 ~ 12) のベクトルです。これは問題なく動作します。for ループを使用してデータセット内の 700 行を反復し、次に 12 か月間別のループを使用し、上記を使用して出力のベクトルを蓄積しました。問題は、これが非常に遅く、関数ごとに約 24 ~ 28 秒かかることです。そして、進化の世代ごとに 100 ~ 500 個の関数をこの評価に送りました。肝心なのは、これは行くべき道ではないということです。次に、以下のように sapply メソッドを使用しようとしました。

outputs <- sapply(1:12,function(m) sapply(rows[1:length(rows)],function(p) do.call(f,as.list(c(p,m)))))

これは (1-12) を月として適用し、次に (1-700) をデータセットの行として適用しました。これには同じくらい時間がかかりました。解決策に関するアイデアは役に立ちます。

4

1 に答える 1

6

このような場合の主な問題は、通常、取っているアプローチが間違っていることです。私はあなたの特定のケースについて十分に知りませんが、

  1. 計算をベクトル化してみてください。そのため、関数は一度に 1 行だけではなく、すべての行を操作する必要があります。
  2. 数値を data.frame に格納するだけの場合、それを行列に変換すると、通常、多くの操作が高速化されます。
  3. 400 個のパラメーターを受け取る関数を作成しないでください。5もおそらく高い側にあります。

編集関数を生成するので、代わりに多くのパラメーターの代わりに値のベクトルを取る別のバージョンを生成できるはずです。渡すベクトルには名前を付けることができることに注意してください。

# Convert this:
f <- function(foo, bar) {
  foo+bar
}
do.call(f, list(foo=42, bar=13))

# To this:
f <- function(args) {
  args[["foo"]] + args[["bar"]] 
  # or even faster:
  #args[[0]] + args[[1]]
  # or fastest:
  #sum(args)
}
do.call(f, list(args=c(foo=42, bar=13)))
# or, simply
f(c(foo=42, bar=13))

... 400 ではなく 1 つのパラメーターで関数を呼び出すと、約60 倍速くなります。ただし、これは関数呼び出しのオーバーヘッドにすぎないことに注意してください。実際の関数にかかる時間も測定する必要があります。それが1秒以上かかる場合は、どれだけ効率的に呼び出すか、ループをどれだけ効率的にするかは問題ではありません...

于 2012-05-07T06:47:06.140 に答える