【问题标题】:GridSearch for Multi-label classification in Scikit-learnGridSearch 用于 Scikit-learn 中的多标签分类
【发布时间】:2014-11-19 01:02:57
【问题描述】:

我正在尝试在十折交叉验证中的每一个中进行 GridSearch 以获得最佳超参数,它在我之前的多类分类工作中运行良好,但这次在多标签工作中并非如此。

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33)
clf = OneVsRestClassifier(LinearSVC())

C_range = 10.0 ** np.arange(-2, 9)
param_grid = dict(estimator__clf__C = C_range)

clf = GridSearchCV(clf, param_grid)
clf.fit(X_train, y_train)

我收到错误:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-65-dcf9c1d2e19d> in <module>()
      6 
      7 clf = GridSearchCV(clf, param_grid)
----> 8 clf.fit(X_train, y_train)

/usr/local/lib/python2.7/site-packages/sklearn/grid_search.pyc in fit(self, X, y)
    595 
    596         """
--> 597         return self._fit(X, y, ParameterGrid(self.param_grid))
    598 
    599 

/usr/local/lib/python2.7/site-packages/sklearn/grid_search.pyc in _fit(self, X, y,   
parameter_iterable)
    357                                  % (len(y), n_samples))
    358             y = np.asarray(y)
--> 359         cv = check_cv(cv, X, y, classifier=is_classifier(estimator))
    360 
    361         if self.verbose > 0:

/usr/local/lib/python2.7/site-packages/sklearn/cross_validation.pyc in _check_cv(cv, X,  
y, classifier, warn_mask)
   1365             needs_indices = None
   1366         if classifier:
-> 1367             cv = StratifiedKFold(y, cv, indices=needs_indices)
   1368         else:
   1369             if not is_sparse:

/usr/local/lib/python2.7/site-packages/sklearn/cross_validation.pyc in __init__(self, 
y, n_folds, indices, shuffle, random_state)
    427         for test_fold_idx, per_label_splits in enumerate(zip(*per_label_cvs)):
    428             for label, (_, test_split) in zip(unique_labels, per_label_splits):
--> 429                 label_test_folds = test_folds[y == label]
    430                 # the test split can be too big because we used
    431                 # KFold(max(c, self.n_folds), self.n_folds) instead of

ValueError: boolean index array should have 1 dimension

这可能是指标签指示器的尺寸或格式。

print X_train.shape, y_train.shape

得到:

(147, 1024) (147, 6)

似乎GridSearch 固有地实现了StratifiedKFold。 该问题出现在具有多标签问题的分层 K-fold 策略中。

StratifiedKFold(y_train, 10)

给予

ValueError                                Traceback (most recent call last)
<ipython-input-87-884ffeeef781> in <module>()
----> 1 StratifiedKFold(y_train, 10)

/usr/local/lib/python2.7/site-packages/sklearn/cross_validation.pyc in __init__(self,   
y, n_folds, indices, shuffle, random_state)
    427         for test_fold_idx, per_label_splits in enumerate(zip(*per_label_cvs)):
    428             for label, (_, test_split) in zip(unique_labels, per_label_splits):
--> 429                 label_test_folds = test_folds[y == label]
    430                 # the test split can be too big because we used
    431                 # KFold(max(c, self.n_folds), self.n_folds) instead of

ValueError: boolean index array should have 1 dimension

目前使用传统的 K-fold 策略效果很好。 有没有什么方法可以实现分层K-fold到多标签分类?

【问题讨论】:

    标签: python scikit-learn


    【解决方案1】:

    网格搜索对分类问题执行stratified cross-validation,但对于多标签任务,这没有实现;事实上,多标签分层是机器学习中一个未解决的问题。我最近遇到了同样的问题,我能找到的所有文献都是this article 中提出的方法(其中的作者表示他们也找不到任何其他解决此问题的尝试)。

    【讨论】:

    • 感谢您的评论,我注意到了问题并更新了主题。也感谢分享论文,我会通过它。
    • 我刚刚想到对每个单独的类样本进行分层拆分是否有意义?既然GridSearchCV 已经完成了OneVsRestClassifier,为什么不能单独处理每个类样本以产生L 二元问题,以便可以对L 中的每一个进行分层拆分?
    【解决方案2】:

    正如Fred Foo 指出的那样,多标签任务没有实现分层交叉验证。一种替代方法是按照here 的建议在转换后的标签空间中使用 scikit-learn 的 StratifiedKFold 类。

    以下是示例python代码。

    from sklearn.model_selection import StratifiedKFold
    kf = StratifiedKFold(n_splits=n_splits, random_state=None, shuffle=shuffle)
    
    
    for train_index, test_index in kf.split(X, lp.transform(y)):
        X_train = X[train_index,:]
        y_train = y[train_index,:]
    
        X_test = X[test_index,:]
        y_test = y[test_index,:]
    
        # learn the classifier
        classifier.fit(X_train, y_train)
    
        # predict labels for test data
        predictions = classifier.predict(X_test)
    

    【讨论】:

      【解决方案3】:

      查看scikit-multilearn package。文档并不完美,但this section 演示了多标签分层。您可以使用iterative_train_test_split 函数。

      还有iterative-stratification package,我相信它实现了相同的想法。

      对此我不确定,但我认为他们都在实现this paper

      【讨论】:

        猜你喜欢
        • 2016-10-17
        • 2016-01-24
        • 2017-08-05
        • 2013-04-30
        • 2018-11-13
        • 2018-02-22
        • 2016-07-12
        • 2018-06-19
        • 2019-11-18
        相关资源
        最近更新 更多