Сохранить результат TFIDF для прогнозирования нового контента с помощью Scikit для Python

Я использую sklearn на Python для выполнения некоторой кластеризации. Я обучил 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 или другие), если один из них содержит обученный результат IDF.

обновление

например. У меня есть данные:

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

и сделать TFIDF, результат будет содержать 4 функции (a,b,c,d)

Когда Я тест:

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

чтобы увидеть, какой кластер (уже сделанный k-means) это принадлежать. TFIDF даст результат только с 3 функциями (a,c, d), поэтому кластеризация в k-средних будет падать. (Если я проверю ["a", "b", "e"], могут быть и другие проблемы.)

Итак, как сохранить список функций для тестирования данных (более того, сохранить его в файле)?

обновление

решено, см. ответы ниже.

5 ответов


Я успешно сохранил список функций, сохранив 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 будет иметь ту же длину функции, что и обученные данные.


Если вы хотите сохранить список функций для тестирования данных для использования в будущем, вы можете сделать это:

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

вы можете сделать векторизацию и преобразование tfidf в один этап:

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)

более простое решение, просто используйте joblib libarary как документ сказал:

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

вместо того, чтобы использовать 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, вы бы просто использовали transform для тестовых данных. Даже когда вы выполняете преобразование, новые документы из тестовых данных "вписываются" в словарь векторизатора поезда. Что именно этим мы здесь и занимаемся. Единственное, что мы можем хранить и повторно использовать для векторизатора tfidf,-это словарь.