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)
したがって、メモリを浪費することなく、 bigmemoryやffなどの大規模なデータセットに R パッケージを使用することなく、このタイプのデータを使用してモデルを作成できます。