получить различное масштабирование в поиске сетки sklearn - PullRequest
0 голосов
/ 13 декабря 2018

Я пытаюсь установить GridSearchCV в sklearn, который использует TimeSeriesSplit с данными, нормализованными в наборе training .Я создал TransformerMixin с именем DivisorTransform, который получает делитель нормализации и сохраняет его.DivisorTransform создается перед Pipeline.В конвейер я устанавливаю DivisorTransform (чтобы соответствовать), а затем NormalizeTransformer принимает в качестве входных данных DivisorTransform и выполняю деление.Однако при использовании этого трубопровода в GridSearchCV трансформатор травится.Это приводит к травлению и установке DivisorTransform, затем травление NormalizeTransformer, но с самим DivisorTransform травлением DivisorTransform снова.Это заставляет NormalizeTransformer использовать неустановленный DivisorTransform.Вот пример

dt = DivisorTransform()
pipe = Pipeline([('divisor',dt),('normalize',NormalizeTransformer(dt))])
gridS = GridSearchCV(pipe,params={...},cv=TimeSeriesSplit())

Каким образом различные нормализации должны управляться в GridSearchCV?Каковы лучшие практики?

Вот пример Python

import pandas as pd
import numpy as np
from sklearn.base import BaseEstimator
from sklearn.base import TransformerMixin
from sklearn.pipeline import Pipeline
from sklearn.grid_search import GridSearchCV
from sklearn.model_selection import TimeSeriesSplit

class DivisorTransform(BaseEstimator,TransformerMixin):
    def __init__(self):
        pass

    def fit(self, X, y=None):
        print(f'{type(self).__name__} id {id(self)} fit')
        self.divisor_ = X.max()
        return self

    def transform(self, X):
        print(f'{type(self).__name__} id {id(self)} transform')
        return X

    def getDivisor(self):
        return self.divisor_

class NormalizationTransform(BaseEstimator,TransformerMixin):
    def __init__(self, divisorTransform, fakeParam):
        self.divTrns = divisorTransform
        self.fakeParam = fakeParam
        print(f'{type(self).__name__} id {id(self)} init saving {type(self.divTrns).__name__} at {id(self.divTrns)}')

    def fit(self, X, y=None):
        print(f'{type(self).__name__} id {id(self)} fit going to fit {type(self.divTrns).__name__} {id(self.divTrns)}')
        self.divisor_ = self.divTrns.fit(X).getDivisor()
        return self

    def transform(self, X):
        print(f'{type(self).__name__} id {id(self)} transform')
        res = X.copy()
        res = res / self.divisor_
        print('_______________________________________')
        print(res)
        return res

    def anti_transform(self, X):
        res = X.copy()
        res = res * self.divisor_
        return res

    def score(self, X, y=None, sample_weight=None):
        return 1


x = pd.DataFrame([[i+j*10 for j in range(3)] for i in range(10)],columns=['A','B','C'])
dvT = DivisorTransform()
print(type(dvT).__name__)
pipe = Pipeline([('divisor',dvT),('normalization',NormalizationTransform(dvT, 0))])
res1 = pipe.fit_transform(x)
params = {'normalization__fakeParam':[0,1]}
gs = GridSearchCV(pipe,params,cv=TimeSeriesSplit(n_splits=3).split(x))
print('Starting Grid Search')
gs.fit(x)

Thi производит в виде печати:

Starting Grid Search
NormalizationTransform id 140321510292896 init saving NoneType at 94405154462352
NormalizationTransform id 140321722266344 init saving NoneType at 94405154462352

Это показывает проблему

...