hyperopt/hyperas

本文介绍如何利用Hyperopt库进行超参数优化,以及暂停使用的Hyperas工具,它为Keras模型提供便利的超参数调整,简化了Hyperopt的使用。

这篇文章所用的数据是以基于tushare数据多维度时间序列lstm预测股票价格为基础经行测试开发。
整体架构与之前的一致。

hyperopt

Hyperopt是一个Python库,用于在尴尬的搜索空间上进行串行和并行优化,搜索空间可能包括实值,离散和条件维。
https://github.com/hyperopt/hyperopt

# https://www.kaggle.com/wrosinski/keras-optimization-template-hyperopt-gridsearch
# https://stackoverflow.com/questions/56460113/valueerror-of-hyperopt-in-searching-parameters-of-randomforest
# https://stackoverflow.com/questions/43533610/how-to-use-hyperopt-for-hyperparameter-optimization-of-keras-deep-learning-netwo
# https://www.kaggle.com/rodcardoso92/using-hyperopt-in-cnn-to-find-best-hyperparameters
# https://www.kaggle.com/inspector/keras-hyperopt-example-sketch
# https://github.com/hyperopt/hyperopt
import pandas as pd
import numpy as np
import sys

def create_dataset(X, Y, window_size=30, predict_size=5):
    data_X, data_Y = [], []
    for i in range(len(X) - window_size - predict_size + 1):
        a = X[i:(i + window_size)]
        data_X.append(a)
        data_Y.append(Y[i + window_size:i + window_size + predict_size, 0])
    return (np.array(data_X), np.array(data_Y))


from sklearn.preprocessing import MinMaxScaler


def minMaxScaler(df, feature_range=(0, 1)):
    scaler = MinMaxScaler(feature_range=feature_range)
    data_raw = pd.DataFrame(df).values.astype("float32")
    scaler.fit(data_raw)
    return scaler


from keras.models import Sequential
from keras.layers.recurrent import LSTM
from keras.layers.core import Dense, Activation, Dropout
from keras.callbacks import EarlyStopping
from keras import optimizers
from keras import backend
from sklearn.metrics import mean_absolute_error



if __name__ == '__main__':
    data = pd.read_csv('../data/data.csv')
    data = data.sort_values('trade_date').reset_index(drop=True)

    temp_data = data.copy()
    # #####################################数据预处理###############################
    scaler = minMaxScaler(temp_data.vol)
    temp_data.vol = \
        scaler.transform(pd.DataFrame(temp_data.vol).values.astype("float32"))

    scaler = minMaxScaler(temp_data.turnover_rate)
    temp_data.turnover_rate = \
        scaler.transform(pd.DataFrame(temp_data.turnover_rate).values.astype("float32"))

    scaler = minMaxScaler(temp_data.net_mf_vol, feature_range=(-1, 1))
    temp_data.net_mf_vol = \
        scaler.transform(pd.DataFrame(temp_data.net_mf_vol).values.astype("float32"))

    scaler = minMaxScaler(temp_data.close)
    temp_data.close = \
        scaler.transform(pd.DataFrame(temp_data.close).values.astype("float32"))
    # #############################################################################
    # #####################################构造数据#################################
    print(temp_data.isnull().any())
    train_data = temp_data[temp_data['trade_date'] <= 20191216]
    test_data = temp_data[temp_data['trade_date'] >= 20190301]

    train_X = pd.DataFrame(train_data[['close', 'vol', 'turnover_rate', 'net_mf_vol']]).values
    train_Y = pd.DataFrame(train_data['close']).values
    test_X = pd.DataFrame(test_data[['close', 'vol', 'turnover_rate', 'net_mf_vol']]).values
    test_Y = pd.DataFrame(test_data['close']).values

    window_size = 90
    predict_size = 5
    train_X, train_Y = create_dataset(train_X, train_Y, window_size=window_size, predict_size=predict_size)
    test_X, test_Y = create_dataset(test_X, test_Y, window_size=window_size, predict_size=predict_size)
    print(f'train_X.shape: {train_X.shape}   train_Y.shape: {train_Y.shape} \n'
          f'test_X.shape: {test_X.shape}     test_Y.shape: {test_Y.shape} ')

    # #############################################################################
    # #####################################构造模型#################################

    # 好像吐槽下hyperopt,他必须要创建一个runModel来调参,同时又要求数据事先放到这个runModel里面,
    # 等于需要一个全局变量直接传进去数据。完全反人类的设计啊,谁tm的会把数据作为一个全局变量啊。
    def runModel(params):
        optimizer = params['optimizer']
        layers_number = params['choice']['layers']
        input_shape = (train_X.shape[1], train_X.shape[2])
        output_shape = train_Y.shape[1]
        early_stopping = EarlyStopping('loss', patience=50)
        # adam = optimizers.Adam(lr=0.0001, beta_1=0.9, beta_2=0.999, decay=0.0, amsgrad=False)
        # sgd = optimizers.SGD(lr=0.001, momentum=0.0, decay=1e-4, nesterov=False)

        model = Sequential()
        model.add(LSTM(64, input_shape=input_shape, return_sequences=True))
        model.add(Dense(32))
        if layers_number == 4:
            model.add(Dropout(params['choice']['dropout4']))
            model.add(LSTM(params['choice']['units4'], return_sequences=True))

        model.add(LSTM(32))
        model.add(Dense(output_shape))
        model.compile(loss="mean_squared_error", optimizer=optimizer, metrics=['accuracy'])
        # model.summary()

        model.fit(train_X, train_Y, epochs=params['epochs'], batch_size=params['batch_size'], verbose=0,
                  callbacks=[early_stopping])
        preds = model.predict(test_X)
        acc = mean_absolute_error(test_Y, preds)
        print('MAE:', acc)
        sys.stdout.flush()
        return {'loss': -acc, 'status': STATUS_OK}


    from datetime import datetime
    from hyperopt import hp, fmin, tpe, hp, STATUS_OK, Trials
    start_time = datetime.now()

    space = dict(  # 相当于GridSearchCV的param_grid,RandomizedSearchCV的distributions
        epochs=hp.choice('epochs',[150]),
        batch_size=hp.choice('batch_size',[32]),
        optimizer=hp.choice('optimizer',['adam']),
        choice=hp.choice('layers_number',[{'layers': 3}, # 默认值
                                         {'layers': 4,
                                          'units4': hp.choice('units4', [32, 64]),
                                          'dropout4': hp.choice('dropout4',
                                                              np.linspace(0.0, 0.0002, 3, dtype=float))
                                         }
                                        ]),
                      )
    trials = Trials()
    best = fmin(runModel, space, algo=tpe.suggest, max_evals=10, trials=trials)
    backend.clear_session()
    end_time = datetime.now()
    print((end_time - start_time).seconds) # 2764
    trials.best_trial



    # #############################################################################

hyperas(暂停使用,有点问题)

围绕hyperopt的非常简单的便利包装,可用于使用keras模型进行快速原型制作。Hyperas使您无需学习Hyperopt的语法即可使用hyperopt的功能。取而代之的是,只需按照您的习惯定义您的keras模型,而是使用简单的模板符号定义要调整的超参数范围。
https://github.com/maxpumperla/hyperas

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值