Jakie są różne przypadki użycia Joblib i marynaty?

85

Tło: dopiero zaczynam pracę ze scikit-learn i czytam na dole strony o joblib i marynacie .

bardziej interesujące może być użycie zamiennika pickle z joblib (joblib.dump & joblib.load), który jest bardziej wydajny w przypadku dużych zbiorów danych, ale może tylko wytrawiać na dysku, a nie na łańcuchu

Czytałem te pytania i odpowiedzi na temat Pickle, Typowe przypadki użycia marynaty w Pythonie i zastanawiam się, czy społeczność tutaj może dzielić się różnicami między joblib i marynatą? Kiedy należy używać jednego nad drugim?

msunbot
źródło

Odpowiedzi:

97
  • joblib jest zwykle znacznie szybsze w przypadku dużych tablic numpy, ponieważ ma specjalną obsługę buforów tablicowych struktury numpy. Aby dowiedzieć się więcej o szczegółach implementacji, zajrzyj do kodu źródłowego . Może również kompresować te dane w locie podczas wytrawiania przy użyciu zlib lub lz4.
  • joblib umożliwia również mapowanie pamięci bufora danych nieskompresowanej tablicy numpy-pickled joblib podczas ładowania go, co umożliwia współdzielenie pamięci między procesami.
  • jeśli nie wytrawiasz dużych tablic numpy, to zwykłe pickle może być znacznie szybsze, szczególnie w przypadku dużych kolekcji małych obiektów Pythona (np. duży dykt obiektów str), ponieważ moduł pickle biblioteki standardowej jest zaimplementowany w C, podczas gdy plik joblib jest czysty Python.
  • Ponieważ PEP 574 (protokół Pickle 5) został włączony do Pythona 3.8, teraz znacznie bardziej wydajne jest (pod względem pamięci i procesora) pobieranie dużych tablic numpy przy użyciu biblioteki standardowej. Duże tablice w tym kontekście oznaczają 4 GB lub więcej.
  • Ale joblib może być nadal przydatne w Pythonie 3.8 do ładowania obiektów, które mają zagnieżdżone tablice numpy w trybie mapowania pamięci z mmap_mode="r".
ogrisel
źródło
1
Wielkie dzięki! To jest pomocne.
msunbot
2
Czy to oznacza, że ​​powinniśmy użyć Joblibponad Pickle? Jakieś wady tego Joblib, co powinniśmy rozważyć? Właśnie o tym Joblibniedawno słyszałem i brzmi to dla mnie interesująco.
Catbuilts
2
Zaktualizowałem moją odpowiedź o wady i nowe rzeczy, które dzieją się w standardowej bibliotece.
ogrisel
2
Czy joblib również wykonuje dowolny kod podczas anulowania analizy? (Niebezpieczne)
Mr-Programs,
Jest to trudne do przeczytania przez wszystkie "Zauważ, że ..." i uzyskania jednowierszowego podsumowania: joblib jest X razy szybsze do zapisywania dużych tablic numpy w 3.8, co mniej więcej to X? i czytać? a pickle jest mniej więcej Y razy szybszy do pisania wielu małych obiektów Pythona, co to jest Y? i czytać? Jakie są także względne współczynniki kompresji / rozmiary plików?
smci
12

Dziękujemy Gunjan za udostępnienie nam tego scenariusza! Zmodyfikowałem go dla wyników Python3

#comapare pickle loaders
from time import time
import pickle
import os
import _pickle as cPickle
from sklearn.externals import joblib

file = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'database.clf')
t1 = time()
lis = []
d = pickle.load(open(file,"rb"))
print("time for loading file size with pickle", os.path.getsize(file),"KB =>", time()-t1)

t1 = time()
cPickle.load(open(file,"rb"))
print("time for loading file size with cpickle", os.path.getsize(file),"KB =>", time()-t1)

t1 = time()
joblib.load(file)
print("time for loading file size joblib", os.path.getsize(file),"KB =>", time()-t1)

time for loading file size with pickle 79708 KB => 0.16768312454223633
time for loading file size with cpickle 79708 KB => 0.0002372264862060547
time for loading file size joblib 79708 KB => 0.0006849765777587891
Michael Mano
źródło
Gunjan użył pliku do wytrawiania 1154320653 KB. Czy większy plik może wpłynąć na korzyść joblib?
guiferviz
2
Prosimy o podanie zawsze używanej wersji Pythona podczas wyświetlania wskaźników wydajności. 2,6? 2,7? 3,6? 3.7? Jeszcze lepiej, podaj względne liczby joblib vs pickle vs cPickle. Napraw również błąd Gunjana, który wynosi 1,1 GB, a nie 1,1 TB
smci,
8

Natknąłem się na to samo pytanie, więc wypróbowałem to (z Pythonem 2.7), ponieważ muszę załadować duży plik marynaty

#comapare pickle loaders
from time import time
import pickle
import os
try:
   import cPickle
except:
   print "Cannot import cPickle"
import joblib

t1 = time()
lis = []
d = pickle.load(open("classi.pickle","r"))
print "time for loading file size with pickle", os.path.getsize("classi.pickle"),"KB =>", time()-t1

t1 = time()
cPickle.load(open("classi.pickle","r"))
print "time for loading file size with cpickle", os.path.getsize("classi.pickle"),"KB =>", time()-t1

t1 = time()
joblib.load("classi.pickle")
print "time for loading file size joblib", os.path.getsize("classi.pickle"),"KB =>", time()-t1

Wynik tego jest

time for loading file size with pickle 1154320653 KB => 6.75876188278
time for loading file size with cpickle 1154320653 KB => 52.6876490116
time for loading file size joblib 1154320653 KB => 6.27503800392

Zgodnie z tym joblib działa lepiej niż moduł cPickle i Pickle z tych 3 modułów. Dzięki

Gunjan
źródło
2
Myślałem, że cpickle powinien być szybszy niż pikle?
Echo
Czy ten test porównawczy został wykonany w Pythonie 3, który domyślnie używa pickle (protokół = 3) (który jest szybszy niż domyślny w pythonie2)?
LearnOPhile
3
os.path.getsize zwraca bajty, a nie kilobajty, więc mówimy o pliku o wielkości około 1,1 GB (a nie 1,1 TB, jak się wydaje z danych wyjściowych)
Vlad Iliescu
To świetnie, ale popraw dane wyjściowe tak, aby odzwierciedlało 1,1 GB, a nie 1,1 TB. Jeszcze lepszym rozwiązaniem byłoby wykreślenie liczb porównawczych dla rozmiarów plików w potęgach-10 od 1KB ... 10GB, dla wersji Pythona 3.6, 3.7, 3.8 i 2.7, dla joblib, pickle i cPickle.
smci