如何为多标签分类器/一对休息分类器腌制 sklearn 管道?

Posted

技术标签:

【中文标题】如何为多标签分类器/一对休息分类器腌制 sklearn 管道?【英文标题】:How to pickle a sklearn pipeline for multi label classifier/one vs rest classifier? 【发布时间】:2019-02-25 07:45:05 【问题描述】:

我正在尝试使用 one vs rest 分类器包装器创建一个多标签分类器。

我为 TFIDF 和分类器使用了管道。

在拟合管道时,我必须按类别循环遍历我的数据,然后每次拟合管道以对每个类别进行预测。

现在,我想像通常使用 pickle 或 joblib 导出拟合模型一样导出它。

例子:

pickle.dump(clf,'clf.pickle')

如何使用管道执行此操作?即使我腌制管道,每次我想预测一个新关键字时,我是否仍然需要拟合管道?

例子:

pickle.dump(pipeline,'pipeline.pickle')
pipeline = pickle.load('pipeline.pickle')

for category in categories:
    pipeline.fit(X_train, y_train[category])
    pipeline.predict(['kiwi'])
    print (predict)

如果我在加载管道后跳过pipeline.fit(X_train, y_train[category]),我只会在预测中得到一个值数组。如果我适合管道,我会得到一个三值数组。

另外,如何将网格搜索合并到我的导出管道中?

原始数据

keyword        class1 class2 class3
"orange apple"    1      0      1
"lime lemon"      1      0      0
"banana"          0      1      0

categories = ['class1','class2','class3']

管道

SVC_pipeline = Pipeline([
                ('tfidf', TfidfVectorizer(stop_words=stop_words)),
                ('clf', OneVsRestClassifier(LinearSVC(), n_jobs=1)),
            ])

Gridsearch(不知道如何将其合并到管道中

parameters = 'tfidf__ngram_range': [(1, 1), (1, 2)],
              'tfidf__use_idf': (True, False),
              'tfidf__max_df': [0.25, 0.5, 0.75, 1.0],
              'tfidf__max_features': [10, 50, 100, 250, 500, 1000, None],
              'tfidf__stop_words': ('english', None),
              'tfidf__smooth_idf': (True, False),
              'tfidf__norm': ('l1', 'l2', None),
              

grid = GridSearchCV(SVC_pipeline, parameters, cv=2, verbose=1)
grid.fit(X_train, y_train)

装配管道

for category in categories:
    print('... Processing '.format(category))

    SVC_pipeline.fit(X_train, y_train[category])

    # compute the testing accuracy
    prediction = SVC_pipeline.predict(X_test)
    print('Test accuracy is '.format(accuracy_score(y_test[category], prediction)))

【问题讨论】:

这可能对***.com/questions/36259967/…有帮助 【参考方案1】:

OneVsRestClassifier 在内部适合每个类一个分类器。所以你不应该像在

中那样为每个类安装管道
for category in categories:
    pipeline.fit(X_train, y_train[category])
    pipeline.predict(['kiwi'])
    print (predict)

你应该做这样的事情

SVC_pipeline = Pipeline([
                ('tfidf', TfidfVectorizer()), #add your stop_words
                ('clf', OneVsRestClassifier(LinearSVC(), n_jobs=1)),
            ])
SVC_pipeline.fit(["apple","boy","cat"],np.array([[0,1,1],[1,1,0],[1,1,1]]))

您现在可以使用

保存模型
pickle.dump(SVC_pipeline,open('pipeline.pickle', 'wb'))   

稍后您可以加载模型并使用

进行预测
obj = pickle.load(open('pipeline.pickle', 'rb'))
obj.predict(["apple","boy","cat"])

您可以在将多类标签传递给 fit 方法之前使用 MultiLabelBinarizer 对多类标签进行二值化处理

示例:

from sklearn.preprocessing import MultiLabelBinarizer
y = [['c1','c2'],['c3'],['c1'],['c1','c3'],['c1','c2','c3']]
mb = MultiLabelBinarizer()
y_encoded = mb.fit_transform(y)
SVC_pipeline.fit(["apple","boy","cat", "dog", "rat"], y_encoded)

使用网格搜索(示例)

grid = GridSearchCV(SVC_pipeline, 'tfidf__use_idf': (True, False), cv=2, verbose=1)
grid.fit(["apple","boy","cat", "dog", "rat"], y_encoded)
# Save the pipeline
pickle.dump(grid,open('grid.pickle', 'wb'))
# Later load it back and make predictions
grid_obj = pickle.load(open('grid.pickle', 'rb'))
grid_obj.predict(["apple","boy","cat", "dog", "rat"])

【讨论】:

以上是关于如何为多标签分类器/一对休息分类器腌制 sklearn 管道?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用带有 countVectorizer.fit_transform() 的腌制分类器来标记数据

如何为训练观察实现具有自定义权重的 KNN 分类器

关于多对多分类器的文献

如何为 Scikit-learn 分类器添加加权损失?

如何为 knn 分类器找到两组数据的决策边界

如何改进我的文本主题分类器?