【问题标题】:Multilabel classification in scikit-learn with hyperparameter search: specifying averagingscikit-learn 中的多标签分类与超参数搜索:指定平均
【发布时间】:2022-02-06 11:33:47
【问题描述】:

我正在研究一个简单的多输出分类问题,并注意到在运行以下代码时会出现此错误:

ValueError: Target is multilabel-indicator but average='binary'. Please 
choose another average setting, one of [None, 'micro', 'macro', 'weighted', 'samples'].

我理解它所引用的问题,即在评估多标签模型时,需要明确设置平均类型。尽管如此,我无法弄清楚这个average 参数应该放在哪里,因为只有accuracy_scoreprecision_scorerecall_score 内置方法有这个参数,我没有在我的代码中明确使用。此外,由于我正在执行RandomizedSearch,因此我也不能只将precision_score(average='micro') 传递给scoringrefit 参数,因为precision_score() 需要正确且真实的y 标签才能传递。这就是为什么 this former SO questionthis one here 都存在类似问题,但没有帮助的原因。

我的示例数据生成代码如下:

from sklearn.datasets import make_multilabel_classification
from sklearn.naive_bayes import MultinomialNB
from sklearn.multioutput import MultiOutputClassifier
from sklearn.model_selection import RandomizedSearchCV
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import MinMaxScaler

X, Y = make_multilabel_classification(
    n_samples=1000,
    n_features=2,
    n_classes=5,
    n_labels=2
)

pipe = Pipeline(
    steps = [
        ('scaler', MinMaxScaler()),
        ('model', MultiOutputClassifier(MultinomialNB()))
    ]
)

search = RandomizedSearchCV(
    estimator = pipe,
    param_distributions={'model__estimator__alpha': (0.01,1)},
    scoring = ['accuracy', 'precision', 'recall'],
    refit = 'precision',
    cv = 5
).fit(X, Y)

我错过了什么?

【问题讨论】:

    标签: python scikit-learn multilabel-classification hyperparameters


    【解决方案1】:

    从 scikit-learn 文档中,我看到您可以传递一个可调用函数,该函数返回一个字典,其中键是指标名称,值是指标分数。这意味着您可以编写自己的评分函数,该函数必须将估计器 X_testy_test 作为输入。这反过来必须计算 y_pred 并使用它来计算您想要使用的分数。这你可以做内置的方法。在那里,您可以指定应使用哪些关键字参数来计算分数。在看起来像的代码中

    def my_scorer(estimator, X_test, y_test) -> dict[str, float]:
        y_pred = estimator.predict(X_test)
        return {
            'accuracy': accuracy_score(y_test, y_pred),
            'precision': precision_score(y_test, y_pred, average='micro'),
            'recall': recall_score(y_test, y_pred, average='micro'),
        }
    
    search = RandomizedSearchCV(
        estimator = pipe,
        param_distributions={'model__estimator__alpha': (0.01,1)},
        scoring = my_scorer,
        refit = 'precision',
        cv = 5
    ).fit(X, Y)
    

    【讨论】:

      【解决方案2】:

      来自the table of scoring metrics,注意f1_microf1_macro 等,以及为precisionrecall 提供的注释“后缀适用于‘f1’”。所以例如

      search = RandomizedSearchCV(
          ...
          scoring = ['accuracy', 'precision_micro', 'recall_macro'],
          ...
      )
      

      【讨论】:

        猜你喜欢
        • 2016-10-17
        • 2016-04-09
        • 2016-01-19
        • 2018-07-28
        • 2014-11-19
        • 2016-01-24
        • 1970-01-01
        • 2017-08-05
        • 2013-04-30
        相关资源
        最近更新 更多