问题描述
我已经能够制作 MultinomialNB 分类器并将其保存到 pickle 文件中以备后用(归功于 youtube 视频:https://www.youtube.com/watch?v=0kPRaYSgblM&t=927s 以及更多)。下面是我的代码:
import sklearn.datasets as skd
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
import pickle
categories = ['alt.atheism','soc.religion.christian','comp.graphics','sci.med']
train_data = skd.load_files('E:/Python/Datasets/train',categories=categories,encoding='ISO-8859-1')
test_data = skd.load_files('E:/Python/Datasets/test',encoding='ISO-8859-1')
tf_vect = TfidfVectorizer()
tfidf_train = tf_vect.fit_transform(train_data.data)
clf = MultinomialNB().fit(tfidf_train,train_data.target)
with open('classifier','wb') as picklefile:
pickle.dump(clf,picklefile)
现在在一个单独的代码文件中,我可以将它读回到一个新变量“new_clf”中,以便将此分类器与新文本数据一起使用:
import pickle
with open('E:\Python\Text Classification\classifier','rb') as tm:
new_clf = pickle.load(tm)
现在,如果我直接运行了之前的文件/代码并从中获得了 tf_vect 变量,该变量已经将我的训练数据装入其中,我可以简单地转换其上的新文本集并将其传递给 new_clf 分类器获取预测。
但在我的情况下,一旦模型经过训练,我想将其发送给另一个用户,该用户将拥有一个单独的代码文件,该文件必须读取分类器,然后将新文本传递给它进行预测。
我在这里遇到的问题是下面的代码(以 ValueError 结尾:维度不匹配):-
new_text = ['God is love','OpenGL is fast on GPU']
new_clf.predict(new_text)
我知道我没有根据训练数据的特征来转换 new_text。但我不知道如何解决它。
我应该创建另一个包含 tf_vect 的 pickle 文件并与用户共享吗?或者它已经与分类器文件本身一起使用,而我错过了从分类器获取它的过程?
解决方法
您确实可以保存两个泡菜文件,一个用于矢量化器,一个用于分类器。但是,对此最方便和推荐的解决方案是将向量化器和分类器合并为一个 Pipeline
对象,然后您可以对其进行pickle。
from sklearn.pipeline import Pipeline
tf_vect = TfidfVectorizer()
clf = MultinomialNB()
pipe = Pipeline([("vectorizer",tf_vect),("classifier",clf)])
pipe.fit(train_data.data,train_data.target)
with open('classifier','wb') as picklefile:
pickle.dump(pipe,picklefile)
一旦你加载了那个pickle文件,你就可以像这样使用新文本:
with open('/.../classifier','rb') as tm:
new_pipe = pickle.load(tm)
new_pipe.predict(new_text)