Scikit-learn 多输出分类器使用:GridSearchCV、Pipeline、OneVsRestClassifier、SGDClassifier

Posted

技术标签:

【中文标题】Scikit-learn 多输出分类器使用:GridSearchCV、Pipeline、OneVsRestClassifier、SGDClassifier【英文标题】:Scikit-learn multi-output classifier using: GridSearchCV, Pipeline, OneVsRestClassifier, SGDClassifier 【发布时间】:2017-03-14 03:38:49 【问题描述】:

我正在尝试使用 GridSearchCV 和 Pipeline 构建多输出模型。管道给我带来了麻烦,因为标准分类器示例没有包装分类器的 OneVsRestClassifier()。我正在使用 scikit-learn 0.18 和 python 3.5

## Pipeline: Train and Predict
## SGD: support vector machine (SVM) with gradient descent
from sklearn.multiclass import OneVsRestClassifier
from sklearn.pipeline import Pipeline
from sklearn.linear_model import SGDClassifier

clf = Pipeline([
               ('vect', CountVectorizer(ngram_range=(1,3), max_df=0.50 ) ),
               ('tfidf', TfidfTransformer() ),
               ('clf', SGDClassifier(loss='modified_huber', penalty='elasticnet',
                                          alpha=1e-4, n_iter=5, random_state=42,
                                          shuffle=True, n_jobs=-1) ),
                ])

ovr_clf = OneVsRestClassifier(clf ) 

from sklearn.model_selection import GridSearchCV
parameters = 'vect__ngram_range': [(1,1), (1,3)],
              'tfidf__norm': ('l1', 'l2', None),
              'estimator__loss': ('modified_huber', 'hinge',),
             

gs_clf = GridSearchCV(estimator=pipeline, param_grid=parameters, 
                      scoring='f1_weighted', n_jobs=-1, verbose=1)
gs_clf = gs_clf.fit(X_train, y_train)

但这会产生错误: ....

ValueError:估计器的参数估计器无效 Pipeline(steps=[('vect', CountVectorizer(analyzer='word', binary=False, decode_error='strict', dtype=,编码='utf-8',输入='内容', 小写=真,max_df=0.5,max_features=无,min_df=1, ngram_range=(1, 3),预处理器=None,stop_words=None, 剥离...er_t=0.5, random_state=42, shuffle=True, 详细=0,warm_start=False), n_jobs=-1))])。使用estimator.get_params().keys()查看可用参数列表。

那么使用 param_grid 和 Pipeline 通过 OneVsRestClassifier 将参数传递给 clf 的正确方法是什么?我需要将矢量化器和 tdidf 与 Pipeline 中的分类器分开吗?

【问题讨论】:

【参考方案1】:

将 OneVsRestClassifier() 作为管道本身的一个步骤,将 SGDClassifier 作为 OneVsRestClassifier 的估计器。 你可以这样走。

pipeline = Pipeline([
               ('vect', CountVectorizer(ngram_range=(1,3), max_df=0.50 ) ),
               ('tfidf', TfidfTransformer() ),
               ('clf', OneVsRestClassifier(SGDClassifier(loss='modified_huber', penalty='elasticnet',
                                          alpha=1e-4, n_iter=5, random_state=42,
                                          shuffle=True, n_jobs=-1) )),
                ])

其余代码可以保持不变。 OneVsRestClassifier 充当其他估算器的包装器。

【讨论】:

成功了! (1) 我将 OneVsRestClassifier 移动到管道内以包装 SGDClassifier。 (2) 我在 param_grid 处理估计器参数中添加了前缀“clf__”,即“clf__estimator__penalty”。 使用 as wrap 和使用 f1_weighted 文件“/opt/conda/lib/python3.7/site-packages/sklearn/metrics/_classification. py”,第 1250 行,在 _check_set_wise_labels 中_check_targets raise ValueError("0 is not supported".format(y_type)) ValueError: multiclass-multioutput is not supported

以上是关于Scikit-learn 多输出分类器使用:GridSearchCV、Pipeline、OneVsRestClassifier、SGDClassifier的主要内容,如果未能解决你的问题,请参考以下文章

多标签分类器中的拟合概率

Python Scikit-learn 感知器输出概率

如何在 scikit-learn 中正确加载文本数据?

Scikit-learn 分类器具有依赖于训练特征的自定义记分器

scikit-learn 的 VotingClassifier 中使用的分类器是啥?

在 java 程序中使用 scikit-learn 分类器