提问者:小点点

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


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

我收到以下错误“sklearn.exceptions.NotFitteError:CountVectorier-词汇表未安装。”我需要重新拟合数据吗?我本以为能够保存模型的意义在于不必这样做。

下面是我使用的代码,不包括数据清理部分。任何有助于实现预测的帮助都将不胜感激。

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)

共2个答案

匿名用户

您的培训部分有3个部分与数据相匹配:

>

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

    tfidfTransform:学习前一部分的词汇表计数,并返回tfidf

    逻辑回归:学习特征的系数,以获得最佳分类性能。

    由于每个部分都在学习有关数据的知识并使用它输出转换后的数据,因此在测试新数据时,您需要拥有所有3个部分。但是,您仅使用joblib保存lr,因此其他两个将丢失,并随之丢失培训数据词汇表和计数。

    现在,在测试部分,您正在初始化新的CountVectorizerTfidfTransformer,并调用fit()fit\u 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和逻辑回归,以便您只需使用单个对象(这更容易保存和加载以及通用处理)。

    所以像这样编辑训练部分:

    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)
    

  • 匿名用户

    您没有安装CountVectorzer。

    你应该这样做。。

    cvec = CountVectorizer()
    x_val_vec = cvec.fit_transform(new_x)
    

    类似地,TfidTransformer必须这样使用。。

    X_val_tfidf = tfidf_transformer.fit_transform(x_val_vec)