sklearn中的GridSearchCV和管道是否适合?

时间:2018-12-26 14:51:51

标签: python machine-learning scikit-learn keras grid-search

也许这仅仅是一个错误,或者我真的很愚蠢,我使用一些Keras转换包装了Keras模型(或者最好是说一位同事包装了Keras模型),因此我们可以在sklearn库中使用Keras模型。

现在,当我在管道上使用fit时,它可以正常工作。它运行并返回一个工作模型实例。但是,当我出于某种原因使用GridSearchCV时,它无法进行转换(或者看起来如此),并且给了我以下错误:

print(*table, sep='\n')

代码看起来像这样:

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)]]

现在,上面的代码因InvalidArgumentError而失败,但是当我使用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) 运行fit时,它将起作用:

enter image description here

Pipeline中的fit()GridSearchCV之间是否有区别?我真的很愚蠢吗,或者这只是一个错误?

顺便说一句,我目前被迫使用Sklearn 0.19.1。

1 个答案:

答案 0 :(得分:0)

经过数小时的思考和调试,我得出以下结论:

Pipeline.fit()能够自动填充**kwargs个参数。

GridSearchCV.fit()无法自动填充**kwargs参数。

我在sklearn 0.19.1上对此进行了测试

我的问题是,使用Tokenizer参数创建了用Keras 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()起作用。