保留TFIDF结果,以便使用Scikit for Python预测新内容



我在Python上使用sklearn来进行一些集群。我已经训练了200000个数据,下面的代码运行良好。

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,并确保新测试内容的结果具有相同的数组长度

提前谢谢。

更新

如果其中一个变量包含经过训练的IDF结果,我可能需要将"transformer"或"tfidf"变量保存到文件(txt或其他文件)中。

更新

例如。我有训练数据:

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

并且做TFIDF,结果将包含4个特征(a,b,c,d)

当I测试时:

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

看看它属于哪个聚类(已经通过k-means生成)。TFIDF只会给出具有3个特征(a,c,d)的结果,所以k-means中的聚类会下降。(如果我测试["a", "b", "e"],可能会有其他问题。)

那么,如何存储测试数据的特性列表(更重要的是,将其存储在文件中)?

更新

已解决,请参阅下面的答案。

我通过保存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将具有与训练数据相同的特征长度。

可以直接使用tfidfvectorizer的词汇表,而不是使用CountVectorizer来存储词汇表。

培训阶段:

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矢量器,我们唯一可以存储和重用的就是词汇表。

如果您想存储功能列表以供将来使用的测试数据,您可以这样做:

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

一个更简单的解决方案,只需使用joblib-libarry作为文档说明:

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(tfidf, 'tfidf.pkl') 
# load your model
tfidf = joblib.load('tfidf.pkl') 

您可以在一个阶段中进行矢量化和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)

相关内容

  • 没有找到相关文章

最新更新