Lưu phân loại vào đĩa trong scikit-learn


191

Làm cách nào để lưu trình phân loại Naive Bayes đã đào tạo vào đĩa và sử dụng nó để dự đoán dữ liệu?

Tôi có chương trình mẫu sau từ trang web 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()

Câu trả lời:


201

Phân loại chỉ là các đối tượng có thể được ngâm và đổ như bất kỳ khác. Để tiếp tục ví dụ của bạn:

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
Hoạt động như một lá bùa! Tôi đã cố gắng sử dụng np.savez và tải lại tất cả cùng và điều đó không bao giờ giúp được. Cảm ơn rất nhiều.
Kartos

7
trong python3, sử dụng mô-đun dưa, hoạt động chính xác như thế này.
MCSH

212

Bạn cũng có thể sử dụng joblib.dumpjoblib.load hiệu quả hơn nhiều trong việc xử lý các mảng số so với trình chọn python mặc định.

Joblib được bao gồm trong scikit-learn:

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

Chỉnh sửa: trong Python 3.8+ giờ đây có thể sử dụng pickle để chọn đối tượng hiệu quả với các mảng số lớn làm thuộc tính nếu bạn sử dụng giao thức Pickle 5 (không phải là mặc định).


1
Nhưng từ sự hiểu biết của tôi, đường ống hoạt động nếu là một phần của một luồng công việc duy nhất. Nếu tôi muốn xây dựng mô hình lưu trữ nó trên đĩa và dừng việc thực hiện ở đó. Sau đó, tôi trở lại một tuần sau đó và thử tải mô hình từ đĩa, nó sẽ báo lỗi cho tôi:
venuktan

2
Không có cách nào để dừng và tiếp tục thực hiện fitphương thức nếu đây là điều bạn đang tìm kiếm. Điều đó đang được nói, joblib.loadkhông nên đưa ra một ngoại lệ sau khi thành công joblib.dumpnếu bạn gọi nó từ Python với cùng một phiên bản của thư viện scikit-learn.
ogrisel

10
Nếu bạn đang sử dụng IPython, không sử dụng --pylabcờ dòng lệnh hoặc %pylabphép thuật vì quá tải không gian tên ẩn được biết là phá vỡ quy trình tẩy. Sử dụng nhập khẩu rõ ràng và %matplotlib inlinephép thuật thay thế.
ogrisel

2
xem tài liệu scikit-learn để tham khảo: scikit-learn.org/urdy/tutorial/basic/ mẹo
user1448319

1
Có thể đào tạo lại mô hình đã lưu trước đó? Cụ thể mô hình SVC?
Uday Sawant

108

Những gì bạn đang tìm kiếm được gọi là Sự kiên trì của mô hình trong các từ sklearn và nó được ghi lại trong phần giới thiệu và trong các phần kiên trì mô hình .

Vì vậy, bạn đã khởi tạo trình phân loại của mình và đào tạo nó trong một thời gian dài với

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

Sau này, bạn có hai lựa chọn:

1) Sử dụng dưa chua

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) Sử dụng công việc

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

Một lần nữa rất hữu ích để đọc các liên kết được đề cập ở trên


30

Trong nhiều trường hợp, đặc biệt với phân loại văn bản, việc lưu trữ trình phân loại là không đủ nhưng bạn cũng cần lưu trữ trình tạo vector để bạn có thể vector hóa đầu vào của mình trong tương lai.

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

trường hợp sử dụng trong tương lai:

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)

Trước khi bỏ vectorizer, người ta có thể xóa thuộc tính stop_words_ của vectorizer bằng cách:

vectorizer.stop_words_ = None

để bán phá giá hiệu quả hơn. Ngoài ra nếu các tham số phân loại của bạn thưa thớt (như trong hầu hết các ví dụ phân loại văn bản), bạn có thể chuyển đổi các tham số từ dày đặc sang thưa thớt, điều này sẽ tạo ra sự khác biệt lớn về mức tiêu thụ bộ nhớ, tải và đổ. Phát triển mô hình bằng cách:

clf.sparsify()

Nó sẽ tự động hoạt động cho SGDClassifier nhưng trong trường hợp bạn biết mô hình của mình thưa thớt (rất nhiều số không trong clf.coef_) thì bạn có thể chuyển đổi thủ công clf.coef_ thành ma trận thưa thớt csr bằng cách:

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

và sau đó bạn có thể lưu trữ nó hiệu quả hơn.


Câu trả lời sâu sắc! Chỉ muốn thêm vào trong trường hợp SVC, nó trả về một tham số mô hình thưa thớt.
Shaya Amani

4

sklearncông cụ ước tính thực hiện các phương pháp để giúp bạn dễ dàng lưu các thuộc tính được đào tạo có liên quan của công cụ ước tính. Một số công cụ ước tính tự thực hiện __getstate__các phương thức, nhưng một số khác, như GMMchỉ sử dụng triển khai cơ sở chỉ đơn giản là lưu các từ điển bên trong các đối tượng:

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

Phương pháp được đề xuất để lưu mô hình của bạn vào đĩa là sử dụng picklemô-đun:

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)

Tuy nhiên, bạn nên lưu dữ liệu bổ sung để bạn có thể đào tạo lại mô hình của mình trong tương lai hoặc chịu hậu quả nghiêm trọng (chẳng hạn như bị khóa trong phiên bản cũ của sklearn) .

Từ tài liệu :

Để xây dựng lại một mô hình tương tự với các phiên bản tương lai của scikit-learn, siêu dữ liệu bổ sung phải được lưu cùng với mô hình ngâm:

Dữ liệu đào tạo, ví dụ như tham chiếu đến ảnh chụp nhanh bất biến

Mã nguồn python được sử dụng để tạo mô hình

Các phiên bản của scikit-learn và các phụ thuộc của nó

Điểm xác nhận chéo thu được trên dữ liệu đào tạo

Điều này đặc biệt đúng đối với các công cụ ước tính của Bộ đồng phục dựa trên tree.pyxmô-đun được viết bằng Cython (chẳng hạn như IsolationForest), vì nó tạo ra một khớp nối với việc triển khai, không được đảm bảo ổn định giữa các phiên bản của sklearn. Nó đã thấy những thay đổi ngược không tương thích trong quá khứ.

Nếu mô hình của bạn trở nên rất lớn và tải trở nên phiền toái, bạn cũng có thể sử dụng hiệu quả hơn joblib. Từ tài liệu:

Trong trường hợp cụ thể của scikit, có thể thú vị hơn khi sử dụng thay thế pickle( joblib.dump& joblib.load) của joblib , hiệu quả hơn đối với các đối tượng mang các mảng numpy lớn trong nội bộ như thường được sử dụng cho các công cụ ước tính tìm hiểu scikit, nhưng chỉ có thể chọn vào đĩa và không vào chuỗi:


1
but can only pickle to the disk and not to a stringNhưng bạn có thể chọn cái này vào StringIO từ joblib. Đây là những gì tôi làm tất cả các thời gian.
Matthew

1

sklearn.externals.joblibđã bị từ chối0.21 và sẽ bị xóa trong v0.23:

/usr/local/lib/python3.7/site-packages/sklearn/externals/joblib/ init .py: 15: FutureWarning: sklearn.externals.joblib bị phản đối trong 0,21 và sẽ bị xóa trong 0,23. Vui lòng nhập chức năng này trực tiếp từ joblib, có thể được cài đặt với: pip install joblib. Nếu cảnh báo này được đưa ra khi tải các mô hình ngâm, bạn có thể cần phải tuần tự hóa lại các mô hình đó với scikit-learn 0.21+.
warnings.warn (tin nhắn, danh mục = FutureWarning)


Do đó, bạn cần cài đặt joblib:

pip install joblib

và cuối cùng ghi mô hình vào đĩa:

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)

Bây giờ để đọc tệp bị đổ, tất cả những gì bạn cần chạy là:

with open('myClassifier.joblib.pkl', 'rb') as f:
    my_clf = joblib.load(f)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.