在 sklearn 中,GridSearchCV 和 Pipeline 的 fit 方法是否有区别?

这可能只是一个bug,或者是我真的很笨,我(或者更准确地说是我的同事)用一些Keras变换包装了一个Keras模型,这样我们就可以在sklearn库中使用这个Keras模型了。

现在,当我对Pipeline使用fit方法时,它运行得很好。它会运行并返回一个可用的模型实例。然而,当我使用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 = 10001class 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 rclass 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 Xmaxlen = 15def 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 modellstmmodel = 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 parametersparameters = {} #Some params to use in gridsearchskf = 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错误,但是当我使用Pipeline运行fit方法时,它却能正常工作:

enter image description here

GridSearchCVPipeline中的fit()方法之间是否有区别?我真的是很笨吗,还是这只是一个bug?

顺便提一下,我目前被迫使用Sklearn 0.19.1版本。


回答:

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

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

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

我在sklearn 0.19.1版本上进行了测试

我的问题在于,使用Keras的Tokenizer创建的词袋是通过num_words参数来限制词袋的最大词数的。我的同事在这方面做得不好,因此词数与LSTM模型的输入维度相匹配。因为num_words从未被设置,所以词袋总是大于输入维度。

num_words是以**kwargs参数的形式传递给Tokenizer的。

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()能够正常工作了。

Related Posts

在MLens Pipeline中使用StandardScaler作为预处理器会生成分类警告

我在MLens Superlearner管道的交叉验证…

如何计算Sklearn中随机森林和极端随机树中各个树的投票?

我一直在用Rust语言构建自己的极端随机树(XT)分类…

如何将嵌套数组输入到SVM模型中

我的问题如下: 我有一个数组,其中包含对应于多个音频文…

Scikit-learn的cross_val_score抛出ValueError: `Layer.call`的第一个参数必须始终传递

我正在进行一个深度学习项目,并尝试按照教程中的方法使用…

运行时间估计:小鼠(MICE)插补?

我使用小鼠(MICE)插补方法来填充机器学习数据集中缺…

使用字符串和整数进行预测的DecisionTreeClassifier

我有一段代码从数据库中获取了一些数据,数据库部分并不重…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注