将模型保存以供后续预测(OneVsRest)。

3
我想知道如何保存OnevsRest分类器模型以备后续预测。
由于需要保存向量化器,因此我在保存时遇到了问题。我已经在这篇文章中学习过。
以下是我创建的模型:
from sklearn.feature_extraction.text import TfidfVectorizer
vectorizer = TfidfVectorizer(strip_accents='unicode', analyzer='word', ngram_range=(1,3), norm='l2')
vectorizer.fit(train_text)
vectorizer.fit(test_text)

x_train = vectorizer.transform(train_text)
y_train = train.drop(labels = ['id','comment_text'], axis=1)

x_test = vectorizer.transform(test_text)
y_test = test.drop(labels = ['id','comment_text'], axis=1)


from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
from sklearn.metrics import accuracy_score
from sklearn.multiclass import OneVsRestClassifier

%%time

# Using pipeline for applying logistic regression and one vs rest classifier
LogReg_pipeline = Pipeline([
                ('clf', OneVsRestClassifier(LogisticRegression(solver='sag'), n_jobs=-1)),
            ])

for category in categories:
    printmd('**Processing {} comments...**'.format(category))

    # Training logistic regression model on train data
    LogReg_pipeline.fit(x_train, train[category])

    # calculating test accuracy
    prediction = LogReg_pipeline.predict(x_test)
    print('Test accuracy is {}'.format(accuracy_score(test[category], prediction)))
    print("\n") 

我非常感谢您的帮助。

真诚地致谢,


@YS-L 如果您能帮忙,我将不胜感激。我已经阅读了您的帖子,我认为我有一个类似的问题,但是我无法解决它。谢谢。 - user10155602
1个回答

2

使用joblib,您可以保存任何Scikit-learn Pipeline的所有元素,因此也包括已安装的TfidfVectorizer

这里我已经使用Newsgroups20数据集的前200个示例重写了您的示例:

注:Original Answer翻译成"最初的回答"

from sklearn.datasets import fetch_20newsgroups
data = fetch_20newsgroups()

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
from sklearn.metrics import accuracy_score
from sklearn.multiclass import OneVsRestClassifier

vectorizer = TfidfVectorizer(strip_accents='unicode', analyzer='word', ngram_range=(1,3), norm='l2')

x_train = data.data[:100]
y_train = data.target[:100]

x_test =  data.data[100:200]
y_test = data.target[100:200]

# Using pipeline for applying logistic regression and one vs rest classifier
LogReg_pipeline = Pipeline([
    ('vectorizer', vectorizer),
    ('clf', OneVsRestClassifier(LogisticRegression(solver='sag', 
                                                   class_weight='balanced'), 
                                n_jobs=-1))
                           ])

# Training logistic regression model on train data
LogReg_pipeline.fit(x_train, y_train)

在上面的代码中,你只需开始定义训练和测试数据,并实例化TfidfVectorizer。然后,你定义了包括向量化器和OVR分类器的流水线,并将其适配到训练数据上。该模型将学习同时预测所有类别。
现在,你只需使用joblib保存整个适配完毕的模型流水线,就像保存单个预测器一样。
from joblib import dump, load
dump(LogReg_pipeline, 'LogReg_pipeline.joblib') 

你的整个模型并没有以'LogReg_pipeline.joblib'的名称保存到磁盘上。你可以使用以下代码片段直接在原始数据上调用它:

最初的回答:

您的模型未以“LogReg_pipeline.joblib”名称保存到磁盘中。您可以使用以下代码片段直接在原始数据上调用它:

clf = load('LogReg_pipeline.joblib') 
clf.predict(x_test)

您会得到原始文本的预测,因为管道将自动对其进行向量化。最初的回答。

非常感谢您的帮助。当我尝试使用自己的数据运行您的模型时,遇到了困难。我收到了一个错误提示,告诉我“np.nan是无效的文档,期望是字节或Unicode字符串”。 - user10155602
也许这个答案可以帮到你:https://dev59.com/clkS5IYBdhLWcg3w6qMz - Luca Massaron
非常感谢您的建议,但问题依然存在。实际上,您提供的链接建议在模型外部执行向量化转换,这正是我在原始模型中所做的。根据您之前的要求,现在没有必要进行单独的向量化处理,因为它已经封装在管道中了。 - user10155602
你所需要做的,基于 https://dev59.com/clkS5IYBdhLWcg3w6qMz,就是在训练时将 x_train.astype('U') 传递给管道,在预测时将 x_test.astype('U') 传递给管道(这将把你的文本数据转换为 Unicode)。 - Luca Massaron
感谢您的帮助。我输入了 LogReg_pipeline.fit(x_train.astype('U'), y_train.astype('U')),但是后来出现了一个错误,提示 ValueError: Multioutput target data is not supported with label binarization - user10155602
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接