【问题标题】:Using custom classifier for mutilabel classification with GridSearchCV and OneVsRestClassifier通过 GridSearchCV 和 OneVsRestClassifier 使用自定义分类器进行多标签分类
【发布时间】:2016-09-26 08:41:50
【问题描述】:

我正在尝试使用 OneVsRestClassifier 对一组 cmets 进行多标签分类。我的目标是将每条评论标记到可能的主题列表中。我的自定义分类器使用手动管理的单词列表及其在 csv 中的相应标签来标记每个评论。我正在尝试将从词袋技术获得的结果与使用 VotingClassifier 的自定义分类器结合起来。这是我现有代码的一部分:

import numpy as np

from sklearn.base import BaseEstimator, ClassifierMixin
from sklearn.ensemble import VotingClassifier
from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer
from sklearn.grid_search import GridSearchCV
from sklearn.linear_model import SGDClassifier
from sklearn.multiclass import OneVsRestClassifier
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import MultiLabelBinarizer

class CustomClassifier(BaseEstimator, ClassifierMixin):
    def __init__(self, word_to_tag):
        self.word_to_tag = word_to_tag

    def fit(self, X, y=None):
        return self

    def predict_proba(self, X):
        prob = np.zeros(shape=(len(self.word_to_tag), 2))

        for index, comment in np.ndenumerate(X):
            prob[index] = [0.5, 0.5]
            for word, label in self.word_to_tag.iteritems():
                if (label == self.class_label) and (comment.find(word) >= 0):
                    prob[index] = [0, 1]
                    break

        return prob

    def _get_label(self, ...):
        # Need to have a way of knowing which label being classified
        # by OneVsRestClassifier (self.class_label)

bow_clf = Pipeline([('vect', CountVectorizer(stop_words='english', min_df=1, max_df=0.9)), 
                    ('tfidf', TfidfTransformer(use_idf=False)),
                    ('clf', SGDClassifier(loss='log', penalty='l2', alpha=1e-3, n_iter=5)),
                   ])
custom_clf = CustomClassifier(word_to_tag_dict)

ovr_clf = OneVsRestClassifier(VotingClassifier(estimators=[('bow', bow_clf), ('custom', custom_clf)],
                                               voting='soft'))

params = { 'estimator_weights': ([1, 1], [1, 2], [2, 1]) }
gs_clf = GridSearchCV(ovr_clf, params, n_jobs=-1, verbose=1, scoring='precision_samples')

binarizer = MultiLabelBinarizer()

gs_clf.fit(X, binarizer.fit_transform(y))

我的目的是使用这个通过几种启发式方法获得的手动策划的单词列表来改进仅应用词袋获得的结果。目前,我正在努力寻找一种方法来了解在预测时对哪个标签进行分类,因为使用 OneVsRestClassifier 为每个标签创建了 CustomClassifier 的副本。

【问题讨论】:

  • self.class_label 对我来说似乎是未定义的。我不确定您所说的“正在分类哪个标签”是什么意思,标签是从数据中预测出来的。
  • 是的,我的问题基本上是如何确定self.class_label 是什么?因此,当 OneVsRestClassifier 拟合数据时,如果您正在进行多标签分类,它会为每个被分类的标签 (github.com/scikit-learn/scikit-learn/blob/51a765a/sklearn/…) 克隆估计器 (github.com/scikit-learn/scikit-learn/blob/51a765a/sklearn/…)。所以,基本上我需要的是一种方法,让我在计算predict_proba 时确定克隆的 CustomClassifier 对应于哪个标签。
  • 为了进一步描述,我举个例子。可以说评论是“这家餐厅的食物很棒。这家餐厅的服务也很棒。”假设我正在使用标签["food", "staff", "location", "other", ...]。然后,在这种情况下,OneVsRestClassifier 会为每个标签创建一个 VotingClassifier 的克隆。这还会递归地为每个标签复制CustomClassifier。但是我不知道如何确定CustomClassifier的具体实例对应哪个标签。

标签: python machine-learning scikit-learn supervised-learning multilabel-classification


【解决方案1】:

【讨论】:

  • ovr_clf.classes_ 似乎是 0 到 n_classes-1 的 numpy 数组,如 shape=[n_classes] 所述。当我尝试fit 数据时,我希望确定ovr_clf.estimators_ 数组中VotingClassifier 的实例之一对应于哪个标签。
  • 要么这个数组就是答案,要么我不明白你的问题。第一个估计器是 0 类与其余的,第二个估计器是 1 类与其余的。如果你以不同的方式命名你的类,你会在那里找到它们的名字。
  • 所以,当我尝试在gs_clf 上拟合数据时,多标签二值化器将y 标签从"food", "staff", "location", "other", ...] 转换为1 和0 的数组[0 1 0 0 ... ]。那么ovr_clf.classes_中的0到15分别对应什么?这是否意味着ovr_clf.estimators_ 列表的每个顺序都与[0 1 0 0 ...] 中表示列的标签的顺序相同? (这基本上意味着它与binarizer.classes列表中的类的顺序相同)
  • 是的。对于所有估计器,classes_ 是哪一列(在多标签或 predict_proba 中)对应于哪个类。对于 OVR,estimators_ 与 classes_ 具有相同的顺序。
猜你喜欢
  • 1970-01-01
  • 2017-03-14
  • 2016-07-12
  • 2016-08-11
  • 2017-05-04
  • 2019-04-02
  • 2021-11-18
  • 2019-09-24
  • 2016-05-09
相关资源
最近更新 更多