子类化sklearn LinearSVC,用作sklearn GridSearchCV的估计器

2024-09-24 04:17:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图从sklearn.svm.LinearSVC创建一个子类,用作sklearn.model_selection.GridSearchCV的估算器。子类有一个额外的函数,在本例中它什么都不做。然而,当我运行这个程序时,我最终遇到了一个我似乎无法调试的错误。如果复制粘贴代码并运行,它将复制以ValueError: Input contains NaN, infinity or a value too large for dtype('float64')结尾的完整错误

一旦我让他开始工作,我希望为方法transform_this()添加更多功能

有人能告诉我哪里出了问题吗?基于this我最初认为这是由于我的数据出现了一些问题。然而,由于我使用sklearn内置数据集复制了它,所以情况似乎并非如此。此外,我相信我正在根据我对上一个问题here的回答正确地将其子类化。此外,我还了解到GridSearchCV似乎没有以不同的方式初始化估计器(不知何故,它首先使用默认参数,正如我从this post中看到的)

from sklearn.datasets import load_breast_cancer
from sklearn.svm import LinearSVC
from sklearn.model_selection import GridSearchCV

RANDOM_STATE = 123


class LinearSVCSub(LinearSVC):
    def __init__(self, penalty='l2', loss='squared_hinge', additional_parameter1=1, additional_parameter2=100,
                 dual=True, tol=0.0001, C=1.0, multi_class='ovr', fit_intercept=True, intercept_scaling=1,
                 class_weight=None, verbose=0, random_state=None, max_iter=1000):
        super(LinearSVCSub, self).__init__(penalty=penalty, loss=loss, dual=dual, tol=tol,
                                           C=C, multi_class=multi_class, fit_intercept=fit_intercept,
                                           intercept_scaling=intercept_scaling, class_weight=class_weight,
                                           verbose=verbose, random_state=random_state, max_iter=max_iter)

        self.additional_parameter1 = additional_parameter1
        self.additional_parameter2 = additional_parameter2

    def fit(self, X, y, sample_weight=None):
        X = self.transform_this(X)
        super(LinearSVCSub, self).fit(X, y, sample_weight)

    def predict(self, X):
        X = self.transform_this(X)
        super(LinearSVCSub, self).predict(X)

    def score(self, X, y, sample_weight=None):
        X = self.transform_this(X)
        super(LinearSVCSub, self).score(X, y, sample_weight)

    def decision_function(self, X):
        X = self.transform_this(X)
        super(LinearSVCSub, self).decision_function(X)

    def transform_this(self, X):
        return X


if __name__ == '__main__':
    data = load_breast_cancer()
    X, y = data.data, data.target

    # Parameter tuning with custom LinearSVC
    param_grid = {'C': [0.00001, 0.0001, 0.0005],
                      'dual': (True, False), 'random_state': [RANDOM_STATE],
                      'additional_parameter1': [0.90, 0.80, 0.60, 0.30],
                      'additional_parameter2': [20, 30]}

    gs_model = GridSearchCV(estimator=LinearSVCSub(), verbose=1, param_grid=param_grid,
                            scoring='roc_auc', n_jobs=-1)
    gs_model.fit(X, y)

Tags: selfmodeldeftransformsklearnthisclassfit
1条回答
网友
1楼 · 发布于 2024-09-24 04:17:00

你有两个问题:

  1. 定义的方法没有return语句
  2. 您选择的数据集不与LinearSVC收敛

一旦你纠正了这些错误,你就可以走了:

from sklearn.datasets import make_classification
from sklearn.svm import LinearSVC
from sklearn.model_selection import GridSearchCV

RANDOM_STATE = 123


class LinearSVCSub(LinearSVC):
    def __init__(self, penalty='l2', loss='squared_hinge', additional_parameter1=1, additional_parameter2=100,
                 dual=True, tol=0.0001, C=1.0, multi_class='ovr', fit_intercept=True, intercept_scaling=1,
                 class_weight=None, verbose=0, random_state=None, max_iter=100000):
        super(LinearSVCSub, self).__init__(penalty=penalty, loss=loss, dual=dual, tol=tol,
                                           C=C, multi_class=multi_class, fit_intercept=fit_intercept,
                                           intercept_scaling=intercept_scaling, class_weight=class_weight,
                                           verbose=verbose, random_state=random_state, max_iter=max_iter)

        self.additional_parameter1 = additional_parameter1
        self.additional_parameter2 = additional_parameter2

    def fit(self, X, y, sample_weight=None):
        X = self.transform_this(X)
        super(LinearSVCSub, self).fit(X, y, sample_weight)
        return self

    def predict(self, X):
        X = self.transform_this(X)
        return super(LinearSVCSub, self).predict(X)

    def score(self, X, y, sample_weight=None):
        X = self.transform_this(X)
        return super(LinearSVCSub, self).score(X, y, sample_weight)

    def decision_function(self, X):
        X = self.transform_this(X)
        return super(LinearSVCSub, self).decision_function(X)

    def transform_this(self, X):
        return X


X, y = make_classification()

# Parameter tuning with custom LinearSVC
param_grid = {'C': [0.00001, 0.0001, 0.0005],
                  'dual': (True, False), 'random_state': [RANDOM_STATE],
                  'additional_parameter1': [0.90, 0.80, 0.60, 0.30],
                  'additional_parameter2': [20, 30]
             }

gs_model = GridSearchCV(estimator=LinearSVCSub(), verbose=1, param_grid=param_grid,
                        scoring='roc_auc', n_jobs=1)

gs_model.fit(X, y)
Fitting 5 folds for each of 48 candidates, totalling 240 fits
[Parallel(n_jobs=1)]: Using backend SequentialBackend with 1 concurrent workers.
[Parallel(n_jobs=1)]: Done 240 out of 240 | elapsed:    0.9s finished
GridSearchCV(estimator=LinearSVCSub(), n_jobs=1,
             param_grid={'C': [1e-05, 0.0001, 0.0005],
                         'additional_parameter1': [0.9, 0.8, 0.6, 0.3],
                         'additional_parameter2': [20, 30],
                         'dual': (True, False), 'random_state': [123]},
             scoring='roc_auc', verbose=1)

gs_model.predict(X)
array([0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1,
       1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1,
       1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1,
       0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0,
       0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1])

相关问题 更多 >