Próbuję uruchomić SVR przy użyciu scikit learn (python) na zbiorze danych szkoleniowych posiadającym 595605 wierszy i 5 kolumn (funkcji) oraz testowym zbiorze danych posiadającym 397070 wierszy. Dane zostały wstępnie przetworzone i uregulowane.
Jestem w stanie z powodzeniem uruchomić przykłady testowe, ale po uruchomieniu przy użyciu mojego zestawu danych i pozostawieniu go na ponad godzinę nadal nie widziałem żadnego wyjścia ani zakończenia programu. Próbowałem wykonać przy użyciu innego IDE, a nawet z terminala, ale nie wydaje się, żeby to był problem. Próbowałem także zmienić wartość parametru „C” z 1 na 1e3.
Mam podobne problemy ze wszystkimi implementacjami svm korzystającymi z programu scikit.
Czy nie czekam wystarczająco długo, aby się skończyć? Ile czasu powinna zająć ta egzekucja?
Z mojego doświadczenia nie powinno to wymagać więcej niż kilku minut.
Oto moja konfiguracja systemu: Ubuntu 14.04, 8 GB pamięci RAM, dużo wolnej pamięci, procesor i7 4. generacji
źródło
Odpowiedzi:
Jądra SVM wymagają obliczenia funkcji odległości między każdym punktem zestawu danych, co jest dominującym kosztem . Przechowywanie odległości jest obciążeniem dla pamięci, dlatego są one przeliczane w locie. Na szczęście przez większość czasu potrzebne są tylko punkty najbliższe granicy decyzji. Często obliczane odległości są przechowywane w pamięci podręcznej. Jeśli pamięć podręczna jest obciążona, czas działania zwiększa się do O ( n cech x n 3 obserwacji ) .O ( ncechy× n2)obserwacje) O ( ncechy× n3)obserwacje)
Możesz zwiększyć tę pamięć podręczną, wywołując SVR as
Ogólnie rzecz biorąc, to nie zadziała. Ale nie wszystko stracone. Możesz podpróbkować dane i wykorzystać resztę jako zestaw sprawdzania poprawności lub wybrać inny model. Powyżej 200 000 zakresu obserwacji mądrze jest wybrać uczniów liniowych.
SVM jądra można aproksymować, przybliżając matrycę jądra i podając ją do liniowego SVM. Pozwala to na kompromis między dokładnością a wydajnością w czasie liniowym.
Popularnym sposobem osiągnięcia tego jest użycie około 100 centrów klastrów znalezionych przez kmeans / kmeans ++ jako podstawy funkcji jądra. Nowe funkcje pochodne są następnie wprowadzane do modelu liniowego. W praktyce działa to bardzo dobrze. Narzędzia takie jak Sophia -ml i Wabbit Wabbit to sposób, w jaki robią to Google, Yahoo i Microsoft. Wejście / wyjście staje się dominującym kosztem dla prostych uczniów liniowych.
W obfitości danych modele nieparametryczne działają mniej więcej tak samo w przypadku większości problemów. Wyjątek stanowią uporządkowane dane wejściowe, takie jak tekst, obrazy, szeregi czasowe, dźwięk.
Dalsza lektura
źródło
SVM rozwiązuje problem optymalizacji rzędu kwadratowego.
Nie mam nic do dodania, co nie zostało tu powiedziane. Chcę tylko zamieścić link do strony sklearn o SVC, która wyjaśnia, co się dzieje:
Jeśli nie chcesz używać jądra, a wystarcza liniowy SVM, istnieje LinearSVR, który jest znacznie szybszy, ponieważ wykorzystuje podejście optymalizacyjne ala regresje liniowe. Będziesz jednak musiał znormalizować swoje dane, na wypadek, gdybyś tego jeszcze nie zrobił, ponieważ stosuje to normalizacji do współczynnika przechwytywania, co prawdopodobnie nie jest tym, czego chcesz. Oznacza to, że jeśli średnia danych jest daleka od zera, nie będzie w stanie rozwiązać jej w zadowalający sposób.
Można również użyć stochastycznego spadku gradientu w celu rozwiązania problemu optymalizacji. Sklearn posiada SGDRegressor . Musisz użyć,
loss='epsilon_insensitive'
aby uzyskać wyniki podobne do liniowej SVM. Zobacz dokumentację. Używałbym jednak zejścia gradientowego tylko w ostateczności, ponieważ implikuje to wiele ulepszeń hiperparametrów, aby uniknąć utknięcia w lokalnych minimach. Użyj,LinearSVR
jeśli możesz.źródło
Czy uwzględniłeś skalowanie na etapie wstępnego przetwarzania? Miałem ten problem podczas uruchamiania mojej SVM. Mój zestaw danych to ~ 780 000 próbek (wiersz) z 20 funkcjami (kol.). Mój zestaw treningowy to ~ 235 000 próbek. Okazuje się, że po prostu zapomniałem skalować moje dane! W takim przypadku spróbuj dodać ten bit do swojego kodu:
przeskaluj dane do [-1,1]; zwiększyć prędkość SVM:
źródło
Przy tak ogromnym zestawie danych myślę, że lepiej byłoby użyć sieci neuronowej, głębokiego uczenia się, losowego lasu (są zaskakująco dobre) itp.
Jak wspomniano we wcześniejszych odpowiedziach, czas potrzebny jest proporcjonalny do trzeciej potęgi liczby próbek treningowych. Nawet czas przewidywania jest wielomianowy pod względem liczby wektorów testowych.
Jeśli naprawdę musisz korzystać z SVM, zalecam przyspieszenie GPU lub zmniejszenie rozmiaru zestawu danych treningowych. Spróbuj najpierw z próbką (może 10 000 wierszy) danych, aby zobaczyć, czy nie jest to problem z formatem lub dystrybucją danych.
Jak wspomniano w innych odpowiedziach, jądra liniowe są szybsze.
źródło
Ostatnio napotkałem podobny problem, ponieważ zapomniałem skalować funkcje w moim zbiorze danych, który wcześniej był używany do trenowania rodzaju modelu zespołu. Skalowanie danych może być prawdopodobnym winowajcą, jak wskazała Shelby Matlock. Możesz wypróbować różne skalery dostępne w sklearn, takie jak RobustScaler :
from sklearn.preprocessing import RobustScaler scaler = RobustScaler() X = scaler.fit_transfrom(X)
X jest teraz przekształcany / skalowany i gotowy do dostarczenia do żądanego modelu.
źródło
To ma sens. IIUC, szybkość wykonywania operacji na wektorach nośnych jest ograniczona liczbą próbek, a nie wymiarowością. Innymi słowy, ogranicza go czas procesora, a nie pamięć RAM. Nie jestem pewien, ile dokładnie to powinno zająć, ale przeprowadzam testy, aby się dowiedzieć.
źródło
Pozostaw na noc lub dłużej przez 24 godziny. Jakie jest twoje wykorzystanie procesora? Jeśli żaden z rdzeni nie działa przy 100%, oznacza to problem. Prawdopodobnie z pamięcią. Czy sprawdziłeś, czy Twój zestaw danych w ogóle pasuje do 8 GB? Czy próbowałeś SGDClassifier? Jest to jeden z najszybszych tam. Warto spróbować najpierw, mając nadzieję, że zakończy się za około godzinę.
źródło
SGDClassifier
nie obsługuje jąder. Jeśli OP chce liniowej SVM, polecam najpierw spróbowaćLinearSVR
. Jest znacznie szybszy niżSVR
dlatego, że rozwiązuje problem za pomocą biblioteki regresji liniowej, a globalne minimum jest gwarantowane (w przeciwieństwie do gradientu spadku).The loss function to be used. Defaults to ‘hinge’, which gives a linear SVM.
samo dlaSGDRegressor
.SGDRegressor
jest równoważne z używaniemSVR(kernel='linear')
. Jeśli tego właśnie chce OP, to świetnie. Miałem wrażenie, że chciał używać SVM z jądrem. Jeśli tak nie jest, poleciłbym, żeby najpierw spróbowałLinearSVR
.Spróbuj normalizować dane do [-1,1]. Napotkałem podobny problem i po normalizacji wszystko działało dobrze. Możesz łatwo znormalizować dane, używając:
from sklearn import preprocessing X_train = preprocessing.scale(X_train) X_test = preprocessing.scale(X_test)
źródło
Zetknąłem się z tym problemem i
cache_size
jak sugerują inni, wcale nie pomaga. Możesz zobaczyć ten post i ten jako główny autor sugerujący, że powinieneś zmienić kod ręcznie.Jak wiesz,
SVC
iSVR
są problemy optymalizacyjne i przestać kiedy margines błędu jest tak mało, gdzie dalsza optymalizacja jest daremny. Jest więc kolejny parametr, wmax_iter
którym możesz ustawić, ile iteracji ma wykonać.Użyłem
sklearn
w Pythonie, a takżee1071
w R i R znacznie szybciej dochodzi do wyniku bez ustawianiamax_iter
isklearn
trwa 2-4 razy dłużej. Jedynym sposobem, w jaki mogłem skrócić czas obliczeń dla Pythona, było użyciemax_iter
. To jest w stosunku do złożoności modelu, numeru funkcji, jąder i hiperparametrów, ale dla małego zbioru danych użyłem około 4000 Datapoint imax_iter
była10000
wyniki nie różniły się w ogóle i to było do zaakceptowania.źródło
Właśnie miałem podobny problem z zestawem danych, który zawiera tylko 115 elementów i tylko jedną cechę (dane międzynarodowych linii lotniczych). Rozwiązaniem było skalowanie danych. Do tej pory w odpowiedziach brakowało mi użycie rurociągu:
Możesz trenować
model
jak zwykły model klasyfikacji / regresji i oceniać go w ten sam sposób. Nic się nie zmienia, tylko definicja modelu.źródło
Pipeline
? Nie importujesz tego.Musisz skalować swoje dane. Skalowanie znormalizuje punkty danych do zakresu od -1 do 1, co pomoże w szybszej konwergencji.
Spróbuj użyć następującego kodu:
źródło