如何使用管道对嵌入 OneVsRestClassifier 的估计器进行网格搜索
How to gridsearch an estimator embeded in OneVsRestClassifier using Pipeline
我正在使用 GridSearchCV 进行模型选择和超参数调整。从最初的实验来看,结果证明带有 rdf 内核的 SVC 具有最好的性能。问题是样本太慢(200K+)。使用 OneVsRestClassifier 可以并行化 SVC (n_jobs)。但是,当我使用 Pipeline 同时测试多个估算器时,gridsearchcv 不适用于此嵌入式估算器。
pipe = Pipeline([('clf', SVC())]) # Placeholder Estimator
# Candidate learning algorithms and their hyperparameters
search_space = [{'clf': [OneVsRestClassifier(SVC(tol=0.1, gamma='scale', probability=True), n_jobs=-1],
'clf__kernel': ['rbf', 'linear'],
'clf__C': [1, 10, 100]},
{'clf': [LogisticRegression(tol=0.1, penalty='l1', solver='saga', multi_class='multinomial', n_jobs=8)],
'clf__C': [1, 10, 100]},
{'clf': [RandomForestClassifier(n_jobs=8)],
'clf__n_estimators': [50, 100, 200, 300, 400],
'clf__max_depth': [10, 20, 30],
'clf__min_samples_leaf': [1, 2, 4],
'clf__min_samples_split': [2, 5, 10]},
{'clf': [MultinomialNB()],
'clf__alpha': [0.1, 0.5, 1]}]
gs = GridSearchCV(pipe, search_space, cv=skf, scoring='accuracy', verbose=10)
我遇到错误
Invalid Parameter __kernel
但是根据GridSearch for an estimator inside a OneVsRestClassifier,这个方法应该可行。我认为是管道搞砸了,因为它基本上在 OneVsRestClassifier 之上添加了另一层。我该如何为这个嵌套估计器执行 gridsearchcv?
照原样,管道在 OneVsRestClassifier
中查找参数 kernel
,找不到(不出所料,因为模块没有这样的参数),并引发错误。由于您实际上想要 SVC
的参数 kernel
(以及随后的 C
),您应该更深入:将 search_space
的前 3 个条目更改为:
{'clf': [OneVsRestClassifier(SVC(tol=0.1, gamma='scale', probability=True), n_jobs=-1],
'clf__estimator__kernel': ['rbf', 'linear'],
'clf__estimator__C': [1, 10, 100]}
你应该没问题。
然而,无论错误如何,您使用此方法的理由:
The problem with that is it is too slow (200K+) sample. Using OneVsRestClassifier can parallelize SVC (n_jobs).
不正确。 OneVsRestClassifier
将并行化 n_classes
个不同的 SVC
估计量的拟合, 而不是 SVC
本身。实际上,您试图通过在其周围包裹其他东西(此处 OneVsRestClassifier
)来避免瓶颈(SVC
),这会增加其自身的额外计算复杂性,只是为了(不出所料)再次在你.
我们可以用虚拟数据的一些时间来证明这一点——让我们尝试一个比较现实的数据集,其中包含 10K 个样本、5 个特征和 3 个 类:
from sklearn.multiclass import OneVsRestClassifier
from sklearn.svm import SVC
from sklearn.datasets import make_classification
X, y = make_classification(n_samples = 10000, n_features=5, n_redundant=0, n_informative=5,
n_classes = 3, n_clusters_per_class=1, random_state=42)
%timeit for x in range(10): SVC().fit(X,y)
# 1 loop, best of 3: 7.72 s per loop
%timeit for x in range(10): OneVsRestClassifier(SVC()).fit(X, y)
# 1 loop, best of 3: 21.1 s per loop
好吧,那是你的基准差异;现在设置 n_jobs=-1
有帮助:
%timeit for x in range(10): OneVsRestClassifier(SVC(), n_jobs=-1).fit(X, y)
# 1 loop, best of 3: 19 s per loop
但是,不出所料,它只针对未并行化的 OneVsRestClassifier
这样做, 而不是 与 SVC
本身相关。
随着功能的增加,差异越来越大 & 类;不去你的完整案例,这里是有 10 个特征和 5 类(相同数量的样本,10K)的情况:
X1, y1 = make_classification(n_samples = 10000, n_features=10, n_redundant=0, n_informative=10,
n_classes = 5, n_clusters_per_class=1, random_state=42)
%timeit for x in range(10): SVC().fit(X1,y1)
# 1 loop, best of 3: 10.3 s per loop
%timeit for x in range(10): OneVsRestClassifier(SVC()).fit(X1, y1)
# 1 loop, best of 3: 30.7 s per loop
%timeit for x in range(10): OneVsRestClassifier(SVC(), n_jobs=-1).fit(X1, y1)
# 1 loop, best of 3: 24.9 s per loop
所以,我强烈建议您在这里重新考虑您的方法(和您的目标)。
(Google Colab 中的所有时间)。
我正在使用 GridSearchCV 进行模型选择和超参数调整。从最初的实验来看,结果证明带有 rdf 内核的 SVC 具有最好的性能。问题是样本太慢(200K+)。使用 OneVsRestClassifier 可以并行化 SVC (n_jobs)。但是,当我使用 Pipeline 同时测试多个估算器时,gridsearchcv 不适用于此嵌入式估算器。
pipe = Pipeline([('clf', SVC())]) # Placeholder Estimator
# Candidate learning algorithms and their hyperparameters
search_space = [{'clf': [OneVsRestClassifier(SVC(tol=0.1, gamma='scale', probability=True), n_jobs=-1],
'clf__kernel': ['rbf', 'linear'],
'clf__C': [1, 10, 100]},
{'clf': [LogisticRegression(tol=0.1, penalty='l1', solver='saga', multi_class='multinomial', n_jobs=8)],
'clf__C': [1, 10, 100]},
{'clf': [RandomForestClassifier(n_jobs=8)],
'clf__n_estimators': [50, 100, 200, 300, 400],
'clf__max_depth': [10, 20, 30],
'clf__min_samples_leaf': [1, 2, 4],
'clf__min_samples_split': [2, 5, 10]},
{'clf': [MultinomialNB()],
'clf__alpha': [0.1, 0.5, 1]}]
gs = GridSearchCV(pipe, search_space, cv=skf, scoring='accuracy', verbose=10)
我遇到错误
Invalid Parameter __kernel
但是根据GridSearch for an estimator inside a OneVsRestClassifier,这个方法应该可行。我认为是管道搞砸了,因为它基本上在 OneVsRestClassifier 之上添加了另一层。我该如何为这个嵌套估计器执行 gridsearchcv?
照原样,管道在 OneVsRestClassifier
中查找参数 kernel
,找不到(不出所料,因为模块没有这样的参数),并引发错误。由于您实际上想要 SVC
的参数 kernel
(以及随后的 C
),您应该更深入:将 search_space
的前 3 个条目更改为:
{'clf': [OneVsRestClassifier(SVC(tol=0.1, gamma='scale', probability=True), n_jobs=-1],
'clf__estimator__kernel': ['rbf', 'linear'],
'clf__estimator__C': [1, 10, 100]}
你应该没问题。
然而,无论错误如何,您使用此方法的理由:
The problem with that is it is too slow (200K+) sample. Using OneVsRestClassifier can parallelize SVC (n_jobs).
不正确。 OneVsRestClassifier
将并行化 n_classes
个不同的 SVC
估计量的拟合, 而不是 SVC
本身。实际上,您试图通过在其周围包裹其他东西(此处 OneVsRestClassifier
)来避免瓶颈(SVC
),这会增加其自身的额外计算复杂性,只是为了(不出所料)再次在你.
我们可以用虚拟数据的一些时间来证明这一点——让我们尝试一个比较现实的数据集,其中包含 10K 个样本、5 个特征和 3 个 类:
from sklearn.multiclass import OneVsRestClassifier
from sklearn.svm import SVC
from sklearn.datasets import make_classification
X, y = make_classification(n_samples = 10000, n_features=5, n_redundant=0, n_informative=5,
n_classes = 3, n_clusters_per_class=1, random_state=42)
%timeit for x in range(10): SVC().fit(X,y)
# 1 loop, best of 3: 7.72 s per loop
%timeit for x in range(10): OneVsRestClassifier(SVC()).fit(X, y)
# 1 loop, best of 3: 21.1 s per loop
好吧,那是你的基准差异;现在设置 n_jobs=-1
有帮助:
%timeit for x in range(10): OneVsRestClassifier(SVC(), n_jobs=-1).fit(X, y)
# 1 loop, best of 3: 19 s per loop
但是,不出所料,它只针对未并行化的 OneVsRestClassifier
这样做, 而不是 与 SVC
本身相关。
随着功能的增加,差异越来越大 & 类;不去你的完整案例,这里是有 10 个特征和 5 类(相同数量的样本,10K)的情况:
X1, y1 = make_classification(n_samples = 10000, n_features=10, n_redundant=0, n_informative=10,
n_classes = 5, n_clusters_per_class=1, random_state=42)
%timeit for x in range(10): SVC().fit(X1,y1)
# 1 loop, best of 3: 10.3 s per loop
%timeit for x in range(10): OneVsRestClassifier(SVC()).fit(X1, y1)
# 1 loop, best of 3: 30.7 s per loop
%timeit for x in range(10): OneVsRestClassifier(SVC(), n_jobs=-1).fit(X1, y1)
# 1 loop, best of 3: 24.9 s per loop
所以,我强烈建议您在这里重新考虑您的方法(和您的目标)。
(Google Colab 中的所有时间)。