Scikit-learn'da sınıflandırıcıyı diske kaydedin


192

Nasıl eğitimli bir tasarruf yapmak sınıflandırıcı Naif Bayes için diske ve için kullanabilirsiniz tahmin verileri?

Scikit-learn web sitesinden aşağıdaki örnek program var:

from sklearn import datasets
iris = datasets.load_iris()
from sklearn.naive_bayes import GaussianNB
gnb = GaussianNB()
y_pred = gnb.fit(iris.data, iris.target).predict(iris.data)
print "Number of mislabeled points : %d" % (iris.target != y_pred).sum()

Yanıtlar:


201

Sınıflandırıcılar sadece diğerleri gibi turşup dökülebilen nesnelerdir. Örneğinize devam etmek için:

import cPickle
# save the classifier
with open('my_dumped_classifier.pkl', 'wb') as fid:
    cPickle.dump(gnb, fid)    

# load it again
with open('my_dumped_classifier.pkl', 'rb') as fid:
    gnb_loaded = cPickle.load(fid)

1
Tıkır tıkır çalışıyor! Ben np.savez kullanmaya çalıştım ve geri yüklemek ve bu hiç yardımcı olmadı. Çok teşekkürler.
Kartos

7
python3'te, tam olarak böyle çalışan turşu modülünü kullanın.
MCSH

213

Sayısal dizileri işlemede varsayılan python seçiciden çok daha verimli olan joblib.dump ve joblib.load öğelerini de kullanabilirsiniz .

Joblib scikit-learn'a dahildir:

>>> import joblib
>>> from sklearn.datasets import load_digits
>>> from sklearn.linear_model import SGDClassifier

>>> digits = load_digits()
>>> clf = SGDClassifier().fit(digits.data, digits.target)
>>> clf.score(digits.data, digits.target)  # evaluate training error
0.9526989426822482

>>> filename = '/tmp/digits_classifier.joblib.pkl'
>>> _ = joblib.dump(clf, filename, compress=9)

>>> clf2 = joblib.load(filename)
>>> clf2
SGDClassifier(alpha=0.0001, class_weight=None, epsilon=0.1, eta0=0.0,
       fit_intercept=True, learning_rate='optimal', loss='hinge', n_iter=5,
       n_jobs=1, penalty='l2', power_t=0.5, rho=0.85, seed=0,
       shuffle=False, verbose=0, warm_start=False)
>>> clf2.score(digits.data, digits.target)
0.9526989426822482

Düzenleme: Python 3.8 ve daha sonraki sürümlerde (varsayılan olmayan) turşu protokolü kullanıyorsanız öznitelik olarak büyük sayısal diziler ile nesnenin verimli turşu için turşu kullanmak mümkün.


1
Ama benim anlayışımdan boru hattı tek bir iş akışının parçasıysa işe yarıyor. Modeli oluşturmak istersem diske kaydet ve orada çalıştırmayı durdur. Sonra bir hafta sonra geri gelip modeli diskten yüklemeye çalışıyorum bana bir hata atıyor:
venuktan

2
fitEğer aradığınız şey buysa , yöntemin yürütülmesini durdurmanın ve devam ettirmenin bir yolu yoktur . Bununla birlikte , scikit-learn kütüphanesinin aynı sürümüne sahip bir Python'dan çağırırsanız joblib.load, başarılı olduktan sonra bir istisna oluşturmamalıdır joblib.dump.
ogrisel

10
IPython kullanıyorsanız , örtük ad alanı aşırı yüklemesinin dekapaj işlemini bozduğu bilindiğinden , --pylabkomut satırı bayrağını veya %pylabsihri kullanmayın . %matplotlib inlineBunun yerine açık ithalat ve sihir kullanın.
ogrisel

2
referans için scikit-learn belgelerine bakın: scikit-learn.org/stable/tutorial/basic/…
user1448319

1
Önceden kaydedilmiş modeli yeniden eğitmek mümkün mü? Özellikle SVC modelleri?
Uday Sawant

108

Aradığınız şeye sklearn kelimelerinde Model kalıcılığı denir ve giriş ve model kalıcılığı bölümlerinde belgelenir .

Böylece sınıflandırıcıyı başlattınız ve uzun bir süre boyunca

clf = some.classifier()
clf.fit(X, y)

Bundan sonra iki seçeneğiniz var:

1) Turşu Kullanma

import pickle
# now you can save it to a file
with open('filename.pkl', 'wb') as f:
    pickle.dump(clf, f)

# and later you can load it
with open('filename.pkl', 'rb') as f:
    clf = pickle.load(f)

2) Joblib'i kullanma

from sklearn.externals import joblib
# now you can save it to a file
joblib.dump(clf, 'filename.pkl') 
# and later you can load it
clf = joblib.load('filename.pkl')

Bir kez daha yukarıda belirtilen bağlantıları okumak yardımcı olur


30

Birçok durumda, özellikle metin sınıflandırmasında, sadece sınıflandırıcıyı depolamak yeterli değildir, ancak ileride girdilerinizi vektörleştirebilmeniz için vektörleyiciyi de saklamanız gerekir.

import pickle
with open('model.pkl', 'wb') as fout:
  pickle.dump((vectorizer, clf), fout)

gelecekteki kullanım durumu:

with open('model.pkl', 'rb') as fin:
  vectorizer, clf = pickle.load(fin)

X_new = vectorizer.transform(new_samples)
X_new_preds = clf.predict(X_new)

Vectorizer'ı boşaltmadan önce, vectorizer'ın stop_words_ özelliğini silebilirsiniz:

vectorizer.stop_words_ = None

dökümü daha verimli hale getirmek. Ayrıca sınıflandırıcı parametreleriniz seyrekse (çoğu metin sınıflandırma örneğinde olduğu gibi), parametreleri yoğundan seyreye dönüştürebilirsiniz, bu da bellek tüketimi, yükleme ve boşaltma açısından büyük bir fark yaratacaktır. Modeli şu şekilde ayırın :

clf.sparsify()

Bu otomatik olarak SGDClassifier için çalışacaktır, ancak modelinizin seyrek olduğunu biliyorsanız (clf.coef_ içindeki sıfırlar bir sürü), sonra clf.coef_'yi manuel olarak bir csr scipy seyrek matrisine dönüştürebilirsiniz :

clf.coef_ = scipy.sparse.csr_matrix(clf.coef_)

ve daha verimli bir şekilde saklayabilirsiniz.


Anlayışlı cevap! Sadece SVC durumunda eklemek istedim, seyrek bir model parametresi döndürür.
Shayan Amani

5

sklearntahmin ediciler, bir tahmin edicinin ilgili eğitimli özelliklerini kaydetmenizi kolaylaştırmak için yöntemler uygular. Bazı tahminciler __getstate__yöntemleri kendileri uygularlar , ancak diğerleri GMMsadece nesnelerin iç sözlüğünü kaydeden temel uygulamayı kullanır gibi :

def __getstate__(self):
    try:
        state = super(BaseEstimator, self).__getstate__()
    except AttributeError:
        state = self.__dict__.copy()

    if type(self).__module__.startswith('sklearn.'):
        return dict(state.items(), _sklearn_version=__version__)
    else:
        return state

Modelinizi diske kaydetmenin önerilen yöntemi picklemodülü kullanmaktır :

from sklearn import datasets
from sklearn.svm import SVC
iris = datasets.load_iris()
X = iris.data[:100, :2]
y = iris.target[:100]
model = SVC()
model.fit(X,y)
import pickle
with open('mymodel','wb') as f:
    pickle.dump(model,f)

Ancak, ileride modelinizi yeniden eğitmek veya korkunç sonuçlara maruz kalmak için (sklearn'un eski bir sürümüne kilitlenmek gibi) ek verileri kaydetmeniz gerekir .

Gönderen belgeler :

Scikit-learn'ın gelecekteki sürümleriyle benzer bir modeli yeniden oluşturmak için, turşu model boyunca ek meta veriler kaydedilmelidir:

Egzersiz verileri, örneğin değişmez bir anlık görüntü referansı

Modeli oluşturmak için kullanılan python kaynak kodu

Scikit-learn sürümleri ve bağımlılıkları

Eğitim verilerinden alınan çapraz geçerlilik puanı

Bu özellikle , aşağıdakilere dayanan Topluluk tahmincileri için geçerlidir .tree.pyx Cython ile yazılmış modüle (örneğin IsolationForest) , çünkü sklearn sürümleri arasında kararlı olması garanti edilmeyen uygulamaya bir bağlantı oluşturur. Geçmişte geriye dönük olarak uyumsuz değişiklikler gördü.

Modelleriniz çok büyük olursa ve yükleme sıkıntı haline gelirse, daha verimli olan joblib . Belgelerden:

Scikitin özel durumunda, işlenmiş scikit-öğrenme tahmin edicileri için genellikle olduğu gibi dahili olarak büyük numpy dizileri taşıyan nesneler üzerinde daha verimli olan joblib'in pickle( joblib.dump& joblib.load) yerine kullanılması daha ilginç olabilir, ancak sadece turşu yapabilir bir dizeye değil diske:


1
but can only pickle to the disk and not to a stringAncak bunu joblib'den StringIO'ya alabilirsiniz. Her zaman yaptığım bu.
Matthew

Mevcut projem de benzer bir şey yapıyor, The training data, e.g. a reference to a immutable snapshotburada ne olduğunu biliyor musunuz ? TIA!
Daisy Qin

1

sklearn.externals.joblibkullanımdan kaldırıldı yana 0.21ve kaldırılacaktır v0.23:

/usr/local/lib/python3.7/site-packages/sklearn/externals/joblib/ init .py: 15: FutureWarning: sklearn.externals.joblib 0,21'de kullanımdan kaldırıldı ve 0,23'te kaldırılacak. Lütfen bu işlevselliği doğrudan aşağıdakilerle kurulabilen joblib'den içe aktarın: pip install joblib. Turşu modelleri yüklenirken bu uyarı verilirse, scikit-learn 0.21+ ile bu modelleri yeniden serileştirmeniz gerekebilir.
msgstr (msg, kategori = Gelecek Uyarısı)


Bu nedenle, yüklemeniz gerekir joblib:

pip install joblib

ve son olarak modeli diske yazın:

import joblib
from sklearn.datasets import load_digits
from sklearn.linear_model import SGDClassifier


digits = load_digits()
clf = SGDClassifier().fit(digits.data, digits.target)

with open('myClassifier.joblib.pkl', 'wb') as f:
    joblib.dump(clf, f, compress=9)

Döküm dosyasını okumak için tek yapmanız gereken:

with open('myClassifier.joblib.pkl', 'rb') as f:
    my_clf = joblib.load(f)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.