我有一个保存的逻辑回归模型,该模型通过训练数据进行了训练,并使用joblib进行了保存。我正在尝试将此模型加载到其他脚本中,将其传递给新数据,并根据新数据进行预测。
我收到以下错误“ sklearn.exceptions.NotFittedError:CountVectorizer-词汇不正确。”我是否需要再次拟合数据?我本以为能够保存模型的目的是不必这样做。
下面使用的代码不包括数据清除部分。任何有助于使预测生效的帮助。
new_df = pd.DataFrame(latest_tweets,columns=['text'])
new_df.to_csv('new_tweet.csv',encoding='utf-8')
csv = 'new_tweet.csv'
latest_df = pd.read_csv(csv)
latest_df.dropna(inplace=True)
latest_df.reset_index(drop=True,inplace=True)
new_x = latest_df.text
loaded_model = joblib.load("finalized_mode.sav")
tfidf_transformer = TfidfTransformer()
cvec = CountVectorizer()
x_val_vec = cvec.transform(new_x)
X_val_tfidf = tfidf_transformer.transform(x_val_vec)
result = loaded_model.predict(X_val_tfidf)
print (result)
答案 0 :(得分:1)
您还没有fit
CountVectorizer。
您应该这样做。.
cvec = CountVectorizer()
x_val_vec = cvec.fit_transform(new_x)
类似地,必须像这样使用TfidTransformer
。
X_val_tfidf = tfidf_transformer.fit_transform(x_val_vec)
答案 1 :(得分:1)
您的训练部分包括3个适合数据的部分:
CountVectorizer
:学习训练数据的词汇并返回计数
TfidfTransformer
:从上一部分学习词汇计数,然后返回tfidf
LogisticRegression
:了解要素的系数,以实现最佳分类性能。
由于每个部分都在学习有关数据的知识,并使用它来输出转换后的数据,因此在测试新数据时,您需要具有全部三个部分。但是您只用joblib保存lr
,所以其他两个丢失了,训练数据的词汇和计数也丢失了。
现在在测试部分,您将初始化新的CountVectorizer
和TfidfTransformer
,然后调用fit()
(fit_transform()
),这将仅从此新数据中学习词汇。因此,单词将少于训练单词。但是随后您加载了先前保存的LR模型,该模型根据训练数据等功能期望数据。因此出现此错误:
ValueError: X has 130 features per sample; expecting 223086
您需要做的是这样
filename = 'finalized_model.sav'
joblib.dump(lr, filename)
filename = 'finalized_countvectorizer.sav'
joblib.dump(cvec, filename)
filename = 'finalized_tfidftransformer.sav'
joblib.dump(tfidf_transformer, filename)
loaded_model = joblib.load("finalized_model.sav")
loaded_cvec = joblib.load("finalized_countvectorizer.sav")
loaded_tfidf_transformer = joblib.load("finalized_tfidftransformer.sav")
# Observe that I only use transform(), not fit_transform()
x_val_vec = loaded_cvec.transform(new_x)
X_val_tfidf = loaded_tfidf_transformer.transform(x_val_vec)
result = loaded_model.predict(X_val_tfidf)
现在您不会收到该错误。
您应该使用TfidfVectorizer代替CountVectorizer和TfidfTransformer,这样您就不必一直使用两个对象。
与此同时,您还应该使用Pipeline结合两个步骤:-TfidfVectorizer和LogisticRegression,因此您只需要使用一个对象(这样就更易于保存和加载以及通用处理)。
因此,像这样编辑培训部分:
tfidf_vectorizer = TfidfVectorizer()
lr = LogisticRegression()
tfidf_lr_pipe = Pipeline([('tfidf', tfidf_vectorizer), ('lr', lr)])
# Internally your X_train will be automatically converted to tfidf
# and that will be passed to lr
tfidf_lr_pipe.fit(X_train, y_train)
# Similarly here only transform() will be called internally for tfidfvectorizer
# And that data will be passed to lr.predict()
y_preds = tfidf_lr_pipe.predict(x_test)
# Now you can save this pipeline alone (which will save all its internal parts)
filename = 'finalized_model.sav'
joblib.dump(tfidf_lr_pipe, filename)
在测试过程中,请执行以下操作:
loaded_pipe = joblib.load("finalized_model.sav")
result = loaded_model.predict(new_x)