2013-06-10 14 views
18

Ich habe ein Problem, Glmnet Lasso mit einem breiten Datenset zu betreiben. Meine Daten haben N = 50, aber p> 49000, alle Faktoren. Um glmnet zu starten, muss ich eine model.matrix erstellen, ABER ich habe gerade keinen Speicher mehr, wenn ich model.matrix (Formel, Daten) anrufe, wobei formula = Class ~. Große Matrix zum Ausführen von glmnet()

Als ausgearbeitetes Beispiel i einen Datensatz generieren:

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) 

Danach habe ich versucht, einen model.matrix zu erstellen, die auf glmnet einzugeben.

Im letzten Schritt (X = model.matrix ...) habe ich keinen Speicher mehr. Was kann ich tun?

+0

Zeit für mehr RAM. (Oder starten Sie mit einer minimalen Anzahl von Anwendungen und Daten neu.) Das ist nur ein 24MB breites Objekt. –

+0

Nun, ich habe nur 50 Proben. Ich kann nicht glauben, dass es keine Lösung gibt! –

+0

Ich habe nicht gesagt, dass es keine Lösung gab. –

Antwort

22

Ich fragte Professor Trevor Hastie und erhielt folgende Hinweise:.

„Hallo Flavio

model.matrix Sie tötet Sie 49K Faktoren haben, und Modellmatrix versucht, sie als Gegensätze darstellen das sind 6 Spaltenmatrizen, also 49 * 6 ca. 300K Spalten Warum nicht binäre Dummy-Variablen (7 pro Faktor) erstellen, sondern einfach ohne model.matrix selbst. Sie könnten 1/7 Speicherplatz sparen, indem Sie speichern dies über SparseMatrix (glmnet akzeptiert dünn besetzte Matrixformate) "

Ich tat genau das und funktionierte perfekt gut. Ich denke, dass das für andere nützlich sein kann.

Ein Artikel, mit Code, das dieses Problem kam bilden: http://www.rmining.net/2014/02/25/genetic-data-large-matrices-glmnet/

Um defekte Links zu vermeiden ich hier einen Teil des Stiftes werde Post:

Das Problem mit der Formel Ansatz besteht darin, dass allgemeine genomische Daten haben mehr Spalten als Beobachtungen. Die Daten, die ich in diesem Fall bearbeitet habe, hatten 40.000 Spalten und nur 73 Beobachtungen. Um einen kleinen Satz von Testdaten, führen Sie den folgenden Code zu erstellen:

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) 

Also, mit diesem Datensatz werden wir versuchen, ein Modell mit glmnet zu passen():

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

Und wenn Sie haben keinen Computer mit mehr RAM als meins, Sie werden wahrscheinlich Speicher auslaufen und einen Absturz in R geben. Die Lösung? Meine erste Idee war es, sparse.model.matrix() zu versuchen, die ein Sparse-Matrix-Modell mit der gleichen Formel erstellt. Leider hat es nicht geklappt, denn selbst bei spärlicher Matrix ist das endgültige Modell noch zu groß! Interessanterweise belegt dieses Dataset nur 24 MB RAM, aber wenn Sie die model.matrix verwenden, ist das Ergebnis ein Array mit mehr als 1 GB.

Die Lösung, die ich fand, war die Matrix auf der Hand zu bauen. Um dies zu tun, kodieren wir das Array mit Dummy-Variablen, Spalte für Spalte, und speichern das Ergebnis in einer Sparse-Matrix. Dann werden wir diese Matrix als Eingabe für das Modell verwenden und sehen, ob es nicht ein Speicherleck wird:

## 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) 
} 

HINWEIS: Achten Sie darauf, wie wir eine spärliche Matrix der Matrix-Paket verwenden, ist erforderlich. Beachten Sie auch, dass die Spalten mit cBind() anstelle von cbind() verbunden sind.

Die so erzeugte Matrix war viel niedriger: weniger als 70 MB beim Testen.Zum Glück glmnet() unterstützt eine spärliche Matrix und Sie können das Modell laufen:

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

So können Sie Modelle mit dieser Art von Daten erstellen, ohne den Speicher Blas- und ohne Verwendung R-Pakete für große Datensätze wie bigmemory und ff.

+1

können Sie auch versuchen Matrix 'sparse.model.matrix' oder' MatrixModels :: modelMatrix (*, sparse = TRUE) ' –

+0

Das funktioniert nicht !!! Probieren Sie es mit dem Beispiel aus. Das mit sparse.model.matrix erstellte Objekt ist sehr viel größer. Ich habe das vor dem Posten dieser Frage versucht. –

+0

naja ... das ist seltsam, ich frage mich warum nicht. –

1

An wen könnte es interessiert sein. Ich habe ein R-Paket namens biglasso entwickelt, das für Lasso-Modelle mit Big Data passt. Es arbeitet mit einer speichergestützten (großen) Entwurfsmatrix, die auf dem bigmemory-Paket basiert, und kann nahtlos für Daten arbeiten, die größer sind als RAM-Fälle. Darüber hinaus ist es im Vergleich zu glmnet berechenbarer und speichereffizienter, indem neu vorgeschlagene Feature-Screening-Regeln sowie eine bessere Implementierung verwendet werden. Bitte überprüfen Sie the GitHub page für Details, und fühlen Sie sich frei, irgendwelche Vorschläge/Kommentare zur Verfügung zu stellen.

Verwandte Themen