make_pipeline with StandardScalar and KerasRegressors



我正在尝试使用以下代码进行 GridSearchCV 纪元和batch_size:

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, shuffle=False)
X_train2 = X_train.values.reshape((X_train.shape[0], 1, X_train.shape[1]))
y_train2 = np.ravel(y_train.values)
X_test2 = X_test.values.reshape((X_test.shape[0], 1, X_test.shape[1]))
y_test2 = np.ravel(y_test.values)
def build_model():
    model = Sequential()
    model.add(LSTM(500, input_shape=(1, X_train.shape[1])))
    model.add(Dense(1))
    model.compile(loss="mse", optimizer="adam")
    return model

new_model = KerasRegressor(build_fn=build_model, verbose=0)
pipe = Pipeline([('s', StandardScaler()), ('reg', new_model)])
param_gridd = {'reg__epochs': [5, 6], 'reg__batch_size': [71, 72]}
model = GridSearchCV(estimator=pipe, param_grid=param_gridd)
# ------------------ if the following two lines are uncommented the code works -> problem with Pipeline?
# param_gridd = {'epochs':[5,6], 'batch_size': [71, 72]}
# model = GridSearchCV(estimator=new_model, param_grid=param_gridd)

fitted = model.fit(X_train2, y_train2, validation_data=(X_test2, y_test2), verbose=2, shuffle=False)

并收到以下错误:

File "/home/geo/anaconda3/lib/python3.6/site-packages/sklearn/model_selection/_search.py", line 722, in fit
 self._run_search(evaluate_candidates)   
File "/home/geo/anaconda3/lib/python3.6/site-packages/sklearn/model_selection/_search.py", line 1191, in _run_search
 evaluate_candidates(ParameterGrid(self.param_grid))   
File "/home/geo/anaconda3/lib/python3.6/site-packages/sklearn/model_selection/_search.py", line 711, in evaluate_candidates
 cv.split(X, y, groups)))   
File "/home/geo/anaconda3/lib/python3.6/site-packages/sklearn/externals/joblib/parallel.py", line 917, in __call__
 if self.dispatch_one_batch(iterator):   
File "/home/geo/anaconda3/lib/python3.6/site-packages/sklearn/externals/joblib/parallel.py", line 759, in dispatch_one_batch
 self._dispatch(tasks)   
File "/home/geo/anaconda3/lib/python3.6/site-packages/sklearn/externals/joblib/parallel.py", line 716, in _dispatch
 job = self._backend.apply_async(batch, callback=cb)   
File "/home/geo/anaconda3/lib/python3.6/site-packages/sklearn/externals/oblib/_parallel_backends.py", line 182, in apply_async
 result = ImmediateResult(func)   
File "/home/geo/anaconda3/lib/python3.6/site-packages/sklearn/externals/joblib/_parallel_backends.py", line 549, in __init__
 self.results = batch()   
File "/home/geo/anaconda3/lib/python3.6/site-packages/sklearn/externals/joblib/parallel.py", line 225, in __call__
 for func, args, kwargs in self.items]   
File "/home/geo/anaconda3/lib/python3.6/site-packages/sklearn/externals/joblib/parallel.py", line 225, in <listcomp>
 for func, args, kwargs in self.items]   
File "/home/geo/anaconda3/lib/python3.6/site-packages/sklearn/model_selection/_validation.py", line 528, in _fit_and_score
 estimator.fit(X_train, y_train, **fit_params)   
File "/home/geo/anaconda3/lib/python3.6/site-packages/sklearn/pipeline.py", line 265, in fit
 Xt, fit_params = self._fit(X, y, **fit_params)    
File "/home/geo/anaconda3/lib/python3.6/site-packages/sklearn/pipeline.py", line 202, in _fit
 step, param = pname.split('__', 1)
ValueError: not enough values to unpack (expected 2, got 1)

我怀疑这与param_gridd的命名有关,但不确定发生了什么。请注意,当我从代码中消除make_pipeline并且直接在new_model上使用 GridSearchCV 时,代码工作正常。

我认为

问题在于喂食KerasRegressor的拟合参数的方式。 validation_datashuffle不是GridSearchCV的参数,而是reg。试试这个!

fitted = model.fit(X_train2, y_train2,**{'reg__validation_data':(X_test2, y_test2),'reg__verbose':2, 'reg__shuffle':False} )

编辑: 根据 @Vivek kumar 的发现,我为您的预处理编写了一个包装器。

from sklearn.preprocessing import StandardScaler
class custom_StandardScaler():
    def __init__(self):
        self.scaler =StandardScaler()
    def fit(self,X,y=None):
        self.scaler.fit(X)
        return self
    def transform(self,X,y=None):
        X_new=self.scaler.transform(X)
        X_new = X_new.reshape((X.shape[0], 1, X.shape[1]))
        return X_new

这将帮助您实现标准缩放器以及创建新维度。请记住,我们必须在将评估数据集作为 fit_params() 馈送之前对其进行转换,因此使用单独的缩放器 (offline_scaler() ) 来转换它。

from sklearn.datasets import load_boston
from keras.models import Sequential
from keras.layers import Dense
from keras.wrappers.scikit_learn import KerasRegressor
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from keras.layers import LSTM
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import train_test_split
import numpy as np
seed = 1
boston = load_boston()
X, y = boston['data'], boston['target']
X_train, X_eval, y_train, y_eval = train_test_split(X, y, test_size=0.2, random_state=42)

def build_model():
    model = Sequential()
    model.add(LSTM(5, input_shape=(1, X_train.shape[1])))
    model.add(Dense(1))
    model.compile(loss='mean_squared_error', optimizer='Adam', metrics=['mae'])
    return model

new_model = KerasRegressor(build_fn=build_model, verbose=0)
param_gridd = {'reg__epochs':[2,3], 'reg__batch_size':[16,32]}
pipe = Pipeline([('s', custom_StandardScaler()),('reg', new_model)])
offline_scaler = custom_StandardScaler()
offline_scaler.fit(X_train)
X_eval2 = offline_scaler.transform(X_eval)
model = GridSearchCV(estimator=pipe, param_grid=param_gridd,cv=3)
fitted = model.fit(X_train, y_train,**{'reg__validation_data':(X_eval2, y_eval),'reg__verbose':2, 'reg__shuffle':False} )

正如@AI_Learning所说,这一行应该有效:

fitted = model.fit(X_train2, y_train2, 
                   reg__validation_data=(X_test2, y_test2), 
                   reg__verbose=2, reg__shuffle=False)

管道要求将参数命名为 "component__parameter" 。因此,在参数前面reg__有效。

但是,这不起作用,因为StandardScaler会抱怨数据维度。你看,当你这样做时:

X_train2 = X_train.values.reshape((X_train.shape[0], 1, X_train.shape[1]))
...
X_test2 = X_test.values.reshape((X_test.shape[0], 1, X_test.shape[1]))

您制作了X_train2X_test2了三维数据。您这样做是为了使其适用于LSTM但不适用于StandardScaler,因为这需要形状(n_samples, n_features)的 2-D 数据。

如果像这样从管道中取出StandardScaler

pipe = Pipeline([('reg', new_model)])

并尝试我和@AI_Learning建议的代码,它会起作用。这表明它与流水线无关,但你一起使用不兼容的变压器在一起。

可以将标准缩放程序从管道中取出,并执行以下操作:

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, shuffle=False)
std = StandardScaler()
X_train = std.fit_transform(X_train)
X_test = std.transform(X_test)
X_train2 = X_train.values.reshape((X_train.shape[0], 1, X_train.shape[1]))
y_train2 = np.ravel(y_train.values)
...
...

相关内容

  • 没有找到相关文章

最新更新