स्किट-डिस्क में डिस्क पर क्लासिफायर सहेजें


192

मैं डिस्क को प्रशिक्षित नाइव बेयस क्लासिफायर को कैसे बचा सकता हूं और इसका उपयोग डेटा की भविष्यवाणी करने के लिए कर सकता हूं ?

मेरे पास scikit-learn वेबसाइट से निम्नलिखित नमूना कार्यक्रम है:

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()

जवाबों:


201

क्लासिफायर सिर्फ ऐसी वस्तुएं हैं जिन्हें किसी भी अन्य की तरह उठाया और डंप किया जा सकता है। अपना उदाहरण जारी रखने के लिए:

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
एक जादू की तरह काम करता है! मैं np.savez का उपयोग करने की कोशिश कर रहा था और इसे वापस सभी के साथ लोड कर रहा था और कभी मदद नहीं की। बहुत बहुत धन्यवाद।
कार्तोस

7
python3 में, अचार मॉड्यूल का उपयोग करें, जो बिल्कुल इस तरह से काम करता है।
MCSH

212

आप joblib.dump और joblib.load का भी उपयोग कर सकते हैं जो कि डिफ़ॉल्ट अजगर पिकर की तुलना में संख्यात्मक सरणियों को संभालने में बहुत अधिक कुशल है।

जॉक्लिब को शामिल किया गया है

>>> 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

संपादित करें: पायथन 3.8+ में अब बड़ी संख्या में सरणियों के साथ ऑब्जेक्ट के कुशल अचार के लिए अचार का उपयोग करना संभव है यदि आप अचार प्रोटोकॉल 5 का उपयोग करते हैं (जो डिफ़ॉल्ट नहीं है)।


1
लेकिन मेरी समझ से पाइपलाइनिंग काम करती है अगर इसका एक भी काम प्रवाह हो। यदि मैं मॉडल को डिस्क पर संग्रहीत करना चाहता हूं और निष्पादन को रोकना चाहता हूं। फिर मैं एक हफ्ते बाद वापस आता हूं और डिस्क से मॉडल को लोड करने की कोशिश करता हूं, इससे मुझे एक त्रुटि
मिलती है

2
fitविधि के निष्पादन को रोकने और फिर से शुरू करने का कोई तरीका नहीं है यदि यह वही है जो आप खोज रहे हैं। कहा जा रहा है, joblib.loadएक सफल के बाद एक अपवाद नहीं उठाना चाहिए joblib.dumpयदि आप इसे स्किटिट-लर्न लाइब्रेरी के एक ही संस्करण के साथ पायथन से कहते हैं।
ऑग्रेसेल

10
यदि आप IPython का उपयोग कर रहे हैं, तो --pylabकमांड लाइन के झंडे या %pylabजादू का उपयोग न करें, क्योंकि निहित नामस्थान ओवरलोडिंग को अचार बनाने की प्रक्रिया को तोड़ने के लिए जाना जाता है। %matplotlib inlineइसके बजाय स्पष्ट आयात और जादू का उपयोग करें।
ऑग्रेसेल

2
संदर्भ के लिए scikit-learn प्रलेखन देखें: scikit-learn.org/stable/tutorial/basic/…
user1448319

1
क्या पहले से सहेजे गए मॉडल को फिर से बनाना संभव है? विशेष रूप से SVC मॉडल?
उदय सावंत

108

आप जो खोज रहे हैं उसे स्केलेर शब्दों में मॉडल दृढ़ता कहा जाता है और इसे परिचय और मॉडल दृढ़ता खंडों में प्रलेखित किया जाता है ।

इसलिए आपने अपने क्लासिफायर को इनिशियलाइज़ किया है और इसे लंबे समय के लिए प्रशिक्षित किया है

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

इसके बाद आपके पास दो विकल्प हैं:

1) अचार का उपयोग करना

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) जोबलीब का उपयोग करना

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')

ऊपर दिए गए लिंक को पढ़ने के लिए एक बार और मददगार है


30

कई मामलों में, विशेष रूप से पाठ वर्गीकरण के साथ यह सिर्फ क्लासिफायर स्टोर करने के लिए पर्याप्त नहीं है, लेकिन आपको सदिशाइज़र को स्टोर करने की आवश्यकता होगी ताकि आप भविष्य में अपने इनपुट को वेक्टर कर सकें।

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

भविष्य के उपयोग के मामले:

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)

सदिशाइज़र को डंप करने से पहले, कोई सदिशाइज़र की stop_words_ संपत्ति को हटा सकता है:

vectorizer.stop_words_ = None

डंपिंग को और अधिक कुशल बनाने के लिए। इसके अलावा अगर आपका क्लासिफायर पैरामीटर विरल है (जैसा कि ज्यादातर टेक्स्ट वर्गीकरण उदाहरणों में) आप मापदंडों को घने से विरल में बदल सकते हैं जो मेमोरी खपत, लोडिंग और डंपिंग के मामले में बहुत बड़ा अंतर लाएगा। Sparsify द्वारा मॉडल:

clf.sparsify()

जो स्वचालित रूप से SGDClassifier के लिए काम करेगा, लेकिन यदि आप जानते हैं कि आपका मॉडल विरल है (clf.coef_ में बहुत सारे शून्य हैं) तो आप मैन्युअल रूप से clf.coef_ को सीएसआर स्किपी स्पार्स मैट्रिक्स में बदल सकते हैं :

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

और फिर आप इसे और अधिक कुशलता से स्टोर कर सकते हैं।


व्यावहारिक जवाब! बस एसवीसी के मामले में जोड़ना चाहता था, यह एक विरल मॉडल पैरामीटर देता है।
शयन अमानी

4

sklearnएक अनुमानक के प्रासंगिक प्रशिक्षित गुणों को बचाने के लिए अनुमानक आपके लिए आसान बनाने के तरीकों को लागू करते हैं। कुछ अनुमानक __getstate__स्वयं तरीकों को लागू करते हैं, लेकिन अन्य, जैसे कि GMMबस आधार कार्यान्वयन का उपयोग करते हैं जो केवल वस्तुओं को आंतरिक शब्दकोश में बचाता है:

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

अपने मॉडल को डिस्क में सहेजने के लिए अनुशंसित विधि pickleमॉड्यूल का उपयोग करना है:

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)

हालाँकि, आपको अतिरिक्त डेटा को सहेजना चाहिए ताकि आप भविष्य में अपने मॉडल को पुनः प्राप्त कर सकें, या गंभीर परिणाम भुगतें पड़ें (जैसे कि स्केलेर के पुराने संस्करण में बंद होना)

से प्रलेखन :

भविष्य के संस्करणों के साथ समान मॉडल के पुनर्निर्माण के लिए, अतिरिक्त मेटाडेटा को अचार वाले मॉडल के साथ सहेजा जाना चाहिए:

प्रशिक्षण डेटा, जैसे एक अपरिवर्तनीय स्नैपशॉट का संदर्भ

मॉडल उत्पन्न करने के लिए अजगर स्रोत कोड का उपयोग किया जाता है

स्किटिट-लर्न के संस्करण और इसकी निर्भरताएं

प्रशिक्षण डेटा पर प्राप्त क्रॉस सत्यापन स्कोर

यह एन्सेम्बल अनुमानकों के लिए विशेष रूप से सचtree.pyx है जो साइथन (जैसे IsolationForest) में लिखे गए मॉड्यूल पर भरोसा करते हैं , क्योंकि यह कार्यान्वयन के लिए एक युग्मन बनाता है, जो स्केलेर के संस्करणों के बीच स्थिर होने की गारंटी नहीं है। इसने अतीत में असंगत परिवर्तन देखे हैं।

यदि आपके मॉडल बहुत बड़े हो जाते हैं और लोडिंग एक उपद्रव बन जाता है, तो आप अधिक कुशल का उपयोग भी कर सकते हैं joblib। प्रलेखन से:

स्किकिट के विशिष्ट मामले में, जॉबलिब के प्रतिस्थापन pickle( joblib.dumpऔर joblib.load) का उपयोग करना अधिक दिलचस्प हो सकता है , जो उन वस्तुओं पर अधिक कुशल होता है जो आंतरिक रूप से बड़ी संख्या में कैरी लेती हैं जैसा कि अक्सर फिट किए गए स्किकिट-लर्न एस्टीमेटर्स के लिए होता है, लेकिन केवल अचार कर सकते हैं डिस्क और स्ट्रिंग के लिए नहीं:


1
but can only pickle to the disk and not to a stringलेकिन आप इसे स्टर्लिंगियो में जॉबलिब से चुन सकते हैं। यही मैं हर समय करता हूं।
मैथ्यू

1

sklearn.externals.joblibके बाद से 0.21हटा दिया गया है और इसमें हटा दिया जाएगा v0.23:

/usr/local/lib/python3.7/site-packages/sklearn/externals/joblib/ init .py: 15: FutureWarning: sklearn.externals.joblib 0.21 में पदावनत किया गया है और 0.23 में निकाल दिया जाएगा। कृपया इस कार्यक्षमता को सीधे जॉबलिब से आयात करें, जिसे इसके साथ स्थापित किया जा सकता है: जॉब को स्थापित करें। यदि यह चेतावनी अचार वाले मॉडलों को लोड करते समय उठाई जाती है, तो आपको उन मॉडलों को फिर से क्रमबद्ध करने की आवश्यकता हो सकती है जिनमें शिकंजा 0.21+ है।
चेतावनियाँ। संदेश (संदेश, श्रेणी = FutureWarning)


इसलिए, आपको स्थापित करने की आवश्यकता है joblib:

pip install joblib

और अंत में डिस्क पर मॉडल लिखें:

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)

अब डंप की गई फ़ाइल को पढ़ने के लिए आपको बस चलाने की ज़रूरत है:

with open('myClassifier.joblib.pkl', 'rb') as f:
    my_clf = joblib.load(f)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.