web-dev-qa-db-ja.com

scikit-learnで将来使用するためにTfidfVectorizerを保存するにはどうすればよいですか?

記事のコレクションとそれに続く特徴選択をベクトル化するTfidfVectorizerがあります。

_vectroizer = TfidfVectorizer()
X_train = vectroizer.fit_transform(corpus)
selector = SelectKBest(chi2, k = 5000 )
X_train_sel = selector.fit_transform(X_train, y_train)
_

これを保存して、他のプログラムで使用したいと思います。トレーニングデータセットでTfidfVectorizer()と機能セレクターを再実行したくありません。それ、どうやったら出来るの? joblibを使用してモデルを永続化する方法は知っていますが、これはモデルを永続化するのと同じかどうか疑問に思います。

16
user2161903

組み込みのpicklelibを使用するだけです。

pickle.dump(vectorizer, open("vectorizer.pickle", "wb"))
pickle.dump(selector, open("selector.pickle", "wb"))

そしてそれをロードします:

vectorizer = pickle.load(open("vectorizer.pickle"), "rb"))
selector = pickle.load(open("selector.pickle"), "rb"))

Pickleはオブジェクトをディスクにシリアル化し、必要なときに再度メモリにロードします

pickle lib docs

11
Marco Ferragina

「オブジェクトを永続化する」とは、基本的に、メモリに格納されている、オブジェクトを表すバイナリコードをハードドライブ上のファイルにダンプすることを意味します。これにより、後でプログラムまたは他のプログラムでオブジェクトを作成できます。ハードドライブ内のファイルからメモリにリロードされました。

Scikit-learnに含まれるjoblibまたはstdlibpicklecPickleのいずれかがその役割を果たします。私はcPickleを使用する傾向があります。 ipythonの%timeitコマンド の使用:

>>> from sklearn.feature_extraction.text import TfidfVectorizer as TFIDF
>>> t = TFIDF()
>>> t.fit_transform(['hello world'], ['this is a test'])

# generic serializer - deserializer test
>>> def dump_load_test(tfidf, serializer):
...:    with open('vectorizer.bin', 'w') as f:
...:        serializer.dump(tfidf, f)
...:    with open('vectorizer.bin', 'r') as f:
...:        return serializer.load(f)

# joblib has a slightly different interface
>>> def joblib_test(tfidf):
...:    joblib.dump(tfidf, 'tfidf.bin')
...:    return joblib.load('tfidf.bin')

# Now, time it!
>>> %timeit joblib_test(t)
100 loops, best of 3: 3.09 ms per loop

>>> %timeit dump_load_test(t, pickle)
100 loops, best of 3: 2.16 ms per loop

>>> %timeit dump_load_test(t, cPickle)
1000 loops, best of 3: 879 µs per loop

複数のオブジェクトを1つのファイルに保存する場合は、データ構造を簡単に作成して保存し、データ構造自体をダンプできます。これは、Tuplelist、またはdictで機能します。あなたの質問の例から:

# train
vectorizer = TfidfVectorizer()
X_train = vectorizer.fit_transform(corpus)
selector = SelectKBest(chi2, k = 5000 )
X_train_sel = selector.fit_transform(X_train, y_train)

# dump as a dict
data_struct = {'vectorizer': vectorizer, 'selector': selector}
# use the 'with' keyword to automatically close the file after the dump
with open('storage.bin', 'wb') as f: 
    cPickle.dump(data_struct, f)

後でまたは別のプログラムで、次のステートメントは、プログラムのメモリにデータ構造を戻します。

# reload
with open('storage.bin', 'rb') as f:
    data_struct = cPickle.load(f)
    vectorizer, selector = data_struct['vectorizer'], data_struct['selector']

# do stuff...
vectors = vectorizer.transform(...)
vec_sel = selector.transform(vectors)
6
Romain G

これがjoblibを使った私の答えです:

joblib.dump(vectorizer, 'vectroizer.pkl')
joblib.dump(selector, 'selector.pkl')

後で、ロードして準備ができました。

vectorizer = joblib.load('vectorizer.pkl')
selector = joblib.load('selector.pkl')

test = selector.trasnform(vectorizer.transform(['this is test']))
5
user2161903