Python 如何将两个估计器对象传递给sklearn的GridSearchCV,以便它们在每个步骤中具有相同的参数?

Python 如何将两个估计器对象传递给sklearn的GridSearchCV,以便它们在每个步骤中具有相同的参数?,python,machine-learning,scikit-learn,grid-search,Python,Machine Learning,Scikit Learn,Grid Search,我正在尝试使用SKL的GridSearchCV来为我的估计器调整超参数 在第一步中,使用估计器计算is,is是一个执行以下操作的自定义库。这意味着迭代地添加新的特征,并确定估计器在哪些方面表现最好。因此,序列特征选择方法需要我的估计器。这个库是经过编程的,因此可以很好地与SKlearn一起使用,所以我在GridSearchCV管道的第一步中集成了它,以将特征转换为所选的特征 在第二步中,我想使用完全相同的分类器,使用完全相同的参数进行拟合,并预测结果。然而,使用参数网格,我只能将参数设置为传递给

我正在尝试使用SKL的GridSearchCV来为我的估计器调整超参数

在第一步中,使用估计器计算is,is是一个执行以下操作的自定义库。这意味着迭代地添加新的特征,并确定估计器在哪些方面表现最好。因此,序列特征选择方法需要我的估计器。这个库是经过编程的,因此可以很好地与SKlearn一起使用,所以我在GridSearchCV管道的第一步中集成了它,以将特征转换为所选的特征

在第二步中,我想使用完全相同的分类器,使用完全相同的参数进行拟合,并预测结果。然而,使用参数网格,我只能将参数设置为传递给SequentialFeatureSelector的分类器,或者设置为“clf”中的参数,我不能保证它们总是相同的

最后,通过选择的特征和选择的参数,我想在之前的测试集上预测

,它们展示了如何将SFS与GridSearchCV结合使用,但用于选择特征的KNN算法和用于预测的KNN算法也使用了不同的参数。当我在trainf SFS和GridSearchCV之后为自己检查时,参数永远不会相同,即使我按照建议使用clf.clone。这是我的密码:

import sklearn.pipeline
import sklearn.tree
import sklearn.model_selection
import mlxtend.feature_selection


def sfs(x, y):
    x_train, x_test, y_train, y_test = sklearn.model_selection.train_test_split(x, y, test_size=0.2, random_state=0)

    clf = sklearn.tree.DecisionTreeClassifier()

    param_grid = {
        "sfs__estimator__max_depth": [5]
    }

    sfs = mlxtend.feature_selection.SequentialFeatureSelector(clone_estimator=True,  # Clone like in Tutorial
                                                              estimator=clf,
                                                              k_features=10,
                                                              forward=True,
                                                              floating=False,
                                                              scoring='accuracy',
                                                              cv=3,
                                                              n_jobs=1)

    pipe = sklearn.pipeline.Pipeline([('sfs', sfs), ("clf", clf)])

    gs = sklearn.model_selection.GridSearchCV(estimator=pipe,
                                              param_grid=param_grid,
                                              scoring='accuracy',
                                              n_jobs=1,
                                              cv=3,
                                              refit=True)

    gs = gs.fit(x_train, y_train)

    # Both estimators should have depth 5!
    print("SFS Final Estimator Depth: " + str(gs.best_estimator_.named_steps.sfs.estimator.max_depth))
    print("CLF Final Estimator Depth: " + str(gs.best_estimator_._final_estimator.max_depth))

    # Evaluate...
    y_test_pred = gs.predict(x_test)
    # Accuracy etc...
问题是,我如何确保在同一条管道中始终设置相同的参数


谢谢

我找到了一个解决方案,我覆盖了SequentialFeatureSelector SFS类的一些方法,也使用它的估计器来预测转换后的结果。这是通过引入自定义SFS类“CSSequentialFeatureSelector”来实现的,该类覆盖SFS中的以下方法:

在fitself,X,y方法中,不仅进行正态拟合,而且对转换数据进行自估计,因此可以对SFS类实施预测和预测概率方法

我为SFS类实现了predict and predict_probba方法,称为拟合自估值器的predict and predict_probba方法

因此,我只剩下一个用于SFS和预测的估计器

下面是一些代码:

import sklearn.pipeline
import sklearn.tree
import sklearn.model_selection
import mlxtend.feature_selection


class CSequentialFeatureSelector(mlxtend.feature_selection.SequentialFeatureSelector):
    def predict(self, X):
        X = self.transform(X)
        return self.estimator.predict(X)

    def predict_proba(self, X):
        X = self.transform(X)
        return self.estimator.predict_proba(X)

    def fit(self, X, y):
        self.fit_helper(X, y) # fit helper is the 'old' fit method, which I copied and renamed to fit_helper
        self.estimator.fit(self.transform(X), y)
        return self


def sfs(x, y):
    x_train, x_test, y_train, y_test = sklearn.model_selection.train_test_split(x, y, test_size=0.2, random_state=0)

    clf = sklearn.tree.DecisionTreeClassifier()

    param_grid = {
        "sfs__estimator__max_depth": [3, 4, 5]
    }

    sfs = mlxtend.feature_selection.SequentialFeatureSelector(clone_estimator=True,
                                                              estimator=clf,
                                                              k_features=10,
                                                              forward=True,
                                                              floating=False,
                                                              scoring='accuracy',
                                                              cv=3,
                                                              n_jobs=1)

    # Now only one object in the pipeline (in fact this is not even needed anymore)
    pipe = sklearn.pipeline.Pipeline([('sfs', sfs)])

    gs = sklearn.model_selection.GridSearchCV(estimator=pipe,
                                              param_grid=param_grid,
                                              scoring='accuracy',
                                              n_jobs=1,
                                              cv=3,
                                              refit=True)

    gs = gs.fit(x_train, y_train)

    print("SFS Final Estimator Depth: " + str(gs.best_estimator_.named_steps.sfs.estimator.max_depth))

    y_test_pred = gs.predict(x_test)
    # Evaluate performance of y_test_pred