使用保存的 sklearn 模型进行预测

dmn*_*nte 2 python numpy pandas scikit-learn logistic-regression

我有一个保存的逻辑回归模型,我用训练数据训练它并使用 joblib 保存。我试图在不同的脚本中加载这个模型,向它传递新数据并根据新数据进行预测。

我收到以下错误“sklearn.exceptions.NotFittedError: CountVectorizer - Vocabulary is not fit”。我需要再次拟合数据吗?我原以为能够保存模型的重点是不必这样做。

我使用的代码如下,不包括数据清理部分。任何帮助预测工作将不胜感激。

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)
Run Code Online (Sandbox Code Playgroud)

Viv*_*mar 5

您的训练部分有 3 个拟合数据的部分:

  • CountVectorizer:学习训练数据的词汇并返回计数

  • TfidfTransformer: 学习上一部分的词汇数,并返回 tfidf

  • LogisticRegression:学习特征系数以获得最佳分类性能。

由于每个部分都在学习有关数据的一些信息并使用它来输出转换后的数据,因此在测试新数据时需要拥有所有 3 个部分。但你只是在保存lrwith joblib,因此其他两个丢失了,并且丢失了训练数据词汇和计数。

现在在您的测试部分,您正在初始化 newCountVectorizerTfidfTransformer,并调用fit()( fit_transform()),它将仅从这些新数据中学习词汇。所以字数会少于训练字数。但是随后您加载了之前保存的 LR 模型,该模型根据训练数据等特征期望数据。因此这个错误:

ValueError: X has 130 features per sample; expecting 223086
Run Code Online (Sandbox Code Playgroud)

你需要做的是:

在训练中:

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)
Run Code Online (Sandbox Code Playgroud)

测试期间

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)
Run Code Online (Sandbox Code Playgroud)

现在你不会得到那个错误。

推荐:

你应该使用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)
Run Code Online (Sandbox Code Playgroud)

在测试期间,请执行以下操作:

loaded_pipe = joblib.load("finalized_model.sav")
result = loaded_model.predict(new_x)
Run Code Online (Sandbox Code Playgroud)