20

幅広いデータセットで glmnet lasso を実行すると問題が発生します。私のデータは N=50 ですが、p > 49000 で、すべての因子です。したがって、glmnet を実行するには、model.matrix を作成する必要がありますが、model.matrix(formula, data) を呼び出すと、メモリが不足します。ここで、formula = Class ~ です。

実際の例として、データセットを生成します:

data <- matrix(rep(0,50*49000), nrow=50)
for(i in 1:50) {
x = rep(letters[2:8], 7000)
y = sample(x=1:49000, size=49000)
data[i,] <- x[y]
}

data <- as.data.frame(data)
x = c(rep('A', 20), rep('B', 15), rep('C', 15))
y = sample(x=1:50, size=50)
class = x[y]
data <- cbind(data, class)

その後、glmnet に入力する model.matrix を作成しようとしました。

  formula <- as.formula(class ~ .)
  X = model.matrix(formula, data)
  model <- cv.glmnet(X, class, standardize=FALSE, family='multinomial', alpha=1, nfolds=10)

最後のステップ (X = model.matrix ...) で、メモリが不足しています。私に何ができる?

4

2 に答える 2

26

Trevor Hastie 教授に尋ねたところ、次のようなアドバイスがありました。

「こんにちはフラビオ

model.matrix があなたを殺しています。49K の因子があり、モデル マトリックスはそれらを 6 列のマトリックスになる対比として表現しようとしているため、49*6 で約 300K の列になります。バイナリ ダミー変数 (因子ごとに 7 つ) を作成し、model.matrix を使用せずに直接これを構築してみませんか。これを sparseMatrix を介して保存することで、1/7 のスペースを節約できます (glmnet は疎行列形式を受け入れます)」

私はまさにそれを行い、完全にうまくいきました。それは他の人にも役立つと思います。

この問題から生まれたコード付きの記事: http://www.rmining.net/2014/02/25/genetic-data-large-matrices-glmnet/

リンク切れを避けるため、投稿の一部をここに投稿します。

数式アプローチの問題点は、一般に、ゲノム データには観測値よりも多くの列があることです。その場合に私が扱ったデータには、40,000 列と 73 の観測値しかありませんでした。テスト データの小さなセットを作成するには、次のコードを実行します。

for(i in 1:50) {
    x = rep(letters[2:8], 7000)
    y = sample(x=1:49000, size=49000)
    data[i,] <- x[y]
}

data <- as.data.frame(data)
x <- c(rep('A', 20), rep('B', 15), rep('C', 15))
y <- sample(x=1:50, size=50)
class = x[y]
data <- cbind(data, class)

したがって、このデータ セットを使用して、glmnet () を使用してモデルを適合させようとします。

formula <- as.formula(class ~ .)
X <- model.matrix(formula, data)
model <- cv.glmnet(X, class, standardize=FALSE, family='multinomial', alpha=1, nfolds=10)

また、私のコンピューターよりも多くの RAM を搭載したコンピューターを持っていない場合、おそらくメモリ リークが発生し、R でクラッシュが発生するでしょう。解決策は? 私の最初のアイデアは、同じ式を使用して疎行列モデルを作成するsparse.model.matrix()を試すことでした。残念ながら、疎行列を使用しても、最終モデルはまだ大きすぎるため、機能しませんでした! 興味深いことに、このデータセットは RAM から 24MB しか占有しませんが、model.matrix を使用すると、結果は 1Gb を超える配列になります。

私が見つけた解決策は、手持ちのマトリックスを構築することでした。これを行うには、列ごとにダミー変数を使用して配列をエンコードし、結果をスパース行列に格納します。次に、この行列をモデルへの入力として使用し、メモリ リークがないかどうかを確認します。

## Creates a matrix using the first column
X <- sparse.model.matrix(~data[,1]-1)

## Check if the column have more then one level
for (i in 2:ncol(data)) {

## In the case of more then one level apply dummy coding 
if (nlevels(data[,i])>1) {
    coluna <- sparse.model.matrix(~data[,i]-1)
    X <- cBind(X, coluna)
}
## Transform fator to numeric
else {
   coluna <- as.numeric(as.factor(data[,i]))
   X <- cBind(X, coluna)
}

注: Matrix パッケージが必要なスパース マトリックスの使用方法に注意してください。また、列は cbind () の代わりに cBind () を使用して接続されていることに注意してください。

このようにして生成されたマトリックスははるかに低く、私がテストしたときは 70 Mb 未満でした。幸い glmnet () は疎行列をサポートしており、モデルを実行できます。

mod.lasso <- cv.glmnet(X, class, standardize=FALSE, family='multinomial', alpha=1, nfolds=10)

したがって、メモリを浪費することなく、 bigmemoryffなどの大規模なデータセットに R パッケージを使用することなく、このタイプのデータを使用してモデルを作成できます。

于 2013-06-17T15:53:31.460 に答える
6

誰に興味があるかもしれません。biglassoビッグデータを使用したなげなわタイプのモデルに適合するR パッケージを開発しました。bigmemoryこれは、パッケージに基づいてメモリ マップされた (大きな) デザイン マトリックスで動作し、RAM よりも大きなデータの場合でもシームレスに動作します。さらに、glmnet新しく提案された機能スクリーニング規則とより優れた実装を使用する場合と比較して、計算効率とメモリ効率が向上します。詳細については GitHub ページを確認してください。提案やコメントがあればお気軽にお寄せください。

于 2016-12-21T05:27:18.617 に答える