web-dev-qa-db-ja.com

PythonのScikitを使用して新しいコンテンツを予測するためのTFIDF結果を保持する

Python=でsklearnを使用してクラスタリングを行っています。200,000のデータをトレーニングしたので、以下のコードはうまく機能します。

corpus = open("token_from_xml.txt")
vectorizer = CountVectorizer(decode_error="replace")
transformer = TfidfTransformer()
tfidf = transformer.fit_transform(vectorizer.fit_transform(corpus))
km = KMeans(30)
kmresult = km.fit(tfidf).predict(tfidf)

しかし、新しいテストコンテンツがある場合は、トレーニングした既存のクラスターにクラスター化したいと思います。だから私はIDF結果を保存して、新しいテストコンテンツのTFIDFを実行し、新しいテストコンテンツの結果が同じ配列の長さであることを確認できるようにする方法を考えています。

前もって感謝します。

[〜#〜]更新[〜#〜]

"transformer"または "tfidf"変数をファイル(txtまたはその他)に保存する必要がある場合があります。それらの1つにトレーニング済みのIDF結果が含まれている場合です。

[〜#〜]更新[〜#〜]

例えば。トレーニングデータがあります。

["a", "b", "c"]
["a", "b", "d"]

TFIDFを実行すると、結果には4つの機能(a、b、c、d)が含まれます

私が[〜#〜] test [〜#〜]の場合:

["a", "c", "d"]

それが属するクラスター(すでにk-meansによって作成されている)を確認します。 TFIDFは3つの特徴(a、c、d)の結果のみを提供するため、k平均のクラスタリングは低下します。 (私がテストした場合["a", "b", "e"]、他の問題がある可能性があります。)

では、テストデータの機能リストを保存するには(さらに、ファイルに保存します)。

[〜#〜]更新[〜#〜]

解決しました。以下の回答を参照してください。

20
lol.Wen

_vectorizer.vocabulary__を保存して機能リストを正常に保存し、CountVectorizer(decode_error="replace",vocabulary=vectorizer.vocabulary_)で再利用しました

以下のコード:

_corpus = np.array(["aaa bbb ccc", "aaa bbb ddd"])
vectorizer = CountVectorizer(decode_error="replace")
vec_train = vectorizer.fit_transform(corpus)
#Save vectorizer.vocabulary_
pickle.dump(vectorizer.vocabulary_,open("feature.pkl","wb"))

#Load it later
transformer = TfidfTransformer()
loaded_vec = CountVectorizer(decode_error="replace",vocabulary=pickle.load(open("feature.pkl", "rb")))
tfidf = transformer.fit_transform(loaded_vec.fit_transform(np.array(["aaa ccc eee"])))
_

うまくいきます。 tfidfは、学習済みデータと同じ特徴の長さを持ちます。

17
lol.Wen

今後使用するテストデータの機能リストを保存する場合は、次のようにします。

tfidf = transformer.fit_transform(vectorizer.fit_transform(corpus))

#store the content
with open("x_result.pkl", 'wb') as handle:
                    pickle.dump(tfidf, handle)
#load the content
tfidf = pickle.load(open("x_result.pkl", "rb" ) )
7
user123

CountVectorizerを使用して語彙を格納する代わりに、tfidfvectorizerの語彙を直接使用できます。

トレーニング段階:

from sklearn.feature_extraction.text import TfidfVectorizer

# tf-idf based vectors
tf = TfidfVectorizer(analyzer='Word', ngram_range=(1,2), stop_words = "english", lowercase = True, max_features = 500000)

# Fit the model
tf_transformer = tf.fit(corpus)

# Dump the file
pickle.dump(tf_transformer, open("tfidf1.pkl", "wb"))


# Testing phase
tf1 = pickle.load(open("tfidf1.pkl", 'rb'))

# Create new tfidfVectorizer with old vocabulary
tf1_new = TfidfVectorizer(analyzer='Word', ngram_range=(1,2), stop_words = "english", lowercase = True,
                          max_features = 500000, vocabulary = tf1.vocabulary_)
X_tf1 = tf1_new.fit_transform(new_corpus)

古いボキャブラリーを使用しているため、ここでfit_transformが機能します。 tfidfを保存していない場合は、テストデータに対して変換を使用しただけです。そこで変換を行っている場合でも、テストデータからの新しいドキュメントは、トレインのベクトライザーの語彙に「適合」しています。それがまさにここで行っていることです。保存してtfidfベクトライザーで再利用できるのは、語彙だけです。

2
Arjun Mishra

より簡単な解決策は、 document が言っているように、joblibライブラリを使用するだけです。

from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.externals import joblib

vectorizer = CountVectorizer()
X = vectorizer.fit_transform(texts)
feature_name = vectorizer.get_feature_names()
tfidf = TfidfTransformer()
tfidf.fit(X)

# save your model in disk
joblib.dump(transformer, 'tfidf.pkl') 

# load your model
tfidf = joblib.load('tfidf.pkl') 
1
GoatWang

ベクトル化とtfidf変換を1つの段階で実行できます。

vec =TfidfVectorizer()

次に、トレーニングデータに合わせて変換します

tfidf = vec.fit_transform(training_data)

そしてtfidfモデルを使用して変換します

unseen_tfidf = vec.transform(unseen_data)
km = KMeans(30)
kmresult = km.fit(tfidf).predict(unseen_tfid)
1
JAB