Turning Python Keras Machine Learning model into repeatable function that can take as input multiple X and y data sets

Issue

I am currently building various machine learning models, each of the models takes in X and Y data that represent different stock prices e.g. there’s an X and y data frame for each stock e.g. Apple, Microsoft.

I am trying to produce these models so that they are repeatable, modular, functions that I can quickly call for each of my X and y data sets.

I have tried these models as standalone lines of code, or as functions that don’t take in parameters and they work as intended, however whenever I try to pass my X and y data sets as parameters they don’t work!

Currently I have:

def LSTM_regressor(X_train, X_test, y_train, y_test):
    convert_X_y_to_numpy_and_reshape(X_train, X_test, y_train, y_test)
    model = Sequential()
    model.add(Dense(1, input_dim=(X_train.shape[1]), kernel_initializer='normal', activation='sigmoid'))
    model.compile(loss='mse', optimizer='adam', metrics=['mse'])
    model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=10, batch_size=20)
    print(model.summary())

final_model = KerasRegressor(build_fn=LSTM_regressor(X_train_reg_aapl, X_test_reg_aapl, y_train_reg_aapl, y_test_reg_aapl),batch_size=20, epochs=50, verbose=1)
kfold = KFold(n_splits=10) # random_state=seed)
results = cross_val_score(final_model, X_train_reg_aapl, y_train_reg_aapl, cv=kfold, n_jobs=1)
print("Results: %.2f (%.2f) MSE" % (results.mean(),results.std()))

I am trying to pass the below into the function:

X_train_reg_aapl, X_test_reg_aapl, y_train_reg_aapl, y_test_reg_aapl

but I get the error message:

AttributeError: 'KerasRegressor' object has no attribute '__call__'

I have tried making a nested function and calling that, but it still doesn’t work.

Also, the below is a function that I have created that I wanted to use to transform the parameters entered into the machine learning model into a data format suitable for the model type.

 convert_X_y_to_numpy_and_reshape(X_train, X_test, y_train, y_test)

It’s full code is this:

def convert_X_y_to_numpy_and_reshape(X_train,X_test,y_train,y_test):
    X_train = X_train.to_numpy()
    X_test = X_test.to_numpy()
    y_train = y_train.to_numpy()
    y_test = y_test.to_numpy()
    y_train = y_train.reshape(-1)
    y_test = y_test.reshape(-1)
    X_train = X_train.reshape((X_train.shape[0], X_train.shape[1], 1))
    X_test = X_test.reshape((X_test.shape[0], X_test.shape[1], 1))

Any help on this would really be appreciated!

Solution

I was able to solve my problem by creating a new function that calls the LSTM model building function. Within the new function I included all the data processing functions needed and when calling the LSTM model building function I used "model=" rather than "build_fn" which allowed me to pass custom parameters to my LSTM model without triggering the below error.

AttributeError: 'KerasRegressor' object has no attribute '__call__'

My final LSTM build model:

def LSTM_regressor(X_train, X_test, y_train, y_test,hidden_layer_sizes, dropout, ):
    model = Sequential()
    model.add(LSTM(64, input_shape = X_train.shape[1:], activation='relu')) 
    model.add(Dense(24,activation='relu'))
    return model

Function used to pass parameters and processed data to my LSTM build model:

def Run_LSTM_Regressor(stock_name,X_train, X_test, y_train, y_test):
    index_train, index_test =  shift_X_reg(1,X_train,X_test)
    y_index_train, y_index_test  = shift_y_reg(1,y_train,y_test)
    X_train, X_test = shift_X_reg(1,X_train,X_test)
    y_train, y_test = shift_y_reg(1,y_train,y_test)
    X_train, X_test = normalise_X(X_train,X_test)
    X_train, X_test, y_train, y_test = convert_X_y_to_numpy_and_reshape_LSTM(X_train,X_test, y_train, y_test)
    run_lstm_regressor_model = KerasRegressor(model=LSTM_regressor(X_train, X_test, y_train, y_test,hidden_layer_sizes=(100,),dropout=0.5),loss="mse",metrics=['mean_squared_error'],epochs=100, verbose=1)
    run_lstm_regressor_model.fit(X_train,y_train)

Answered By – TheChef

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published