{"cells":[{"metadata":{},"cell_type":"markdown","source":"This is not original at all!!\nData Munging: https://www.kaggle.com/mayer79/rnn-starter-for-huge-time-series (Please Upvote!)\nLSTM: https://www.kaggle.com/thebrownviking20/intro-to-recurrent-neural-networks-lstm-gru (Please Upvote!)"},{"metadata":{"trusted":true},"cell_type":"code","source":"# BASIC IDEA OF THE KERNEL\n\n# The data consists of a one dimensional time series x with 600 Mio data points. \n# At test time, we will see a time series of length 150'000 to predict the next earthquake.\n# The idea of this kernel is to randomly sample chunks of length 150'000 from x, derive some\n# features and use them to update weights of a recurrent neural net with 150'000 / 1000 = 150\n# time steps. \n\nimport numpy as np \nimport pandas as pd\nimport os\nfrom tqdm import tqdm\n# Define model\nfrom keras.models import Sequential\nfrom keras.layers import Dense, CuDNNGRU, Dropout, TimeDistributed, LSTM, CuDNNLSTM\nfrom keras.optimizers import adam, RMSprop\nfrom keras.callbacks import ModelCheckpoint\nfrom keras.models import load_model\n# Fix seeds\nfrom numpy.random import seed\nseed(639)\nfrom tensorflow import set_random_seed\nset_random_seed(5944)\n\nfrom numpy.random import seed\nseed(639)\nfrom tensorflow import set_random_seed\nset_random_seed(5944)\n\n# Import\nfloat_data = pd.read_csv(\"../input/train.csv\", dtype={\"acoustic_data\": np.float32, \"time_to_failure\": np.float32}).values\n\n# Helper function for the data generator. Extracts mean, standard deviation, and quantiles per time step.\n# Can easily be extended. Expects a two dimensional array.\ndef extract_features(z):\n     return np.c_[z.mean(axis=1), \n                  z.min(axis=1),\n                  z.max(axis=1),\n                  z.std(axis=1)]\n\n# For a given ending position \"last_index\", we split the last 150'000 values \n# of \"x\" into 150 pieces of length 1000 each. So n_steps * step_length should equal 150'000.\n# From each piece, a set features are extracted. This results in a feature matrix \n# of dimension (150 time steps x features).  \ndef create_X(x, last_index=None, n_steps=150, step_length=1000):\n    if last_index == None:\n        last_index=len(x)\n       \n    assert last_index - n_steps * step_length >= 0\n\n    # Reshaping and approximate standardization with mean 5 and std 3.\n    temp = (x[(last_index - n_steps * step_length):last_index].reshape(n_steps, -1) - 5 ) / 3\n    \n    # Extracts features of sequences of full length 1000, of the last 100 values and finally also \n    # of the last 10 observations. \n    return np.c_[extract_features(temp),\n                 extract_features(temp[:, -step_length // 10:]),\n                 extract_features(temp[:, -step_length // 100:]),\n                 extract_features(temp[:, -step_length // 300:])]\n\n# Query \"create_X\" to figure out the number of features\nn_features = create_X(float_data[0:150000]).shape[1]\nprint(\"Our RNN is based on %i features\"% n_features)\n    \n# The generator endlessly selects \"batch_size\" ending positions of sub-time series. For each ending position,\n# the \"time_to_failure\" serves as target, while the features are created by the function \"create_X\".\ndef generator(data, min_index=0, max_index=None, batch_size=16, n_steps=150, step_length=1000):\n    if max_index is None:\n        max_index = len(data) - 1\n     \n    while True:\n        # Pick indices of ending positions\n        rows = np.random.randint(min_index + n_steps * step_length, max_index, size=batch_size)\n         \n        # Initialize feature matrices and targets\n        samples = np.zeros((batch_size, n_steps, n_features))\n        targets = np.zeros(batch_size, )\n        \n        for j, row in enumerate(rows):\n            samples[j] = create_X(data[:, 0], last_index=row, n_steps=n_steps, step_length=step_length)\n            targets[j] = data[row - 1, 1]\n        yield samples, targets\n        \nbatch_size = 32\n\n# Position of second (of 16) earthquake. Used to have a clean split\n# between train and validation\nsecond_earthquake = 50085877\nfloat_data[second_earthquake, 1]\n\n# Initialize generators\n# train_gen = generator(float_data, batch_size=batch_size) # Use this for better score\ntrain_gen = generator(float_data, batch_size=batch_size, min_index=second_earthquake + 1)\nvalid_gen = generator(float_data, batch_size=batch_size, max_index=second_earthquake)","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"n_features","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"cb = [ModelCheckpoint(\"model.hdf5\", save_best_only=True)]\n\n# The LSTM architecture\nmodel = Sequential()\n# LSTM layer\nmodel.add(CuDNNLSTM(units=50))\nmodel.add(Dropout(0.2))\n# The output layer\nmodel.add(Dense(units=1))\n\n# Compiling the RNN\n\n\nmodel.summary()\n\n# Compile and fit model\nmodel.compile(optimizer='rmsprop',loss='mae')\n\n\n\nhistory = model.fit_generator(train_gen,\n                              steps_per_epoch=1000,\n                              epochs=430,\n                              verbose=2,\n                              callbacks=cb,\n                              validation_data=valid_gen,\n                              validation_steps=200\n                             )\n\nmodel = model = load_model(\"model.hdf5\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"# Visualize accuracies\nimport matplotlib.pyplot as plt\n%matplotlib inline\ndef perf_plot(history, what = 'loss'):\n    x = history.history[what]\n    val_x = history.history['val_' + what]\n    epochs = np.asarray(history.epoch) + 1\n    \n    plt.plot(epochs, x, 'bo', label = \"Training \" + what)\n    plt.plot(epochs, val_x, 'b', label = \"Validation \" + what)\n    plt.title(\"Training and validation \" + what)\n    plt.xlabel(\"Epochs\")\n    plt.legend()\n    plt.show()\n    return None\nperf_plot(history) # Extra Layer","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"# Load submission file\nsubmission = pd.read_csv('../input/sample_submission.csv', index_col='seg_id', dtype={\"time_to_failure\": np.float32})\nx = None\n# Load each test data, create the feature matrix, get numeric prediction\nfor i, seg_id in enumerate(tqdm(submission.index)):\n  #  print(i)\n    seg = pd.read_csv('../input/test/' + seg_id + '.csv')\n    x = seg['acoustic_data'].values[:]\n    #print(x.shape)\n    submission.time_to_failure[i] = (model.predict(np.expand_dims(create_X(x), 0)))\n\n# Save\nsubmission.to_csv('submission.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission.head(10)","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.7.1"}},"nbformat":4,"nbformat_minor":1}