OneVsRestClassifier 中多个 类 的分类器参数是否可以不同
Can the parameters of a Classifier be different for multiple classes in OneVsRestClassifier
有谁知道 sklearn 是否支持 OneVsRestClassifier
中各种分类器的不同参数?例如在那个例子中,我想为不同的 类.
设置不同的 C
值
from sklearn.multiclass import OneVsRestClassifier
from sklearn.svm import LinearSVC
text_clf = OneVsRestClassifier(LinearSVC(C=1.0, class_weight="balanced"))
没有 OneVsRestClassifier 目前没有不同的估计器参数或不同 类 当前的不同估计器。
有一些在其他东西中实现,例如 LogisticRegressionCV 会根据 类 自动调整不同的参数值,但尚未扩展到 OneVsRestClassifier。
但如果您需要,我们可以更改源代码以实现它。
fit()
in the master branch is this的当前来源:
...
...
self.estimators_ = Parallel(n_jobs=self.n_jobs)(delayed(_fit_binary)(
self.estimator, X, column, classes=[
"not %s" % self.label_binarizer_.classes_[i],
self.label_binarizer_.classes_[i]])
for i, column in enumerate(columns))
如您所见,相同的估计器 (self.estimator
) 正在传递给所有 类 进行训练。所以我们将制作一个新版本的 OneVsRestClassifier 来改变这个:
from sklearn.multiclass import OneVsRestClassifier
from sklearn.preprocessing import LabelBinarizer
from sklearn.externals.joblib import Parallel, delayed
from sklearn.multiclass import _fit_binary
class CustomOneVsRestClassifier(OneVsRestClassifier):
# Changed the estimator to estimators which can take a list now
def __init__(self, estimators, n_jobs=1):
self.estimators = estimators
self.n_jobs = n_jobs
def fit(self, X, y):
self.label_binarizer_ = LabelBinarizer(sparse_output=True)
Y = self.label_binarizer_.fit_transform(y)
Y = Y.tocsc()
self.classes_ = self.label_binarizer_.classes_
columns = (col.toarray().ravel() for col in Y.T)
# This is where we change the training method
self.estimators_ = Parallel(n_jobs=self.n_jobs)(delayed(_fit_binary)(
estimator, X, column, classes=[
"not %s" % self.label_binarizer_.classes_[i],
self.label_binarizer_.classes_[i]])
for i, (column, estimator) in enumerate(zip(columns, self.estimators)))
return self
现在您可以使用它了。
# Make sure you add those many estimators as there are classes
# In binary case, only a single estimator should be used
estimators = []
# I am considering 3 classes as of now
estimators.append(LinearSVC(C=1.0, class_weight="balanced"))
estimators.append(LinearSVC(C=0.1, class_weight="balanced"))
estimators.append(LinearSVC(C=10, class_weight="balanced"))
clf = CustomOneVsRestClassifier(estimators)
clf.fit(X, y)
注意:我还没有在其中实现 partial_fit()
。如果您打算使用它,我们可以处理它。
有谁知道 sklearn 是否支持 OneVsRestClassifier
中各种分类器的不同参数?例如在那个例子中,我想为不同的 类.
C
值
from sklearn.multiclass import OneVsRestClassifier
from sklearn.svm import LinearSVC
text_clf = OneVsRestClassifier(LinearSVC(C=1.0, class_weight="balanced"))
没有 OneVsRestClassifier 目前没有不同的估计器参数或不同 类 当前的不同估计器。
有一些在其他东西中实现,例如 LogisticRegressionCV 会根据 类 自动调整不同的参数值,但尚未扩展到 OneVsRestClassifier。
但如果您需要,我们可以更改源代码以实现它。
fit()
in the master branch is this的当前来源:
...
...
self.estimators_ = Parallel(n_jobs=self.n_jobs)(delayed(_fit_binary)(
self.estimator, X, column, classes=[
"not %s" % self.label_binarizer_.classes_[i],
self.label_binarizer_.classes_[i]])
for i, column in enumerate(columns))
如您所见,相同的估计器 (self.estimator
) 正在传递给所有 类 进行训练。所以我们将制作一个新版本的 OneVsRestClassifier 来改变这个:
from sklearn.multiclass import OneVsRestClassifier
from sklearn.preprocessing import LabelBinarizer
from sklearn.externals.joblib import Parallel, delayed
from sklearn.multiclass import _fit_binary
class CustomOneVsRestClassifier(OneVsRestClassifier):
# Changed the estimator to estimators which can take a list now
def __init__(self, estimators, n_jobs=1):
self.estimators = estimators
self.n_jobs = n_jobs
def fit(self, X, y):
self.label_binarizer_ = LabelBinarizer(sparse_output=True)
Y = self.label_binarizer_.fit_transform(y)
Y = Y.tocsc()
self.classes_ = self.label_binarizer_.classes_
columns = (col.toarray().ravel() for col in Y.T)
# This is where we change the training method
self.estimators_ = Parallel(n_jobs=self.n_jobs)(delayed(_fit_binary)(
estimator, X, column, classes=[
"not %s" % self.label_binarizer_.classes_[i],
self.label_binarizer_.classes_[i]])
for i, (column, estimator) in enumerate(zip(columns, self.estimators)))
return self
现在您可以使用它了。
# Make sure you add those many estimators as there are classes
# In binary case, only a single estimator should be used
estimators = []
# I am considering 3 classes as of now
estimators.append(LinearSVC(C=1.0, class_weight="balanced"))
estimators.append(LinearSVC(C=0.1, class_weight="balanced"))
estimators.append(LinearSVC(C=10, class_weight="balanced"))
clf = CustomOneVsRestClassifier(estimators)
clf.fit(X, y)
注意:我还没有在其中实现 partial_fit()
。如果您打算使用它,我们可以处理它。