2012-06-25 10 views
7

Próbuję użyć obiektu LogisticRegression sklearn 0.11, aby dopasować model do 200 000 obserwacji przy użyciu około 80 000 funkcji. Celem jest klasyfikacja krótkich opisów tekstowych na 1 z 800 klas.Błąd pamięci regresji logiki Scikit-Learn

Gdy próbuję dopasować pythonw.exe klasyfikatora daje mi:

Application Error „Instrukcja w ... pamięci odwołuje się 0x00000000”. Pamięć nie mogła zostać zapisana. "

Funkcje są bardzo rzadkie, około 10 na obserwację i są binarne (1 lub 0), więc moim zdaniem obliczenia obwiedni moje 4 GB pamięci RAM powinno być w stanie poradzić sobie z wymaganiami dotyczącymi pamięci, ale wydaje się, że nie jest tak w przypadku modeli, które pasują tylko wtedy, gdy używam mniej obserwacji i/lub mniej funkcji,

Jeśli w ogóle, chciałbym użyć jeszcze więcej obserwacji i funkcji. naiwne zrozumienie polega na tym, że biblioteka liblinear działająca za kulisami jest w stanie ją wspierać.Wszelkie pomysły na to, jak mogę wycisnąć kilka dodatkowych obserwacji w?

Mój kod wygląda następująco:

y_vectorizer = LabelVectorizer(y) # my custom vectorizer for labels 
y = y_vectorizer.fit_transform(y) 

x_vectorizer = CountVectorizer(binary = True, analyzer = features) 
x = x_vectorizer.fit_transform(x) 

clf = LogisticRegression() 
clf.fit(x, y) 

Funkcja() Funkcja, którą przekazuję do analizatora, zwraca listę ciągów wskazującą cechy wykryte w każdej obserwacji.

Używam Python 2.7, sklearn 0.11, Windows XP z 4 GB pamięci RAM.

+0

Czy interpreter w języku Python zawiesił się? Zapisywanie do '0x0' jest dość poważnym błędem, powinniśmy (scikit-learn developerzy) zajrzeć do niego. –

+0

Interpreter Pythona ulega awarii. –

+0

Czy używany zestaw danych jest publiczny? Czy możesz odtworzyć tę awarię za pomocą mniejszego zestawu danych (na przykład z 'x_first_half = x [: x.shape [0]/2]' lub 'x_second_half = x [x.kształt [0]/2:] '? – ogrisel

Odpowiedz

20

liblinear (realizacja pokrywająca sklearn.linear_model.LogisticRegression) organizuje własną kopię danych, ponieważ jest to biblioteka C++, której wewnętrzna pamięć układu nie mogą być bezpośrednio mapowane na wstępnie przydzielona rzadki matrycy scipy takie jak scipy.sparse.csr_matrix lub scipy.sparse.csc_matrix.

W twoim przypadku polecam załadować swoje dane jako scipy.sparse.csr_matrix i karmić go do sklearn.linear_model.SGDClassifier (z loss='log' jeśli chcesz model regresji logistycznej oraz zdolność do wywołania metody predict_proba). SGDClassifier nie skopiuje danych wejściowych, jeśli już korzysta z układu pamięci scipy.sparse.csr_matrix.

Należy oczekiwać, że w pamięci zostanie przydzielony gęsty model o wielkości 800 * (80000 + 1) * 8/(1024 ** 2) = 488 MB (oprócz rozmiaru wejściowego zestawu danych wejściowych).

Edit: jak zoptymalizować dostęp do pamięci dla zbioru danych

Aby zwolnić pamięć po ekstrakcji zestawu danych można:

x_vectorizer = CountVectorizer(binary = True, analyzer = features) 
x = x_vectorizer.fit_transform(x) 
from sklearn.externals import joblib 
joblib.dump(x.tocsr(), 'dataset.joblib') 

następnie zamknij ten proces Pythona (wymuszenie kompletnego dealokacji pamięci) i w nowym procesie:

x_csr = joblib.load('dataset.joblib') 

Pod Linuksem/OSX możesz mapować pamięć jeszcze wydajniej dzięki:

x_csr = joblib.load('dataset.joblib', mmap_mode='c') 
+3

Doskonała odpowiedź, zapewniasz lepszą obsługę tego darmowego oprogramowania, niż inne oferują bardzo drogie oprogramowanie, świat zawdzięcza Ci wiele podziękowań. Jedna drobna uwaga, jednak metoda predict_proba SGDClassifier wydaje się być implementowana tylko dla zadań klasyfikacji 2 kategorii. –

+0

Rzeczywiście, zapomniałem o tym. Na liście mailingowej odbywa się obecnie dyskusja w celu dodania prawidłowej wielomianowej regresji logistycznej do SGDClassifier lub wdrożenia skalowania Platt lub wariantów przewidywania prawdopodobieństw w ustawieniu multiclass w jednym kontraście. – ogrisel