Есть ли разница в посадке на GridSearchCV и Pipeline в sklearn? - PullRequest
0 голосов
/ 26 декабря 2018

Может быть, это просто ошибка, или я действительно глуп, я обернул (или лучше сказал, что коллега обернул) модель Keras, используя некоторые преобразования Keras, также обернутые, чтобы мы могли использовать модель Keras с библиотекой sklearn.

Теперь, когда я использую подгонку к конвейеру, он работает нормально.Он запускается и возвращает экземпляр рабочей модели.Однако, когда я по какой-то причине использую GridSearchCV, он не выполняет преобразования (или так может показаться) и выдает мне следующую ошибку:

InvalidArgumentError (see above for traceback): indices[11,2] = 26048 is not in [0, 10001)
     [[Node: embedding_4/Gather = Gather[Tindices=DT_INT32, Tparams=DT_FLOAT, validate_indices=true, _device="/job:localhost/replica:0/task:0/cpu:0"](embedding_4/embeddings/read, embedding_4/Cast)]]

Код выглядит примерно так:

vocab_size = 10001

class TextsToSequences(Tokenizer, BaseEstimator, TransformerMixin):
    def __init__(self,  **kwargs):
        super().__init__(**kwargs)

    def fit(self, X, y=None):
        print('fitting the text')
        print(self.document_count)
        self.fit_on_texts(X)
        return self

    def transform(self, X, y=None):
        print('transforming the text')
        r = np.array(self.texts_to_sequences(X))
        print(r)
        print(self.document_count)
        return r

class Padder(BaseEstimator, TransformerMixin):
    def __init__(self, maxlen=500):
        self.maxlen = maxlen
        self.max_index = None

    def fit(self, X, y=None):
        #self.max_index = pad_sequences(X, maxlen=self.maxlen).max()
        return self

    def transform(self, X, y=None):
        print('pad the text')
        X = pad_sequences(X, maxlen=self.maxlen, padding='post')
        #X[X > self.max_index] = 0

        print(X)

        return X

maxlen = 15

def makeLstmModel():
    model = Sequential()
    model.add(Embedding(10001, 100, input_length=15))
    model.add(LSTM(35, dropout=0.2, recurrent_dropout=0.2))
    model.add(Dense(16, activation='sigmoid'))
    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
    model.summary()
    return model

lstmmodel = KerasClassifier(build_fn=makeLstmModel, epochs=5, batch_size=1000, verbose=42)

pipeline =  [
        ('seq', TextsToSequences(num_words=vocab_size)),
        ('pad', Padder(maxlen)),
        ('clf', lstmmodel)
    ]

textClassifier = Pipeline(pipeline)

#Setup parameters
parameters = {} #Some params to use in gridsearch

skf = StratifiedKFold(n_splits=numberOfFolds, shuffle=True, random_state=1)
gscv = GridSearchCV(textClassifier, parameters, cv=skf, iid=False, n_jobs=1, verbose=50)

gscv.fit(x_train, y_train)

Теперь приведенный выше код завершается ошибкой с InvalidArgumentError, но когда я запускаю fit с Pipeline, он работает:

enter image description here

Isесть разница между fit() в GridSearchCV и Pipeline?Я действительно тупой или это просто ошибка?

Кстати, в настоящее время я вынужден использовать Sklearn 0.19.1.

1 Ответ

0 голосов
/ 28 декабря 2018

После нескольких часов размышлений и отладки я пришел к следующему выводу:

Pipeline.fit() может автоматически заполнять **kwargs аргументы.

GridSearchCV.fit() не может автоматическизаполните **kwargs аргументов.

Я проверял это на sklearn 0.19.1

Моя проблема заключалась в том, что пакет слов, созданный с помощью Keras Tokenizer, был создан с использованиемnum_words параметр, который ограничивает сумку максимальным количеством слов.Мой коллега справился с этим плохо, поэтому количество слов соответствует количеству входных измерений в модели LSTM.* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *). num_words никогда не задавались, поэтому мешок всегда был больше входного размера.

num_words передавались Tokenizer в качестве аргументов **kwargs.

class TextsToSequences(Tokenizer, BaseEstimator, TransformerMixin):
    def __init__(self,  **kwargs):
        super().__init__(**kwargs)

По какой-то причине GridSearchCV.fit() не может заполнить это автоматически.Решением этой проблемы было бы использование фиксированных аргументов.

class TextsToSequences(Tokenizer, BaseEstimator, TransformerMixin):
    def __init__(self, num_words=8000, **kwargs):
        super().__init__(num_words, **kwargs)

После этого изменения GridSearchCV.fit() работает.

...