sklearn RandomizedSearchCV 与流水线 KerasClassifier

Posted

技术标签:

【中文标题】sklearn RandomizedSearchCV 与流水线 KerasClassifier【英文标题】:sklearn RandomizedSearchCV with Pipelined KerasClassifier 【发布时间】:2018-03-25 16:48:57 【问题描述】:

我正在使用 sklearn 在 Keras 模型上执行超参数调整优化任务。我正在尝试优化管道中的 KerasClassifiers ...... 代码如下:

import numpy as np
import pandas as pd
from keras.models import Sequential
from keras.layers import Dense
from keras.wrappers.scikit_learn import KerasClassifier
from sklearn.model_selection import cross_val_score, StratifiedKFold,RandomizedSearchCV
from sklearn.preprocessing import LabelEncoder, StandardScaler
from sklearn.pipeline import Pipeline

my_seed=7

dataframe = pd.read_csv("z:/sonar.all-data.txt", header=None)

dataset = dataframe.values
# split into input and output variables
X = dataset[:,:60].astype(float)
Y = dataset[:,60]

encoder = LabelEncoder()
Y_encoded=encoder.fit_transform(Y)
myScaler = StandardScaler()
X_scaled = myScaler.fit_transform(X)

def create_keras_model(hidden=60):
    model = Sequential()
    model.add(Dense(units=hidden, input_dim=60, kernel_initializer="normal", activation="relu"))
    model.add(Dense(1,  kernel_initializer="normal", activation="sigmoid"))
    #compile model
    model.compile(loss="binary_crossentropy", optimizer="adam", metrics=["accuracy"])
    return model

def create_pipeline(hidden=60):
    steps = []
    steps.append(('scaler', StandardScaler()))
    steps.append(('dl', KerasClassifier(build_fn=create_keras_model,hidden=hidden, verbose=0)))
    pipeline = Pipeline(steps)
    return pipeline

my_neurons = [15, 30, 60]
my_epochs= [50, 100, 150]
my_batch_size = [5,10]
my_param_grid = dict(hidden=my_neurons, epochs=my_epochs, batch_size=my_batch_size)

model2Tune = KerasClassifier(build_fn=create_keras_model, verbose=0)
model2Tune2 = create_pipeline()

griglia = RandomizedSearchCV(estimator=model2Tune, param_distributions = my_param_grid, n_iter=8 )
griglia.fit(X_scaled, Y_encoded) #this works

griglia2 = RandomizedSearchCV(estimator=create_pipeline, param_distributions = my_param_grid, n_iter=8 )
griglia2.fit(X, Y_encoded) #this does not

我们看到RandomizedSearchCV 适用于 griglia,而它不适用于 griglia2,返回

"TypeError: estimator 应该是一个实现 'fit' 的 estimator 方法,通过”。

是否可以修改代码使其在 Pipeline 对象下运行?

提前致谢

【问题讨论】:

estimator 参数需要一个对象,而不是指针。试试改成griglia2 = RandomizedSearchCV(estimator=create_pipeline(), param_distributions = my_param_grid, n_iter=8 ) @VivekKumar,感谢您的初步见解。我仍然收到一条(新)错误消息,现在是“ValueError: Invalid parameter batch_size for estimator Pipeline。使用 estimator.get_params().keys() 检查可用参数列表。” 【参考方案1】:

estimator 参数需要一个对象,而不是指针。当前,您正在传递一个指向生成管道对象的方法的指针。尝试添加() 来解决这个问题:

griglia2 = RandomizedSearchCV(estimator=create_pipeline(), param_distributions = my_param_grid, n_iter=8 )

现在是关于无效参数错误的第二条评论。您需要将创建管道时定义的名称附加到实际参数中,以便它们可以成功传递。

看Pipeline usage here的描述。

使用这个:

my_param_grid = dict(dl__hidden=my_neurons, dl__epochs=my_epochs,
                     dl__batch_size=my_batch_size)

注意dl__(带有两个下划线)。当您想要调整管道内多个对象的参数时,这很有用。

例如,假设除了上述参数,您还想调整或指定 StandardScaler 的参数。

那么你的参数网格就变成了:

my_param_grid = dict(dl__hidden=my_neurons, dl__epochs=my_epochs,
                     dl__batch_size=my_batch_size,
                     scaler__with_mean=False)

希望这能解决问题。

【讨论】:

以上是关于sklearn RandomizedSearchCV 与流水线 KerasClassifier的主要内容,如果未能解决你的问题,请参考以下文章

sklearn的PCA

sklearn数据库-老鱼学sklearn

使用sklearn画二分类模型ROC曲线,PR曲线

Keras Sklearn Tuner 模块“sklearn”没有属性“管道”

导入sklearn时出现conda sklearn错误

sklearn库的安装