保留 TFIDF 结果以使用 Scikit 预测新内容 Python
Keep TFIDF result for predicting new content using Scikit for Python
我在 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 或其他文件),如果其中一个包含经过训练的 IDF 结果。
更新
例如。我有训练数据:
["a", "b", "c"]
["a", "b", "d"]
然后做TFIDF,结果会包含4个特征(a,b,c,d)
当我测试时:
["a", "c", "d"]
看看它属于哪个集群(已经用k-means做了)。 TFIDF 只会给出具有 3 个特征(a、c、d)的结果,因此 k-means 中的聚类会下降。 (如果我测试["a", "b", "e"]
,可能还有其他问题。)
那么如何存储测试数据的特征列表(更进一步,存储在文件中)?
更新
已解决,请参阅下面的答案。
您可以在一个阶段进行矢量化和 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)
如果您想存储特征列表以供将来使用的测试数据,您可以这样做:
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" ) )
我通过保存 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
将具有与训练数据相同的特征长度。
一个更简单的解决方案,只需使用 joblib 库,如 document 所说:
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')
不使用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,您将只对测试数据使用转换。即使您在那里进行转换,来自测试数据的新文档也会 "fit" 到火车矢量化器的词汇表中。这正是我们在这里所做的。我们唯一可以为 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 或其他文件),如果其中一个包含经过训练的 IDF 结果。
更新
例如。我有训练数据:
["a", "b", "c"]
["a", "b", "d"]
然后做TFIDF,结果会包含4个特征(a,b,c,d)
当我测试时:
["a", "c", "d"]
看看它属于哪个集群(已经用k-means做了)。 TFIDF 只会给出具有 3 个特征(a、c、d)的结果,因此 k-means 中的聚类会下降。 (如果我测试["a", "b", "e"]
,可能还有其他问题。)
那么如何存储测试数据的特征列表(更进一步,存储在文件中)?
更新
已解决,请参阅下面的答案。
您可以在一个阶段进行矢量化和 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)
如果您想存储特征列表以供将来使用的测试数据,您可以这样做:
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" ) )
我通过保存 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
将具有与训练数据相同的特征长度。
一个更简单的解决方案,只需使用 joblib 库,如 document 所说:
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')
不使用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,您将只对测试数据使用转换。即使您在那里进行转换,来自测试数据的新文档也会 "fit" 到火车矢量化器的词汇表中。这正是我们在这里所做的。我们唯一可以为 tfidf 向量化器存储和重用的是词汇表。