2013-06-10 16 views
18

Mam problem z uruchomieniem glasso lasso z szerokim zestawem danych. Moje dane mają wartość N = 50, ale p> 49000, wszystkie czynniki. Tak więc, aby uruchomić glmnet, muszę utworzyć model.matrix, ale po prostu zabraknie pamięci, gdy zadzwonię do model.matrix (formuła, dane), gdzie formuła = klasa ~.Duża macierz do uruchomienia glmnet()

Jako przykład pracował i wygeneruje zestaw danych:

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) 

Potem próbowałem stworzyć model.matrix aby wejść na glmnet.

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

W ostatnim kroku (X = model.matrix ...) zabrakło pamięci. Co mogę zrobić?

+0

Czas na więcej pamięci RAM. (Lub uruchom ponownie z minimalnym zestawem aplikacji i danych.) To tylko obiekt o szerokości 24 MB. –

+0

Cóż, mam tylko 50 próbek. Nie mogę uwierzyć, że nie ma rozwiązania! –

+0

Nie powiedziałem, że nie było rozwiązania. –

Odpowiedz

22

poprosiłem profesora Trevora Hastie i otrzymał następującą radę.

„Hello Flavio

model.matrix zabija cię Będziesz mieć 49K czynników, i model macierzy stara się reprezentować ich jako kontrastów co będzie 6 kolumnami kolumn, więc 49 * 6 około 300 000 kolumn. Dlaczego nie tworzyć binarnych fałszywych zmiennych (7 na czynnik), i po prostu skonstruować to bezpośrednio bez użycia modelu.matrix.Możesz zaoszczędzić 1/7 przestrzeni, przechowując to przez SparseMatrix (glmnet akceptuje rzadkie formaty matryc) "

Zrobiłem dokładnie to i działałem idealnie dobrze. Myślę, że to może być przydatne dla innych.

artykuł, z kodem, który przyszedł tworzą ten problem: http://www.rmining.net/2014/02/25/genetic-data-large-matrices-glmnet/

W celu uniknięcia niedziałających linków i zaksięguje część słupka tutaj:

Problem z podejściem formuła jest, że w ogólne, dane genomowe mają więcej kolumn niż obserwacji. Dane, które pracowałem w tej sprawie, zawierały 40 000 kolumn i tylko 73 obserwacje. Aby stworzyć mały zestaw danych testowych, uruchom następujący kod:

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) 

Tak, z tego zestawu danych postaramy się dopasować model z glmnet():

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

a jeśli nie masz komputera z większą pamięcią RAM niż moja, prawdopodobnie wyciekniesz pamięć i doprowadzisz do awarii w R. Rozwiązanie? Moim pierwszym pomysłem było wypróbowanie modelu sparse.model.matrix(), który tworzy rzadki model macierzy wykorzystujący tę samą formułę. Niestety nie zadziałało, bo nawet z rzadką matrycą ostateczny model jest wciąż zbyt duży! Co ciekawe, ten zestaw danych zajmuje tylko 24 MB z pamięci RAM, ale gdy używasz modelu.matrix, wynikiem jest tablica z więcej niż 1 GB.

Rozwiązaniem, które znalazłem, było zbudowanie matrycy na ręce. W tym celu kodujemy tablicę ze zmiennymi atrapowymi, kolumna po kolumnie i zapisujemy wynik w rzadkiej macierzy. Wtedy będziemy używać tej macierzy jako wejście do modelu i sprawdzić, czy to nie będzie przeciekać Pamięć:

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

UWAGA: Należy zwrócić uwagę na to, jak używamy rzadki matrycy wymagany jest pakiet Matrix. Zauważ również, że kolumny są połączone za pomocą cBind() zamiast cbind().

Tak wygenerowana macierz była znacznie niższa: mniej niż 70 Mb, gdy testowałem.Na szczęście glmnet() obsługuje rzadki macierzy i można uruchomić model:

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

dzięki czemu można tworzyć modele z tego typu danych bez dmuchanie pamięci i bez pakietów użycie R dla dużych zbiorów danych, takich jak bigmemory i ff.

+1

można również wypróbować 'Matrix :: sparse.model.matrix' lub' MatrixModels :: modelMatrix (*, sparse = TRUE) ' –

+0

To nie działa !!! Spróbuj sam z tym przykładem. Obiekt utworzony za pomocą sparse.model.matrix jest znacznie większy. Próbowałem tego przed napisaniem tego pytania. –

+0

cóż ... to dziwne, zastanawiam się, dlaczego nie. –

1

Dla kogo może być zainteresowany. Opracowałem pakiet R o nazwie biglasso, który pasuje do modeli typu lasso z Big Data. Działa z mapowaną pamięcią (dużą) matrycą projektową opartą na pakiecie bigmemory i może bezproblemowo pracować dla przypadków większych niż pamięci RAM. Co więcej, jest bardziej wydajny w zakresie obliczeń i pamięci w porównaniu z glmnet dzięki zastosowaniu nowo proponowanych reguł kontroli funkcji, jak również lepszej implementacji. Proszę sprawdzić the GitHub page w celu uzyskania szczegółowych informacji, i proszę podać wszelkie sugestie/komentarze.

Powiązane problemy