Incluindo Escala e PCA como parâmetro de GridSearchCV

Oct 02 2020

Quero executar uma regressão logística usando GridSearchCV, mas quero comparar o desempenho quando o Scaling e o PCA são usados, portanto, não quero usá-lo em todos os casos.

Eu basicamente gostaria de incluir o PCA e o escalonamento como "parâmetros" do GridSearchCV

Estou ciente de que posso fazer um pipeline como este:

mnl = LogisticRegression(fit_intercept=True, multi_class="multinomial")

pipe = Pipeline([
    ('scale', StandardScaler()),
    ('mnl', mnl)])

params_mnl = {'mnl__solver': ['newton-cg', 'lbfgs', 'liblinear', 'sag', 'saga'],
              'mnl__max_iter':[500,1000,2000,3000]}

Acontece que, nesse caso, o dimensionamento seria aplicado em todas as dobras, certo? Existe uma maneira de fazer com que seja "incluído" na pesquisa em rede?

EDITAR:

Acabei de ler esta resposta e embora seja semelhante ao que desejo, não é bem assim, pois nesse caso o Scaler será aplicado ao melhor estimador fora do GridSearch.

O que eu quero fazer é, por exemplo, digamos

params_mnl = {'mnl__solver': ['newton-cg', 'lbfgs']}

Quero executar a regressão com Scaler + newton-cg, Sem Scaler + newton-cg, Scaler + lbfgs, Sem Scaler + lbfgs.

Respostas

4 jhihan Oct 02 2020 at 00:13

Você pode configurar os parâmetros with_meane with_stdde StandardScaler()como False para representar a não padronização. No GirdSearchCV, o parâmetro para_gridpode ser configurado como

param_grid = [{'scale__with_mean': [False],
               'scale__with_std': [False],
               'mnl__solver': ['newton-cg', 'lbfgs', 'liblinear', 'sag', 'saga'],
               'mnl__max_iter':[500,1000,2000,3000]
              },
              {'mnl__solver': ['newton-cg', 'lbfgs', 'liblinear', 'sag', 'saga'],
              'mnl__max_iter':[500,1000,2000,3000]}
]

Então, o primeiro dict na lista é "No Scaler + mnl" e o segundo é "Scaler + mnl"

Ref:

https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.StandardScaler.html

https://scikit-learn.org/stable/tutorial/statistical_inference/putting_together.html

Edit: Eu acho que é complicado se você também considerar ligar / desligar o PCA ... Talvez você precise definir um PCA personalizado que derive o PCA original. E então definir o argumento booleano adicional que determina se o PCA deve ser executado ou não ...

class MYPCA(PCA):
    def __init__(self, PCA_turn_on, *args):
        super().__init__(*args)
        self.PCA_turn_on = PCA_turn_on
    
    def fit(X, y=None):
        if (PCA_turn_on == True):
            return super().fit(X, y=None)
        else:
            pass

    # same for other methods defined in PCA
1 BenReiniger Oct 02 2020 at 09:08

Da documentação para Pipeline:

O estimador de uma etapa pode ser substituído inteiramente configurando o parâmetro com seu nome para outro estimador, ou um transformador removido configurando-o para 'passthrough' ou None.

Por exemplo:

pipe = Pipeline([
    ('scale', StandardScaler()),
    ('mnl', mnl)])

params = {
    'scale': ['passthrough', StandardScaler()],
    'mnl__solver': ['newton-cg', 'lbfgs', 'liblinear', 'sag', 'saga'],
    'mnl__max_iter':[500,1000,2000,3000]
}