'idf vector is not fitted' 使用保存的 classifier/model 时出错
'idf vector is not fitted' error when using a saved classifier/model
请原谅我使用了错误的术语,但我想要的是训练一组数据(使用 Scikit Learn 的 GaussianNB 朴素贝叶斯),保存 model/classifier,然后在需要时加载它并进行预测一个类别。
from sklearn.externals import joblib
from sklearn.naive_bayes import GaussianNB
from sklearn.feature_extraction.text import TfidfVectorizer
self.vectorizer = TfidfVectorizer(decode_error='ignore')
self.X_train_tfidf = self.vectorizer.fit_transform(train_data)
# Fit the model to my training data
self.clf = self.gnb.fit(self.X_train_tfidf.toarray(), category)
# Save the classifier to file
joblib.dump(self.clf, 'trained/NB_Model.pkl')
# Save the vocabulary to file
joblib.dump(self.vectorizer.vocabulary_, 'trained/vectorizer_vocab.pkl')
#Next time, I read the saved classifier
self.clf = joblib.load('trained/NB_Model.pkl')
# Read the saved vocabulary
self.vocab =joblib.load('trained/vectorizer_vocab.pkl')
# Initializer the vectorizer
self.vectorizer = TfidfVectorizer(vocabulary=self.vocab, decode_error='ignore')
# Try to predict a category for new data
X_new_tfidf = self.vectorizer.transform(new_data)
print self.clf.predict(X_new_tfidf.toarray())
# After running the predict command above, I get the error
'idf vector is not fitted'
谁能告诉我我错过了什么?
注:模型的保存、保存模型的读取和尝试预测一个新的类别都是一个class的不同方法。为了便于阅读,我已将它们全部折叠到一个屏幕中。
谢谢
您需要 pickle self.vectorizer
并重新加载。目前您只保存矢量化器学习的词汇。
更改程序中的以下行:
joblib.dump(self.vectorizer.vocabulary_, 'trained/vectorizer_vocab.pkl')
至:
joblib.dump(self.vectorizer, 'trained/vectorizer.pkl')
以及以下行:
self.vocab =joblib.load('trained/vectorizer_vocab.pkl')
至:
self.vectorizer =joblib.load('trained/vectorizer.pkl')
删除这一行:
self.vectorizer = TfidfVectorizer(vocabulary=self.vocab, decode_error='ignore')
问题解释:
你的想法是正确的,只是把学过的词汇保存下来再利用。但是 scikit-learn TfidfVectorizer 也有 idf_
属性,其中包含保存的词汇表的 IDF。所以你也需要保存它。但是,即使您将两者都保存并在新的 TfidfVectorizer 实例中加载它们,您也会收到 "not_fitted" 错误。因为这正是大多数 scikit 转换器和估算器的定义方式。因此,不做任何事情 "hacky" 保存整个矢量化器是最好的选择。如果您仍想继续保存词汇路径,请在此处查看如何正确执行此操作:
上面的页面将vocabulary
保存到json,将idf_
保存到一个简单的数组中。您可以在那里使用泡菜,但您会了解 TfidfVectorizer 的工作原理。
希望对您有所帮助。
请原谅我使用了错误的术语,但我想要的是训练一组数据(使用 Scikit Learn 的 GaussianNB 朴素贝叶斯),保存 model/classifier,然后在需要时加载它并进行预测一个类别。
from sklearn.externals import joblib
from sklearn.naive_bayes import GaussianNB
from sklearn.feature_extraction.text import TfidfVectorizer
self.vectorizer = TfidfVectorizer(decode_error='ignore')
self.X_train_tfidf = self.vectorizer.fit_transform(train_data)
# Fit the model to my training data
self.clf = self.gnb.fit(self.X_train_tfidf.toarray(), category)
# Save the classifier to file
joblib.dump(self.clf, 'trained/NB_Model.pkl')
# Save the vocabulary to file
joblib.dump(self.vectorizer.vocabulary_, 'trained/vectorizer_vocab.pkl')
#Next time, I read the saved classifier
self.clf = joblib.load('trained/NB_Model.pkl')
# Read the saved vocabulary
self.vocab =joblib.load('trained/vectorizer_vocab.pkl')
# Initializer the vectorizer
self.vectorizer = TfidfVectorizer(vocabulary=self.vocab, decode_error='ignore')
# Try to predict a category for new data
X_new_tfidf = self.vectorizer.transform(new_data)
print self.clf.predict(X_new_tfidf.toarray())
# After running the predict command above, I get the error
'idf vector is not fitted'
谁能告诉我我错过了什么?
注:模型的保存、保存模型的读取和尝试预测一个新的类别都是一个class的不同方法。为了便于阅读,我已将它们全部折叠到一个屏幕中。
谢谢
您需要 pickle self.vectorizer
并重新加载。目前您只保存矢量化器学习的词汇。
更改程序中的以下行:
joblib.dump(self.vectorizer.vocabulary_, 'trained/vectorizer_vocab.pkl')
至:
joblib.dump(self.vectorizer, 'trained/vectorizer.pkl')
以及以下行:
self.vocab =joblib.load('trained/vectorizer_vocab.pkl')
至:
self.vectorizer =joblib.load('trained/vectorizer.pkl')
删除这一行:
self.vectorizer = TfidfVectorizer(vocabulary=self.vocab, decode_error='ignore')
问题解释:
你的想法是正确的,只是把学过的词汇保存下来再利用。但是 scikit-learn TfidfVectorizer 也有 idf_
属性,其中包含保存的词汇表的 IDF。所以你也需要保存它。但是,即使您将两者都保存并在新的 TfidfVectorizer 实例中加载它们,您也会收到 "not_fitted" 错误。因为这正是大多数 scikit 转换器和估算器的定义方式。因此,不做任何事情 "hacky" 保存整个矢量化器是最好的选择。如果您仍想继续保存词汇路径,请在此处查看如何正确执行此操作:
上面的页面将vocabulary
保存到json,将idf_
保存到一个简单的数组中。您可以在那里使用泡菜,但您会了解 TfidfVectorizer 的工作原理。
希望对您有所帮助。